| /*============================================================================= |
| Copyright (c) 2001-2010 Joel de Guzman |
| Copyright (c) 2001-2010 Hartmut Kaiser |
| http://spirit.sourceforge.net/ |
| |
| Distributed under the Boost Software License, Version 1.0. (See accompanying |
| file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| =============================================================================*/ |
| #if !defined(BOOST_SPIRIT_WRAP_ACTION_APR_19_2008_0103PM) |
| #define BOOST_SPIRIT_WRAP_ACTION_APR_19_2008_0103PM |
| |
| #if defined(_MSC_VER) |
| #pragma once |
| #endif |
| |
| #include <boost/spirit/home/phoenix/core/actor.hpp> |
| #include <boost/spirit/home/phoenix/core/argument.hpp> |
| #include <boost/spirit/home/phoenix/bind.hpp> |
| #include <boost/spirit/home/phoenix/scope.hpp> |
| #include <boost/spirit/home/support/attributes.hpp> |
| #include <boost/spirit/home/lex/lexer/pass_flags.hpp> |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| namespace boost { namespace spirit { namespace lex { namespace lexertl |
| { |
| namespace detail |
| { |
| template <typename FunctionType, typename Iterator, typename Context |
| , typename IdType> |
| struct wrap_action |
| { |
| // plain functions with 5 arguments and function objects are not |
| // touched at all |
| template <typename F> |
| static FunctionType call(F const& f) |
| { |
| return f; |
| } |
| |
| // wrap phoenix actor |
| struct phoenix_action |
| { |
| template <typename F, typename T1, typename T2, typename T3 |
| , typename T4, typename T5> |
| struct result { typedef void type; }; |
| |
| template <typename Eval> |
| void operator()(phoenix::actor<Eval> const& f, Iterator& start |
| , Iterator& end, BOOST_SCOPED_ENUM(pass_flags)& pass |
| , IdType& id, Context& ctx) const |
| { |
| f (start, end, pass, id, ctx); |
| } |
| }; |
| |
| template <typename Eval> |
| static FunctionType call(phoenix::actor<Eval> const& f) |
| { |
| using phoenix::arg_names::_1; |
| using phoenix::arg_names::_2; |
| using phoenix::arg_names::_3; |
| using phoenix::arg_names::_4; |
| using phoenix::arg_names::_5; |
| return phoenix::bind(phoenix_action(), phoenix::lambda[f], |
| _1, _2, _3, _4, _5); |
| } |
| |
| // semantic actions with 4 arguments |
| template <typename F> |
| static void arg4_action(F* f, Iterator& start, Iterator& end |
| , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType& id |
| , Context const&) |
| { |
| f(start, end, pass, id); |
| } |
| |
| template <typename A0, typename A1, typename A2, typename A3> |
| static FunctionType call(void (*f)(A0, A1, A2, A3)) |
| { |
| void (*pf)(void(*)(A0, A1, A2, A3) |
| , Iterator&, Iterator&, BOOST_SCOPED_ENUM(pass_flags)& |
| , IdType&, Context const&) = &wrap_action::arg4_action; |
| |
| using phoenix::arg_names::_1; |
| using phoenix::arg_names::_2; |
| using phoenix::arg_names::_3; |
| using phoenix::arg_names::_4; |
| using phoenix::arg_names::_5; |
| return phoenix::bind(pf, f, _1, _2, _3, _4, _5); |
| } |
| |
| // semantic actions with 3 arguments |
| template <typename F> |
| static void arg3_action(F* f, Iterator& start, Iterator& end |
| , BOOST_SCOPED_ENUM(pass_flags)& pass, IdType |
| , Context const&) |
| { |
| f(start, end, pass); |
| } |
| |
| template <typename A0, typename A1, typename A2> |
| static FunctionType call(void (*f)(A0, A1, A2)) |
| { |
| void (*pf)(void(*)(A0, A1, A2), Iterator&, Iterator& |
| , BOOST_SCOPED_ENUM(pass_flags)&, IdType |
| , Context const&) = &wrap_action::arg3_action; |
| |
| using phoenix::arg_names::_1; |
| using phoenix::arg_names::_2; |
| using phoenix::arg_names::_3; |
| using phoenix::arg_names::_4; |
| using phoenix::arg_names::_5; |
| return phoenix::bind(pf, f, _1, _2, _3, _4, _5); |
| } |
| |
| // semantic actions with 2 arguments |
| template <typename F> |
| static void arg2_action(F* f, Iterator& start, Iterator& end |
| , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) |
| { |
| f (start, end); |
| } |
| |
| template <typename A0, typename A1> |
| static FunctionType call(void (*f)(A0, A1)) |
| { |
| void (*pf)(void(*)(A0, A1), Iterator&, Iterator& |
| , BOOST_SCOPED_ENUM(pass_flags)& |
| , IdType, Context const&) = &wrap_action::arg2_action; |
| |
| using phoenix::arg_names::_1; |
| using phoenix::arg_names::_2; |
| using phoenix::arg_names::_3; |
| using phoenix::arg_names::_4; |
| using phoenix::arg_names::_5; |
| return phoenix::bind(pf, f, _1, _2, _3, _4, _5); |
| } |
| |
| // we assume that either both iterators are to be passed to the |
| // semantic action or none iterator at all (i.e. it's not possible |
| // to have a lexer semantic action function taking one arguments). |
| |
| // semantic actions with 0 argument |
| template <typename F> |
| static void arg0_action(F* f, Iterator&, Iterator& |
| , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&) |
| { |
| f(); |
| } |
| |
| static FunctionType call(void (*f)()) |
| { |
| void (*pf)(void(*)(), Iterator&, Iterator& |
| , BOOST_SCOPED_ENUM(pass_flags)& |
| , IdType, Context const&) = &arg0_action; |
| |
| using phoenix::arg_names::_1; |
| using phoenix::arg_names::_2; |
| using phoenix::arg_names::_3; |
| using phoenix::arg_names::_4; |
| using phoenix::arg_names::_5; |
| return phoenix::bind(pf, f, _1, _2, _3, _4, _5); |
| } |
| }; |
| |
| // specialization allowing to skip wrapping for lexer types not |
| // supporting semantic actions |
| template <typename Iterator, typename Context, typename Idtype> |
| struct wrap_action<unused_type, Iterator, Context, Idtype> |
| { |
| // plain function objects are not touched at all |
| template <typename F> |
| static F const& call(F const& f) |
| { |
| return f; |
| } |
| }; |
| } |
| |
| }}}} |
| |
| #endif |