/*============================================================================= | |
Copyright (c) 2001-2011 Joel de Guzman | |
Copyright (c) 2001-2011 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 |