Definition of the proto::when<> and proto::otherwise<> transforms. The type used to define the global proto::transforms, a key for use when creating and accessing a slot in a transform environment for a set of external transforms. The proto::transforms_type type, along with the proto::transforms global, are declared using the BOOST_PROTO_DEFINE_ENV_VAR() macro. env<transforms_type, see-below> Value & env<transforms_type, see-below> Value const & If Value is a specialization boost::reference_wrapper<T>, this function returns env<transforms_type, T &>(value.get()). Else, if the type Value is non-copyable (i.e., a function, an array, abstract, or an ostream), this function returns env<transforms_type, Value cv &>(value), where cv is const for the second overload, and empty for the first. Otherwise, this function returns env<transforms_type, Value>(value). A key key for use when creating and accessing a slot in a transform environment for a set of external transforms. proto::transforms_type const A grammar element and a PrimitiveTransform that associates a transform with the grammar. Use proto::when<> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression. // Count the terminals in an expression tree. // Must be invoked with initial state == mpl::int_<0>(). struct CountLeaves : proto::or_< proto::when<proto::terminal<proto::_>, mpl::next<proto::_state>()>, proto::otherwise<proto::fold<proto::_, proto::_state, CountLeaves> > > {}; In proto::when<G, T>, when T is a class type it is a PrimitiveTransform and the following equivalencies hold: boost::result_of<proto::when<G,T>(E,S,V)>::type is the same as boost::result_of<T(E,S,V)>::type. proto::when<G,T>()(e,s,d) is the same as T()(e,s,d). PrimitiveTransform typename Grammar::proto_grammar Grammar Fun * proto::when< Grammar, Fun > A specialization that treats function pointer Transforms as if they were function type Transforms. This specialization requires that Fun is actually a function type. This specialization is required for nested transforms such as proto::when<G, T0(T1(_))>. In C++, functions that are used as parameters to other functions automatically decay to funtion pointer types. In other words, the type T0(T1(_)) is indistinguishable from T0(T1(*)(_)). This specialization is required to handle these nested function pointer type transforms properly. Grammar R(A...) proto::transform< when<Grammar, R(A...)> > A grammar element and a Transform that associates a transform with the grammar. Use proto::when<> to override a grammar's default transform with a custom transform. It is for use when composing larger transforms by associating smaller transforms with individual rules in your grammar. The when<G, R(A...)> form accepts either a CallableTransform or an ObjectTransform as its second parameter. proto::when<> uses proto::is_callable<R>::value to distinguish between the two, and uses proto::call<> to evaluate CallableTransforms and proto::make<> to evaluate ObjectTransforms. proto::transform_impl< Expr, State, Data > For exposition only proto::call<R(A...)> For exposition only proto::make<R(A...)> For exposition only typename mpl::if_<proto::is_callable<R>,call_,make_>::type typename boost::result_of<which(Expr, State, Data)>::type result_type typename impl::expr_param The current expression typename impl::state_param The current state typename impl::data_param An arbitrary data Evaluate R(A...) as a transform either with proto::call<> or with proto::make<> depending on whether proto::is_callable<R>::value is true or false. proto::matches<Expr, Grammar>::value is true. which()(expr, state, data) typename Grammar::proto_grammar Grammar R(A..., ...) proto::transform< when<Grammar, R(A..., ...)> > A grammar element and a Transform that associates a transform with the grammar. Use proto::when<> to override a grammar's default transform with a custom transform. It is for use when composing larger transforms by associating smaller transforms with individual rules in your grammar. The when<G, R(A..., ...)> form accepts either a CallableTransform or an ObjectTransform as its second parameter. proto::when<> uses proto::is_callable<R>::value to distinguish between the two, and uses proto::call<> to evaluate CallableTransforms and proto::make<> to evaluate ObjectTransforms. Note: In the specialization when<G, R(A..., ...)>, the first ellipsis denotes a C++11-style variadic template (which is emulated for C++98 compilers). The second ellipsis is a C-style vararg. proto::transform_impl< Expr, State, Data > For exposition only proto::call<R(A..., ...)> For exposition only proto::make<R(A..., ...)> For exposition only typename mpl::if_<proto::is_callable<R>,call_,make_>::type typename boost::result_of<which(Expr, State, Data)>::type result_type typename impl::expr_param The current expression typename impl::state_param The current state typename impl::data_param An arbitrary data Evaluate R(A..., ...) as a transform either with proto::call<> or with proto::make<> depending on whether proto::is_callable<R>::value is true or false. proto::matches<Expr, Grammar>::value is true. which()(expr, state, data) typename Grammar::proto_grammar Grammar proto::external_transform proto::transform< when<Grammar, proto::external_transform> > A grammar element that associates an externally-specified transform with the grammar. The transform is looked up in the Data parameter using the Grammar as a key. Use proto::when<> to override a grammar's default transform with a custom transform. It is for use when composing larger transforms by associating smaller transforms with individual rules in your grammar. The when<G, proto::external_transform> indicates that the associated transform is not yet known. It should be looked up when the transform is about to be applied. It is found by looking it up in the passed-in Data parameter, which behaves like a compile-time map from grammar types to transform types. The map is indexed using Grammar as a key. The associated value type is used as the transform to apply. In this way, the same grammar can be used to define multiple evaluating strategies that can be added post-hoc. See proto::external_transforms for an example. boost::remove_reference< typename mpl::eval_if_c< proto::result_of::has_env_var<Data, proto::transforms_type>::value, proto::result_of::env_var<Data, proto::transforms_type>, proto::result_of::env_var<Data, proto::data_type> >::type >::type ::template when< Grammar > ::template impl< Expr, State, Data > The implementation of the impl struct depends on whether the Data parameter is a transform environment that contains a value corresponding to the proto::transforms_type key. If so, that value is treated as a map from rules to transforms. Otherwise, the Data type itself is treated as such a map. typename Grammar::proto_grammar proto::when< proto::_, Fun > Syntactic sugar for proto::when< proto::_, Fun >, for use in grammars to handle all the cases not yet handled. Use proto::otherwise<T> in your grammars as a synonym for proto::when< proto::_, Fun > as in the following transform which counts the number of terminals in an expression. // Count the terminals in an expression tree. // Must be invoked with initial state == mpl::int_<0>(). struct CountLeaves : proto::or_< proto::when<proto::terminal<proto::_>, mpl::next<proto::_state>()>, proto::otherwise<proto::fold<proto::_, proto::_state, CountLeaves> > > {}; A placeholder for use as the second parameter for proto::when to indicate that the rule's transform is specified externally. See proto::external_transforms for an example. A map from grammars to transforms, used as a way to externally associate transforms. For exposition only. mpl::map< typename to_mpl_pair< When >::type... > proto::otherwise< typename mpl::at< map_type, Grammar >::type > It is sometimes desirable to define a grammar that can be customized with different sets of transforms. To do that, where you would normally specify a transform within a grammar, you can instead put proto::external_transform; for example: proto::when< some_grammar, proto::external_transform >. Then, when invoking the grammar, you can pass an approriately-defined instance of proto::external_transforms as the Data parameter. When an expression matches some_grammar, Proto will look up the approprite transform in the Data parameter using some_grammar as a key. struct int_terminal : proto::terminal<int> {}; struct char_terminal : proto::terminal<char> {}; struct my_grammar : proto::or_< // The next two grammar rules are customization points. // The associated transforms are specified externally // using external_transforms below. proto::when< int_terminal, proto::external_transform > , proto::when< char_terminal, proto::external_transform > , proto::when< proto::plus< my_grammar, my_grammar > , proto::fold< proto::_, int(), my_grammar > > > {}; // Here is where the transforms are associated with the // grammar rules above. struct my_transforms : proto::external_transforms< proto::when<int_terminal, print(proto::_value)> , proto::when<char_terminal, print(proto::_value)> > {}; // ... proto::literal<int> i(1); proto::literal<char> c('a'); my_transforms trx; // Evaluate "i+c" using my_grammar with the specified transforms: my_grammar()(i + c, 0, trx); // If you would also like to pass arbitrary data along with the // transforms, you can use a transform environment, as so: my_grammar()(i + c, 0, (proto::data = 42, proto::transforms = trx));