embed_by_reference(parser
const &); } } //============================================================================== // Implementation //============================================================================== #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_REGISTER_TEMPLATE // // Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE # define BOOST_SPIRIT_RP_REGISTER_TEMPLATE(name,params) \ BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ BOOST_TYPEOF_REGISTER_TEMPLATE( \ BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name, \ params) \ BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_REGISTER_TYPE // // Boost.Typeof registration from within BOOST_SPIRIT__NAMESPACE # define BOOST_SPIRIT_RP_REGISTER_TYPE(name) \ BOOST_SPIRIT_RP_EMIT(NS_CLOSE,BOOST_SPIRIT__NAMESPACE,-) \ BOOST_TYPEOF_REGISTER_TYPE( \ BOOST_SPIRIT_RP_EMIT(NS_QUALIFY,BOOST_SPIRIT__NAMESPACE,-) name ) \ BOOST_SPIRIT_RP_EMIT(NS_OPEN,BOOST_SPIRIT__NAMESPACE,-) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_AP_IMPL // // The action placeholder definition # define BOOST_SPIRIT_RP_AP_IMPL(name,ns) \ namespace __action_placeholder \ { \ struct name \ { \ template \ ns :: action_chain< name, ns :: replace, Action> \ operator=(Action const & __a) const \ { return ns :: action_chain< name, ns :: replace, Action>(__a); } \ \ template \ ns :: action_chain< name, ns :: append, Action> \ operator+=(Action const & __a) const \ { return ns :: action_chain< name, ns :: append, Action> (__a); } \ }; \ } \ __action_placeholder:: name const name = __action_placeholder:: name (); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_IMPL_I // // Does some precalculation so RP_IMPL_II can look cleaner # define BOOST_SPIRIT_RP_IMPL_I(name,pars,acts,mbrs,expr) \ BOOST_SPIRIT_RP_IMPL_II(name, name ## _t , \ pars, BOOST_SPIRIT_RP_ARRAY_SIZE(pars), \ acts, BOOST_SPIRIT_RP_ARRAY_SIZE(acts), \ mbrs, BOOST_SPIRIT_RP_ARRAY_SIZE(mbrs), expr) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_IMPL_II # define BOOST_SPIRIT_RP_IMPL_II(name,name_t,pars,np,acts,na,mbrs,nm,x) \ BOOST_PP_IIF(BOOST_PP_OR(np,na),BOOST_SPIRIT_RP_IMPL_III, \ BOOST_SPIRIT_RP_OPAQUE_IMPL_II) \ (name,name_t,pars,np,acts,na,mbrs,nm,x) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_IMPL_III // // The rule parser definition # define BOOST_SPIRIT_RP_IMPL_III(name,name_t,pars,np,acts,na,mbrs,nm,x) \ \ template< BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,typename __,1) > \ class name_t \ : public ::boost::spirit::parser< name_t \ < BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,__,0) > > \ { \ class __rule \ { \ BOOST_SPIRIT_RP_EMIT(PM_STATIC,pars,__T) \ BOOST_SPIRIT_RP_EMIT(AP_STATIC,acts,-) \ BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_IDENTITY(typename)) \ public: \ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(__expr, \ ::boost::spirit::type_of::depend_on_type<__Dummy>(x) ); \ }; \ \ public: \ \ typedef name_t self_t; \ typedef typename __rule::__expr::type::parser_category_t \ parser_category_t; \ \ BOOST_PP_EXPR_IIF(BOOST_PP_NOR(np,na),typedef self_t const & embed_t;) \ \ protected: \ \ BOOST_SPIRIT_RP_EMIT(MV_NONSTATIC,mbrs,BOOST_PP_IDENTITY(typename)) \ BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_AP_EXTRA_MBRS,2)(np,na) \ \ typename __rule::__expr::type::embed_t __parser; \ \ public: \ \ explicit name_t ( BOOST_SPIRIT_RP_CTOR(PARAMS,pars,np,acts) ) \ : BOOST_SPIRIT_RP_EMIT(MV_CTOR_INIT_LIST,mbrs,-) \ BOOST_PP_COMMA_IF(nm) \ BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_CTOR_COMMA,4)(INIT_LIST,pars,np,acts)\ __parser(x) \ { } \ \ name_t( name_t const & that) \ : BOOST_SPIRIT_RP_EMIT(MV_CTOR_COPY_INIT_LIST,mbrs,that) \ BOOST_PP_COMMA_IF(nm) \ BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_CTOR_COMMA,4) \ (COPY_INIT_LIST,pars,np,acts) \ __parser(that.__parser) \ { } \ \ template struct result \ { \ typedef typename ::boost::spirit::parser_result< \ typename __rule::__expr::type, Scanner>::type type; \ }; \ \ template \ typename ::boost::spirit::parser_result::type \ parse(Scanner const & s) const { return __parser.parse(s); } \ \ BOOST_SPIRIT_RP_IF(na,SPIRIT_RP_AP_HANDLER,5) \ (name_t,np,acts,na,::boost::spirit::type_of) \ }; \ \ BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_FUNC,BOOST_SPIRIT_RP_GLOB_VAR) \ (name,name_t,np,na) \ BOOST_SPIRIT_RP_REGISTER_TEMPLATE \ (name_t,BOOST_PP_INC(BOOST_PP_ADD(np,na))) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_OPAQUE_IMPL_I // # define BOOST_SPIRIT_RP_OPAQUE_IMPL_I(name,pars,mbrs,expr) \ BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name, name ## _t, \ pars,BOOST_SPIRIT_RP_ARRAY_SIZE(pars),-,-,\ mbrs,BOOST_SPIRIT_RP_ARRAY_SIZE(mbrs),expr) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_OPAQUE_IMPL_II // # define BOOST_SPIRIT_RP_OPAQUE_IMPL_II(name,name_t,pars,np,_1,_2,mbrs,nm,x) \ class name_t; \ \ BOOST_SPIRIT_RP_REGISTER_TYPE(name_t) \ \ class name_t \ : public ::boost::spirit::parser< name_t > \ { \ class __rule \ { \ BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_STATIC,pars,-) \ BOOST_SPIRIT_RP_EMIT(MV_STATIC,mbrs,BOOST_PP_EMPTY) \ public: \ BOOST_TYPEOF_NESTED_TYPEDEF(__expr,x) ; \ }; \ \ public: \ \ typedef name_t self_t; \ typedef __rule::__expr::type::parser_category_t parser_category_t; \ BOOST_PP_EXPR_IIF(BOOST_PP_NOT(np),typedef self_t const & embed_t;) \ \ protected: \ \ BOOST_SPIRIT_RP_EMIT(MV_NONSTATIC,mbrs,BOOST_PP_EMPTY) \ \ __rule::__expr::type::embed_t __parser; \ \ public: \ \ explicit name_t (BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_CTOR_PARAMS,pars,-)) \ : BOOST_SPIRIT_RP_EMIT(MV_CTOR_INIT_LIST,mbrs,-) \ BOOST_PP_COMMA_IF(nm) __parser(x) \ { } \ \ name_t(name_t const & that) \ : BOOST_SPIRIT_RP_EMIT(MV_CTOR_COPY_INIT_LIST,mbrs,that) \ BOOST_PP_COMMA_IF(nm) __parser(that.__parser) \ { } \ \ template struct result \ { \ typedef typename ::boost::spirit::parser_result< \ __rule::__expr::type, Scanner>::type type; \ }; \ \ template \ typename ::boost::spirit::parser_result::type \ parse(Scanner const & s) const { return __parser.parse(s); } \ }; \ \ BOOST_PP_IF(np,BOOST_SPIRIT_RP_GEN_OPAQUE,BOOST_SPIRIT_RP_GLOB_OPAQUE) \ (name,name_t,np,pars) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_AP_HANDLER // // Part of the rule parser definition for handling action placeholders # define BOOST_SPIRIT_RP_AP_HANDLER(name_t,np,acts,na,ns) \ private: \ template struct __rebound_1st \ { \ typedef name_t < void BOOST_PP_ENUM_TRAILING_PARAMS(np,__T) , \ typename ns ::action_concatenator<__A0,A>::type \ BOOST_PP_COMMA_IF(BOOST_PP_DEC(na)) \ BOOST_PP_ENUM_SHIFTED_PARAMS(na,__A) \ > type; \ }; \ \ template struct __rebound \ { \ typedef name_t < \ void BOOST_PP_ENUM_TRAILING_PARAMS(np,__T) \ BOOST_SPIRIT_RP_EMIT(AP_REBOUND_TPL_ARGS,acts,X) \ > type; \ }; \ public: \ template \ typename __rebound_1st::type const operator[](A const & a) const \ { \ return typename __rebound_1st::type ( \ BOOST_PP_ENUM_PARAMS(np,__p) BOOST_PP_COMMA_IF(np) \ ns ::concatenate_actions(__a0,a) \ BOOST_PP_COMMA_IF(BOOST_PP_DEC(na)) \ BOOST_PP_ENUM_SHIFTED_PARAMS(na,__a) ); \ } \ template \ typename __rebound< ns ::action_chain >::type const \ operator[]( ns ::action_chain const & x) const \ { \ return typename __rebound< ns ::action_chain >::type ( \ BOOST_PP_ENUM_PARAMS(np,__p) BOOST_PP_COMMA_IF(np) \ BOOST_SPIRIT_RP_EMIT(AP_REBOUND_ARGS,acts,x) ); \ } \ template \ typename __rebound< ns ::action_chains >::type const \ operator[]( ns ::action_chains const & x) const \ { \ return typename __rebound< ns ::action_chains >::type ( \ BOOST_PP_ENUM_PARAMS(np,__p) BOOST_PP_COMMA_IF(np) \ BOOST_SPIRIT_RP_EMIT(AP_REBOUND_ARGS,acts,x) ); \ } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_AP_EXTRA_MBRS // // Extra members we need for rebinding if there are action placeholders # define BOOST_SPIRIT_RP_AP_EXTRA_MBRS(np,na) \ private: \ BOOST_PP_REPEAT(np,BOOST_SPIRIT_RP_PM_MBRS,-) \ BOOST_PP_REPEAT(na,BOOST_SPIRIT_RP_AP_MBRS,-) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_PM_MBRS // // Member variables to remember parameters if there are action placeholder # define BOOST_SPIRIT_RP_PM_MBRS(z,i,d) __T ## i __p ## i ; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_AP_MBRS // // Member variables to remember action placeholder substitutes # define BOOST_SPIRIT_RP_AP_MBRS(z,i,d) __A ## i __a ## i ; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_CTOR // // Expands to a fragment of a constructor (parameters or init-list) # define BOOST_SPIRIT_RP_CTOR(what,pars,np,acts) \ BOOST_SPIRIT_RP_EMIT(PM_CTOR_ ## what,pars,__T) \ BOOST_SPIRIT_RP_EMIT(AP_CTOR_ ## what,acts,np) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_CTOR_COMMA // // RP_CTOR with a trailing comma # define BOOST_SPIRIT_RP_CTOR_COMMA(what,pars,np,acts) \ BOOST_SPIRIT_RP_CTOR(what,pars,np,acts) , // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_TPL_PARAMS // // Expands to the template parameters or arguments of the rule parser template # define BOOST_SPIRIT_RP_TPL_PARAMS(pars,acts,prefix,defaults) \ prefix ## Dummy \ BOOST_SPIRIT_RP_EMIT(PM_TEMPLATE_PARAMS,pars,prefix ## T) \ BOOST_SPIRIT_RP_EMIT(AP_TEMPLATE_PARAMS,acts,(prefix ## A,defaults)) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_GEN_FUNC // // Generator function # define BOOST_SPIRIT_RP_GEN_FUNC(name,name_t,np,na) \ template< BOOST_PP_ENUM_PARAMS(np,typename T) > \ inline name_t < void BOOST_PP_ENUM_TRAILING_PARAMS(np,T) > \ name( BOOST_PP_ENUM_BINARY_PARAMS(np,T, const & p) ) \ { return name_t < void BOOST_PP_ENUM_TRAILING_PARAMS(np,T) > \ (BOOST_PP_ENUM_PARAMS(np,p) BOOST_PP_ENUM_TRAILING_PARAMS(na, \ ::boost::spirit::type_of::nop_functor() BOOST_PP_INTERCEPT) ); \ } // RP_GEN_OPAQUE // // non-templated version for opaque rule parsers. # define BOOST_SPIRIT_RP_GEN_OPAQUE(name,name_t,np,pars) \ inline name_t name( BOOST_SPIRIT_RP_EMIT(PM_OPAQUE_GEN_PARAMS,pars,p)) \ { return name_t (BOOST_PP_ENUM_PARAMS(np,p)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_GLOB_VAR // // Global variable -- used instead of the generator function if there are no // parameters # define BOOST_SPIRIT_RP_GLOB_VAR(name,name_t,np,na) \ static name_t const name = name_t (BOOST_PP_ENUM_PARAMS(na, \ ::boost::spirit::type_of::nop_functor() BOOST_PP_INTERCEPT) ); // RP_GLOB_OPAQUE // // non-templated version for opaque rule parsers. # define BOOST_SPIRIT_RP_GLOB_OPAQUE(name,name_t,np,pars) \ static name_t const name = name_t () ; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // PP_EMIT operations (fragment emittion based on array input) // - - Namespace handling // NS_OPEN # define BOOST_SPIRIT_RP__NS_OPEN(r,data,i,elem) \ namespace BOOST_SPIRIT_RP_OPTIONAL(elem) { // NS_QUALIFY # define BOOST_SPIRIT_RP__NS_QUALIFY(r,data,i,elem) \ BOOST_SPIRIT_RP_OPTIONAL(elem ::) // NS_CLOSE # define BOOST_SPIRIT_RP__NS_CLOSE(r,data,i,elem) } // - - Parameter handling // PM_STATIC # define BOOST_SPIRIT_RP__PM_STATIC(r,data,i,elem) \ static typename ::boost::call_traits< data ## i >::reference elem ; // PM_CTOR_PARAMS # define BOOST_SPIRIT_RP__PM_CTOR_PARAMS(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) \ typename ::boost::call_traits< data ## i >::param_type elem // PM_CTOR_ARGS # define BOOST_SPIRIT_RP__PM_CTOR_ARGS(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) elem // PM_CTOR_INIT_LIST # define BOOST_SPIRIT_RP__PM_CTOR_INIT_LIST(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) __p ## i ( elem ) // PM_CTOR_COPY_INIT_LIST # define BOOST_SPIRIT_RP__PM_CTOR_COPY_INIT_LIST(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) __p ## i ( that. __p ## i ) // PM_TEMPLATE_PARAMS # define BOOST_SPIRIT_RP__PM_TEMPLATE_PARAMS(r,data,i,elem) , data ## i // - strictly typed parameters of the opaque rule_parser // PM_OPAQUE_STATIC # define BOOST_SPIRIT_RP__PM_OPAQUE_STATIC(r,data,i,elem) \ static ::boost::call_traits< \ BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(2,0,elem)) \ >::reference BOOST_PP_TUPLE_ELEM(2,1,elem) ; // PM_OPAQUE_CTOR_PARAMS # define BOOST_SPIRIT_RP__PM_OPAQUE_CTOR_PARAMS(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) ::boost::call_traits< \ BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(2,0,elem)) \ >::param_type BOOST_PP_TUPLE_ELEM(2,1,elem) // PM_OPAQUE_GEN_PARAMS # define BOOST_SPIRIT_RP__PM_OPAQUE_GEN_PARAMS(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) ::boost::call_traits< \ BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(2,0,elem)) \ >::param_type data ## i // - - Member variable handling // MV_NONSTATIC # define BOOST_SPIRIT_RP__MV_NONSTATIC(r,data,i,elem) \ data() BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(3,0,elem)) \ BOOST_PP_TUPLE_ELEM(3,1,elem) ; // MV_STATIC # define BOOST_SPIRIT_RP__MV_STATIC(r,data,i,elem) \ static data() ::boost::call_traits< \ data() BOOST_SPIRIT_RP_TYPE(BOOST_PP_TUPLE_ELEM(3,0,elem)) \ >::reference BOOST_PP_TUPLE_ELEM(3,1,elem) ; // MV_CTOR_INIT_LIST # define BOOST_SPIRIT_RP__MV_CTOR_INIT_LIST(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) \ BOOST_PP_TUPLE_ELEM(3,1,elem) BOOST_PP_TUPLE_ELEM(3,2,elem) // MV_CTOR_COPY_INIT_LIST # define BOOST_SPIRIT_RP__MV_CTOR_COPY_INIT_LIST(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) \ BOOST_PP_TUPLE_ELEM(3,1,elem) (data . BOOST_PP_TUPLE_ELEM(3,1,elem)) // - - Action placeholder handling // AP_STATIC # define BOOST_SPIRIT_RP__AP_STATIC(r,data,i,elem) static __A ## i & elem ; // AP_CTOR_PARAMS # define BOOST_SPIRIT_RP__AP_CTOR_PARAMS(r,data,i,elem) \ BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) \ typename ::boost::call_traits< __A ## i >::param_type elem // AP_CTOR_ARGS # define BOOST_SPIRIT_RP__AP_CTOR_ARGS(r,data,i,elem) \ BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) elem // AP_CTOR_INIT_LIST # define BOOST_SPIRIT_RP__AP_CTOR_INIT_LIST(r,data,i,elem) \ BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) __a ## i ( elem ) // AP_CTOR_COPY_INIT_LIST # define BOOST_SPIRIT_RP__AP_CTOR_COPY_INIT_LIST(r,data,i,elem) \ BOOST_SPIRIT_RP_COMMA_IF_OR(data,i) __a ## i ( that. __a ## i ) // AP_TEMPLATE_PARAMS # define BOOST_SPIRIT_RP__AP_TEMPLATE_PARAMS(r,data,i,elem) \ , BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,data),i) \ BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(2,1,data), \ = ::boost::spirit::type_of::nop_functor) // AP_REBOUND_ARGS # define BOOST_SPIRIT_RP__AP_REBOUND_ARGS(r,data,i,elem) \ BOOST_PP_COMMA_IF(i) \ ::boost::spirit::type_of::get_placeholdee< __action_placeholder:: elem > \ ( __a ## i , data ) // AP_REBOUND_TPL_ARGS # define BOOST_SPIRIT_RP__AP_REBOUND_TPL_ARGS(r,data,i,elem) \ , typename ::boost::spirit::type_of::placeholdee< \ __action_placeholder:: elem , __A ## i, data >::type // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // PP_EMIT // // Performs one of the operations in the above section on an optional array. // # define BOOST_SPIRIT_RP_EMIT(op, array, data) \ BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(BOOST_SPIRIT_RP__ ## op,data,array) // --- --- - - --- - - --- - - - - --- - - - - - - - - - - - - - - - - - - - - - // RP_ARRAY_FOR_EACH_I // // Iterates an optional array. That is you can pass e.g.'-' or 'none' to denote // emptiness. # define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I(macro,data,optional_array) \ BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL, \ BOOST_PP_TUPLE_EAT(3))(macro,data,optional_array) // RP_ARRAY_FOR_EACH_I_IMPL # define BOOST_SPIRIT_RP_ARRAY_FOR_EACH_I_IMPL(macro,data,array) \ BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array),PP_SEQ_FOR_EACH_I,3) \ (macro,data, BOOST_SPIRIT_RP_IF(BOOST_PP_ARRAY_SIZE(array), \ PP_TUPLE_TO_SEQ,2) array) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_ARRAY_SIZE // // Expands to the size of an "optional array". // // Examples: // // BOOST_SPIRIT_RP_ARRAY_SIZE( (2,(a,b)) ) // 2 // BOOST_SPIRIT_RP_ARRAY_SIZE( (0,()) ) // 0 // BOOST_SPIRIT_RP_ARRAY_SIZE( none ) // 0 // BOOST_SPIRIT_RP_ARRAY_SIZE( - ) // 0 // # define BOOST_SPIRIT_RP_ARRAY_SIZE(optional_array) \ BOOST_PP_IIF(BOOST_PP_IS_BINARY(optional_array), \ BOOST_PP_ARRAY_SIZE, 0 BOOST_PP_TUPLE_EAT(1))(optional_array) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_OPTIONAL // // Expands to nothing if the argument is parenthesized. // // Examples: // // BOOST_SPIRIT_RP_OPTIONAL( foobar ) // foobar // BOOST_SPIRIT_RP_OPTIONAL( (none) ) // evaluates to nothing // # define BOOST_SPIRIT_RP_OPTIONAL(elem) \ BOOST_PP_EXPR_IIF(BOOST_PP_COMPL(BOOST_PP_IS_UNARY(elem)),elem) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_COMMA_IF_OR // // Expands to nothing if both arguments are zero, otherwise expands to a comma. // # define BOOST_SPIRIT_RP_COMMA_IF_OR(a,b) \ BOOST_PP_IIF(BOOST_PP_OR(a,b),BOOST_PP_COMMA,BOOST_PP_EMPTY)() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // RP_IF // // BOOST_SPIRIT_RP_IF(cond,name,arity) // // is equivalent to: // // BOOST_PP_IF(cond,BOOST_name,BOOST_PP_TUPLE_EAT(arity)) // # define BOOST_SPIRIT_RP_IF(cond,name,arity) \ BOOST_PP_IF(cond,BOOST_ ## name,BOOST_PP_TUPLE_EAT(arity)) //------------------------------------------------------------------------------ // Wrapper and gernator function to embed a parser by reference //------------------------------------------------------------------------------ namespace boost { namespace spirit { // Wrapper to embed a parser by reference template class parser_reference : public parser< parser_reference > { P const & ref_that; public: parser_reference(P & that) // we allow implicit conversion but forbid temporaries. : ref_that(that) { } typedef parser_reference self_t; typedef self_t const & embed_t; typedef typename P::parser_category_t parser_category_t; template struct result { typedef typename P::BOOST_NESTED_TEMPLATE result::type type; }; template typename result::type parse(ScannerT const & scan) const { return this->ref_that.parse(scan); } }; template parser_reference embed_by_reference(::boost::spirit::parser & p) { return p; } } } // namespace ::boost::spirit BOOST_TYPEOF_REGISTER_TEMPLATE(boost::spirit::parser_reference, 1) //------------------------------------------------------------------------------ // Expression templates for action placeholders. //------------------------------------------------------------------------------ namespace boost { namespace spirit { namespace type_of { // No-operation functor struct nop_functor { template bool operator()(T const &) const { return false; } template bool operator()(T const &, U const &) const { return false; } typedef bool result_type; }; // Composite action template class composite_action { Action1 fnc_a1; Action2 fnc_a2; public: composite_action(Action1 const & a1, Action2 const & a2) : fnc_a1(a1), fnc_a2(a2) { } template void operator()(T const & inp) const { fnc_a1(inp); fnc_a2(inp); } template void operator()(T const & inp1, U const inp2) const { fnc_a1(inp1, inp2); fnc_a2(inp1, inp2); } }; // Action concatenation (and optimize away nop_functorS) template struct action_concatenator { typedef composite_action type; static type concatenate(Action1 const & a1, Action2 const & a2) { return composite_action(a1,a2); } }; template struct action_concatenator { typedef Action type; static type concatenate(nop_functor const &, Action const & a) { return a; } }; template struct action_concatenator { typedef Action type; static type concatenate(Action const & a, nop_functor const &) { return a; } }; template<> struct action_concatenator { typedef nop_functor type; static type concatenate(nop_functor const &, nop_functor const &) { return nop_functor(); } }; template typename action_concatenator::type concatenate_actions(Action1 const & a1, Action2 const & a2) { return action_concatenator::concatenate(a1,a2); } // Action chains enum action_chain_mode { replace, append }; template class action_chain { Action fnc_action; public: action_chain(Action const & a) : fnc_action(a) { } typedef Action action_type; Action const & action() const { return fnc_action; } }; // This operator adds actions to an action chain definition template action_chain::type> operator, (action_chain const & chain, A2 const & a) { return action_chain::type> ( concatenate_actions(chain.action(), a) ); } // Expression template for mutiple action chain assignments template class action_chains { ChainOrChains obj_head; LastChain obj_tail; public: action_chains(ChainOrChains const & head, LastChain const & tail) : obj_head(head), obj_tail(tail) { } typedef ChainOrChains head_type; typedef LastChain tail_type; head_type const & head() const { return obj_head; } tail_type const & tail() const { return obj_tail; } }; // Action chain concatenation template action_chains make_chain(Head const & h, Tail const & t) { return action_chains(h,t); } template action_chains< action_chain, action_chain > operator, (action_chain const & h, action_chain const & t) { return make_chain(h,t); } template action_chains< action_chains, action_chain > operator, (action_chains const & h, action_chain const & t) { return make_chain(h,t); } // Extract the (maybe composite) action associated with an action // placeholders from the chains with a fold algorithm. template struct placeholdee { typedef StartAction type; static type get(StartAction const & a, NewChainOrChains const &) { return a; } }; template typename placeholdee::type get_placeholdee(StartAction const & a, NewChainOrChains const & c) { return placeholdee::get(a,c); } template struct placeholdee < Placeholder, StartAction, action_chains > { typedef typename placeholdee::type, Tail >::type type; static type get(StartAction const & a, action_chains const & c) { return get_placeholdee( get_placeholdee(a,c.head()), c.tail() ); } }; template struct placeholdee < Placeholder, StartAction, action_chain > { typedef A type; static type get(StartAction const &, action_chain const & c) { return c.action(); } }; template struct placeholdee < Placeholder, StartAction, action_chain > { typedef typename action_concatenator::type type; static type get(StartAction const & a, action_chain const & c) { return concatenate_actions(a,c.action()); } }; } } } // namespace ::boost::spirit::type_of BOOST_TYPEOF_REGISTER_TYPE(boost::spirit::type_of::nop_functor) BOOST_TYPEOF_REGISTER_TEMPLATE(boost::spirit::type_of::composite_action,2) //------------------------------------------------------------------------------ // Misc.utilities //------------------------------------------------------------------------------ namespace boost { namespace spirit { namespace type_of { // Utility function to create a dependency to a template argument. template X const & depend_on_type(X const & x) { return x; } // Utility to allow use parenthesized type expressions with commas inside // as a type within macros. Thanks to Dave Abrahams for telling me this nice // trick. #define BOOST_SPIRIT_RP_TYPE(x) \ ::boost::spirit::type_of::remove_special_fptr \ < ::boost::spirit::type_of::special_result & (*) x >::type struct special_result; template struct remove_special_fptr { }; template struct remove_special_fptr< special_result & (*)(T) > { typedef T type; }; } } } // namespace ::boost::spirit::type_of //------------------------------------------------------------------------------ #endif //------------------------------------------------------------------------------
> { P const & ref_that; public: parser_reference(P & that) // we allow implicit conversion but forbid temporaries. : ref_that(that) { } typedef parser_reference
self_t; typedef self_t const & embed_t; typedef typename P::parser_category_t parser_category_t; template struct result { typedef typename P::BOOST_NESTED_TEMPLATE result::type type; }; template typename result::type parse(ScannerT const & scan) const { return this->ref_that.parse(scan); } }; template parser_reference embed_by_reference(::boost::spirit::parser & p) { return p; } } } // namespace ::boost::spirit BOOST_TYPEOF_REGISTER_TEMPLATE(boost::spirit::parser_reference, 1) //------------------------------------------------------------------------------ // Expression templates for action placeholders. //------------------------------------------------------------------------------ namespace boost { namespace spirit { namespace type_of { // No-operation functor struct nop_functor { template bool operator()(T const &) const { return false; } template bool operator()(T const &, U const &) const { return false; } typedef bool result_type; }; // Composite action template class composite_action { Action1 fnc_a1; Action2 fnc_a2; public: composite_action(Action1 const & a1, Action2 const & a2) : fnc_a1(a1), fnc_a2(a2) { } template void operator()(T const & inp) const { fnc_a1(inp); fnc_a2(inp); } template void operator()(T const & inp1, U const inp2) const { fnc_a1(inp1, inp2); fnc_a2(inp1, inp2); } }; // Action concatenation (and optimize away nop_functorS) template struct action_concatenator { typedef composite_action type; static type concatenate(Action1 const & a1, Action2 const & a2) { return composite_action(a1,a2); } }; template struct action_concatenator { typedef Action type; static type concatenate(nop_functor const &, Action const & a) { return a; } }; template struct action_concatenator { typedef Action type; static type concatenate(Action const & a, nop_functor const &) { return a; } }; template<> struct action_concatenator { typedef nop_functor type; static type concatenate(nop_functor const &, nop_functor const &) { return nop_functor(); } }; template typename action_concatenator::type concatenate_actions(Action1 const & a1, Action2 const & a2) { return action_concatenator::concatenate(a1,a2); } // Action chains enum action_chain_mode { replace, append }; template class action_chain { Action fnc_action; public: action_chain(Action const & a) : fnc_action(a) { } typedef Action action_type; Action const & action() const { return fnc_action; } }; // This operator adds actions to an action chain definition template action_chain::type> operator, (action_chain const & chain, A2 const & a) { return action_chain::type> ( concatenate_actions(chain.action(), a) ); } // Expression template for mutiple action chain assignments template class action_chains { ChainOrChains obj_head; LastChain obj_tail; public: action_chains(ChainOrChains const & head, LastChain const & tail) : obj_head(head), obj_tail(tail) { } typedef ChainOrChains head_type; typedef LastChain tail_type; head_type const & head() const { return obj_head; } tail_type const & tail() const { return obj_tail; } }; // Action chain concatenation template action_chains make_chain(Head const & h, Tail const & t) { return action_chains(h,t); } template action_chains< action_chain, action_chain > operator, (action_chain const & h, action_chain const & t) { return make_chain(h,t); } template action_chains< action_chains, action_chain > operator, (action_chains const & h, action_chain const & t) { return make_chain(h,t); } // Extract the (maybe composite) action associated with an action // placeholders from the chains with a fold algorithm. template struct placeholdee { typedef StartAction type; static type get(StartAction const & a, NewChainOrChains const &) { return a; } }; template typename placeholdee::type get_placeholdee(StartAction const & a, NewChainOrChains const & c) { return placeholdee::get(a,c); } template struct placeholdee < Placeholder, StartAction, action_chains > { typedef typename placeholdee::type, Tail >::type type; static type get(StartAction const & a, action_chains const & c) { return get_placeholdee( get_placeholdee(a,c.head()), c.tail() ); } }; template struct placeholdee < Placeholder, StartAction, action_chain > { typedef A type; static type get(StartAction const &, action_chain const & c) { return c.action(); } }; template struct placeholdee < Placeholder, StartAction, action_chain > { typedef typename action_concatenator::type type; static type get(StartAction const & a, action_chain const & c) { return concatenate_actions(a,c.action()); } }; } } } // namespace ::boost::spirit::type_of BOOST_TYPEOF_REGISTER_TYPE(boost::spirit::type_of::nop_functor) BOOST_TYPEOF_REGISTER_TEMPLATE(boost::spirit::type_of::composite_action,2) //------------------------------------------------------------------------------ // Misc.utilities //------------------------------------------------------------------------------ namespace boost { namespace spirit { namespace type_of { // Utility function to create a dependency to a template argument. template X const & depend_on_type(X const & x) { return x; } // Utility to allow use parenthesized type expressions with commas inside // as a type within macros. Thanks to Dave Abrahams for telling me this nice // trick. #define BOOST_SPIRIT_RP_TYPE(x) \ ::boost::spirit::type_of::remove_special_fptr \ < ::boost::spirit::type_of::special_result & (*) x >::type struct special_result; template struct remove_special_fptr { }; template struct remove_special_fptr< special_result & (*)(T) > { typedef T type; }; } } } // namespace ::boost::spirit::type_of //------------------------------------------------------------------------------ #endif //------------------------------------------------------------------------------
embed_by_reference(::boost::spirit::parser
& p) { return p; } } } // namespace ::boost::spirit BOOST_TYPEOF_REGISTER_TEMPLATE(boost::spirit::parser_reference, 1) //------------------------------------------------------------------------------ // Expression templates for action placeholders. //------------------------------------------------------------------------------ namespace boost { namespace spirit { namespace type_of { // No-operation functor struct nop_functor { template bool operator()(T const &) const { return false; } template bool operator()(T const &, U const &) const { return false; } typedef bool result_type; }; // Composite action template class composite_action { Action1 fnc_a1; Action2 fnc_a2; public: composite_action(Action1 const & a1, Action2 const & a2) : fnc_a1(a1), fnc_a2(a2) { } template void operator()(T const & inp) const { fnc_a1(inp); fnc_a2(inp); } template void operator()(T const & inp1, U const inp2) const { fnc_a1(inp1, inp2); fnc_a2(inp1, inp2); } }; // Action concatenation (and optimize away nop_functorS) template struct action_concatenator { typedef composite_action type; static type concatenate(Action1 const & a1, Action2 const & a2) { return composite_action(a1,a2); } }; template struct action_concatenator { typedef Action type; static type concatenate(nop_functor const &, Action const & a) { return a; } }; template struct action_concatenator { typedef Action type; static type concatenate(Action const & a, nop_functor const &) { return a; } }; template<> struct action_concatenator { typedef nop_functor type; static type concatenate(nop_functor const &, nop_functor const &) { return nop_functor(); } }; template typename action_concatenator::type concatenate_actions(Action1 const & a1, Action2 const & a2) { return action_concatenator::concatenate(a1,a2); } // Action chains enum action_chain_mode { replace, append }; template class action_chain { Action fnc_action; public: action_chain(Action const & a) : fnc_action(a) { } typedef Action action_type; Action const & action() const { return fnc_action; } }; // This operator adds actions to an action chain definition template action_chain::type> operator, (action_chain const & chain, A2 const & a) { return action_chain::type> ( concatenate_actions(chain.action(), a) ); } // Expression template for mutiple action chain assignments template class action_chains { ChainOrChains obj_head; LastChain obj_tail; public: action_chains(ChainOrChains const & head, LastChain const & tail) : obj_head(head), obj_tail(tail) { } typedef ChainOrChains head_type; typedef LastChain tail_type; head_type const & head() const { return obj_head; } tail_type const & tail() const { return obj_tail; } }; // Action chain concatenation template action_chains make_chain(Head const & h, Tail const & t) { return action_chains(h,t); } template action_chains< action_chain, action_chain > operator, (action_chain const & h, action_chain const & t) { return make_chain(h,t); } template action_chains< action_chains, action_chain > operator, (action_chains const & h, action_chain const & t) { return make_chain(h,t); } // Extract the (maybe composite) action associated with an action // placeholders from the chains with a fold algorithm. template struct placeholdee { typedef StartAction type; static type get(StartAction const & a, NewChainOrChains const &) { return a; } }; template typename placeholdee::type get_placeholdee(StartAction const & a, NewChainOrChains const & c) { return placeholdee::get(a,c); } template struct placeholdee < Placeholder, StartAction, action_chains > { typedef typename placeholdee::type, Tail >::type type; static type get(StartAction const & a, action_chains const & c) { return get_placeholdee( get_placeholdee(a,c.head()), c.tail() ); } }; template struct placeholdee < Placeholder, StartAction, action_chain > { typedef A type; static type get(StartAction const &, action_chain const & c) { return c.action(); } }; template struct placeholdee < Placeholder, StartAction, action_chain > { typedef typename action_concatenator::type type; static type get(StartAction const & a, action_chain const & c) { return concatenate_actions(a,c.action()); } }; } } } // namespace ::boost::spirit::type_of BOOST_TYPEOF_REGISTER_TYPE(boost::spirit::type_of::nop_functor) BOOST_TYPEOF_REGISTER_TEMPLATE(boost::spirit::type_of::composite_action,2) //------------------------------------------------------------------------------ // Misc.utilities //------------------------------------------------------------------------------ namespace boost { namespace spirit { namespace type_of { // Utility function to create a dependency to a template argument. template X const & depend_on_type(X const & x) { return x; } // Utility to allow use parenthesized type expressions with commas inside // as a type within macros. Thanks to Dave Abrahams for telling me this nice // trick. #define BOOST_SPIRIT_RP_TYPE(x) \ ::boost::spirit::type_of::remove_special_fptr \ < ::boost::spirit::type_of::special_result & (*) x >::type struct special_result; template struct remove_special_fptr { }; template struct remove_special_fptr< special_result & (*)(T) > { typedef T type; }; } } } // namespace ::boost::spirit::type_of //------------------------------------------------------------------------------ #endif //------------------------------------------------------------------------------