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///////////////////////////////////////////////////////////////////////////////
22namespace 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>
33 static FunctionType call(F const& f)
34 {
35 return f;
36 }
37
38 // semantic actions with 4 arguments
39 template <typename F>
40 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>
48 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>
64 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>
72 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>
88 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>
95 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>
115 static void arg0_action(F* f, Iterator&, Iterator&
116 , BOOST_SCOPED_ENUM(pass_flags)&, IdType, Context const&)
117 {
118 f();
119 }
120
121 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>
143 static F const& call(F const& f)
144 {
145 return f;
146 }
147 };
148 }
149
150}}}}
151
152#endif
153

source code of boost/libs/spirit/include/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp