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/home/support/attributes.hpp> 17 #include <boost/spirit/home/lex/lexer/pass_flags.hpp> 18 #include <boost/phoenix/core/argument.hpp> 19 #include <boost/phoenix/bind.hpp> 20 21 /////////////////////////////////////////////////////////////////////////////// 22 namespace boost { namespace spirit { namespace lex { namespace lexertl 23 { 24 namespace detail 25 { 26 template <typename FunctionType, typename Iterator, typename Context 27 , typename IdType> 28 struct wrap_action 29 { 30 // plain functions with 5 arguments, function objects (including 31 // phoenix actors) are not touched at all 32 template <typename F> callboost::spirit::lex::lexertl::detail::wrap_action33 static FunctionType call(F const& f) 34 { 35 return f; 36 } 37 38 // semantic actions with 4 arguments 39 template <typename F> arg4_actionboost::spirit::lex::lexertl::detail::wrap_action40 static void arg4_action(F* f, Iterator& start, Iterator& end 41 , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType& id 42 , Context const&) 43 { 44 f(start, end, pass, id); 45 } 46 47 template <typename A0, typename A1, typename A2, typename A3> callboost::spirit::lex::lexertl::detail::wrap_action48 static FunctionType call(void (*f)(A0, A1, A2, A3)) 49 { 50 void (*pf)(void(*)(A0, A1, A2, A3) 51 , Iterator&, Iterator&, BOOST_SCOPED_ENUM(pass_flags)& 52 , IdType&, Context const&) = &wrap_action::arg4_action; 53 54 using phoenix::arg_names::_1; 55 using phoenix::arg_names::_2; 56 using phoenix::arg_names::_3; 57 using phoenix::arg_names::_4; 58 using phoenix::arg_names::_5; 59 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 60 } 61 62 // semantic actions with 3 arguments 63 template <typename F> arg3_actionboost::spirit::lex::lexertl::detail::wrap_action64 static void arg3_action(F* f, Iterator& start, Iterator& end 65 , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType 66 , Context const&) 67 { 68 f(start, end, pass); 69 } 70 71 template <typename A0, typename A1, typename A2> callboost::spirit::lex::lexertl::detail::wrap_action72 static FunctionType call(void (*f)(A0, A1, A2)) 73 { 74 void (*pf)(void(*)(A0, A1, A2), Iterator&, Iterator& 75 , BOOST_SCOPED_ENUM(pass_flags)&, IdType 76 , Context const&) = &wrap_action::arg3_action; 77 78 using phoenix::arg_names::_1; 79 using phoenix::arg_names::_2; 80 using phoenix::arg_names::_3; 81 using phoenix::arg_names::_4; 82 using phoenix::arg_names::_5; 83 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 84 } 85 86 // semantic actions with 2 arguments 87 template <typename F> arg2_actionboost::spirit::lex::lexertl::detail::wrap_action88 static void arg2_action(F* f, Iterator& start, Iterator& end 89 , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) 90 { 91 f (start, end); 92 } 93 94 template <typename A0, typename A1> callboost::spirit::lex::lexertl::detail::wrap_action95 static FunctionType call(void (*f)(A0, A1)) 96 { 97 void (*pf)(void(*)(A0, A1), Iterator&, Iterator& 98 , BOOST_SCOPED_ENUM(pass_flags)& 99 , IdType, Context const&) = &wrap_action::arg2_action; 100 101 using phoenix::arg_names::_1; 102 using phoenix::arg_names::_2; 103 using phoenix::arg_names::_3; 104 using phoenix::arg_names::_4; 105 using phoenix::arg_names::_5; 106 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 107 } 108 109 // we assume that either both iterators are to be passed to the 110 // semantic action or none iterator at all (i.e. it's not possible 111 // to have a lexer semantic action function taking one arguments). 112 113 // semantic actions with 0 argument 114 template <typename F> arg0_actionboost::spirit::lex::lexertl::detail::wrap_action115 static void arg0_action(F* f, Iterator&, Iterator& 116 , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) 117 { 118 f(); 119 } 120 callboost::spirit::lex::lexertl::detail::wrap_action121 static FunctionType call(void (*f)()) 122 { 123 void (*pf)(void(*)(), Iterator&, Iterator& 124 , BOOST_SCOPED_ENUM(pass_flags)& 125 , IdType, Context const&) = &arg0_action; 126 127 using phoenix::arg_names::_1; 128 using phoenix::arg_names::_2; 129 using phoenix::arg_names::_3; 130 using phoenix::arg_names::_4; 131 using phoenix::arg_names::_5; 132 return phoenix::bind(pf, f, _1, _2, _3, _4, _5); 133 } 134 }; 135 136 // specialization allowing to skip wrapping for lexer types not 137 // supporting semantic actions 138 template <typename Iterator, typename Context, typename Idtype> 139 struct wrap_action<unused_type, Iterator, Context, Idtype> 140 { 141 // plain function objects are not touched at all 142 template <typename F> callboost::spirit::lex::lexertl::detail::wrap_action143 static F const& call(F const& f) 144 { 145 return f; 146 } 147 }; 148 } 149 150 }}}} 151 152 #endif 153