1 /*============================================================================= 2 Copyright (c) 2001-2011 Joel de Guzman 3 Copyright (c) 2001-2011 Hartmut Kaiser 4 http://spirit.sourceforge.net/ 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #if !defined(BOOST_SPIRIT_WRAP_ACTION_APR_19_2008_0103PM) 10 #define BOOST_SPIRIT_WRAP_ACTION_APR_19_2008_0103PM 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 #include <boost/spirit/include/phoenix_core.hpp> 17 #include <boost/spirit/include/phoenix_bind.hpp> 18 #include <boost/spirit/include/phoenix_scope.hpp> 19 20 #include <boost/spirit/home/support/attributes.hpp> 21 #include <boost/spirit/home/lex/lexer/pass_flags.hpp> 22 23 /////////////////////////////////////////////////////////////////////////////// 24 namespace boost { namespace spirit { namespace lex { namespace lexertl 25 { 26 namespace detail 27 { 28 template <typename FunctionType, typename Iterator, typename Context 29 , typename IdType> 30 struct wrap_action 31 { 32 // plain functions with 5 arguments, function objects (including 33 // phoenix actors) are not touched at all 34 template <typename F> callboost::spirit::lex::lexertl::detail::wrap_action35 static FunctionType call(F const& f) 36 { 37 return f; 38 } 39 40 // semantic actions with 4 arguments 41 template <typename F> arg4_actionboost::spirit::lex::lexertl::detail::wrap_action42 static void arg4_action(F* f, Iterator& start, Iterator& end 43 , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType& id 44 , Context const&) 45 { 46 f(start, end, pass, id); 47 } 48 49 template <typename A0, typename A1, typename A2, typename A3> callboost::spirit::lex::lexertl::detail::wrap_action50 static FunctionType call(void (*f)(A0, A1, A2, A3)) 51 { 52 void (*pf)(void(*)(A0, A1, A2, A3) 53 , Iterator&, Iterator&, BOOST_SCOPED_ENUM(pass_flags)& 54 , IdType&, Context const&) = &wrap_action::arg4_action; 55 56 using phoenix::arg_names::_1; 57 using phoenix::arg_names::_2; 58 using phoenix::arg_names::_3; 59 using phoenix::arg_names::_4; 60 using phoenix::arg_names::_5; 61 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 62 } 63 64 // semantic actions with 3 arguments 65 template <typename F> arg3_actionboost::spirit::lex::lexertl::detail::wrap_action66 static void arg3_action(F* f, Iterator& start, Iterator& end 67 , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType 68 , Context const&) 69 { 70 f(start, end, pass); 71 } 72 73 template <typename A0, typename A1, typename A2> callboost::spirit::lex::lexertl::detail::wrap_action74 static FunctionType call(void (*f)(A0, A1, A2)) 75 { 76 void (*pf)(void(*)(A0, A1, A2), Iterator&, Iterator& 77 , BOOST_SCOPED_ENUM(pass_flags)&, IdType 78 , Context const&) = &wrap_action::arg3_action; 79 80 using phoenix::arg_names::_1; 81 using phoenix::arg_names::_2; 82 using phoenix::arg_names::_3; 83 using phoenix::arg_names::_4; 84 using phoenix::arg_names::_5; 85 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 86 } 87 88 // semantic actions with 2 arguments 89 template <typename F> arg2_actionboost::spirit::lex::lexertl::detail::wrap_action90 static void arg2_action(F* f, Iterator& start, Iterator& end 91 , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) 92 { 93 f (start, end); 94 } 95 96 template <typename A0, typename A1> callboost::spirit::lex::lexertl::detail::wrap_action97 static FunctionType call(void (*f)(A0, A1)) 98 { 99 void (*pf)(void(*)(A0, A1), Iterator&, Iterator& 100 , BOOST_SCOPED_ENUM(pass_flags)& 101 , IdType, Context const&) = &wrap_action::arg2_action; 102 103 using phoenix::arg_names::_1; 104 using phoenix::arg_names::_2; 105 using phoenix::arg_names::_3; 106 using phoenix::arg_names::_4; 107 using phoenix::arg_names::_5; 108 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 109 } 110 111 // we assume that either both iterators are to be passed to the 112 // semantic action or none iterator at all (i.e. it's not possible 113 // to have a lexer semantic action function taking one arguments). 114 115 // semantic actions with 0 argument 116 template <typename F> arg0_actionboost::spirit::lex::lexertl::detail::wrap_action117 static void arg0_action(F* f, Iterator&, Iterator& 118 , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) 119 { 120 f(); 121 } 122 callboost::spirit::lex::lexertl::detail::wrap_action123 static FunctionType call(void (*f)()) 124 { 125 void (*pf)(void(*)(), Iterator&, Iterator& 126 , BOOST_SCOPED_ENUM(pass_flags)& 127 , IdType, Context const&) = &arg0_action; 128 129 using phoenix::arg_names::_1; 130 using phoenix::arg_names::_2; 131 using phoenix::arg_names::_3; 132 using phoenix::arg_names::_4; 133 using phoenix::arg_names::_5; 134 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 135 } 136 }; 137 138 // specialization allowing to skip wrapping for lexer types not 139 // supporting semantic actions 140 template <typename Iterator, typename Context, typename Idtype> 141 struct wrap_action<unused_type, Iterator, Context, Idtype> 142 { 143 // plain function objects are not touched at all 144 template <typename F> callboost::spirit::lex::lexertl::detail::wrap_action145 static F const& call(F const& f) 146 { 147 return f; 148 } 149 }; 150 } 151 152 }}}} 153 154 #endif 155