]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/support/action_dispatch.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / support / action_dispatch.hpp
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_ACTION_DISPATCH_APRIL_18_2008_0720AM)
10 #define BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include<boost/config.hpp>
17
18 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
19 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
20 #include <utility>
21 #include <type_traits>
22 #endif
23
24
25 #include <boost/spirit/include/phoenix_core.hpp>
26 #include <boost/spirit/home/support/attributes.hpp>
27
28 namespace boost { namespace spirit { namespace traits
29 {
30 template <typename Component>
31 struct action_dispatch
32 {
33 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
34 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
35 // omit function parameters without specializing for each possible
36 // type of callable entity
37 // many thanks to Eelis/##iso-c++ for this contribution
38
39 private:
40 // this will be used to pass around POD types which are safe
41 // to go through the ellipsis operator (if ever used)
42 template <typename>
43 struct fwd_tag {};
44
45 // the first parameter is a placeholder to obtain SFINAE when
46 // doing overload resolution, the second one is the actual
47 // forwarder, where we can apply our implementation
48 template <typename, typename T>
49 struct fwd_storage { typedef T type; };
50
51 // gcc should accept fake<T>() but it prints a sorry, needs
52 // a check once the bug is sorted out, use a FAKE_CALL macro for now
53 template <typename T>
54 T fake_call();
55
56 #define BOOST_SPIRIT_FAKE_CALL(T) (*(T*)0)
57
58 // the forwarders, here we could tweak the implementation of
59 // how parameters are passed to the functions, if needed
60 struct fwd_none
61 {
62 template<typename F, typename... Rest>
63 auto operator()(F && f, Rest&&...) -> decltype(f())
64 {
65 return f();
66 }
67 };
68
69 struct fwd_attrib
70 {
71 template<typename F, typename A, typename... Rest>
72 auto operator()(F && f, A && a, Rest&&...) -> decltype(f(a))
73 {
74 return f(a);
75 }
76 };
77
78 struct fwd_attrib_context
79 {
80 template<typename F, typename A, typename B, typename... Rest>
81 auto operator()(F && f, A && a, B && b, Rest&&...)
82 -> decltype(f(a, b))
83 {
84 return f(a, b);
85 }
86 };
87
88 struct fwd_attrib_context_pass
89 {
90 template<typename F, typename A, typename B, typename C
91 , typename... Rest>
92 auto operator()(F && f, A && a, B && b, C && c, Rest&&...)
93 -> decltype(f(a, b, c))
94 {
95 return f(a, b, c);
96 }
97 };
98
99 // SFINAE for our calling syntax, the forwarders are stored based
100 // on what function call gives a proper result
101 // this code can probably be more generic once implementations are
102 // steady
103 template <typename F>
104 static auto do_call(F && f, ...)
105 -> typename fwd_storage<decltype(f()), fwd_none>::type
106 {
107 return {};
108 }
109
110 template <typename F, typename A>
111 static auto do_call(F && f, fwd_tag<A>, ...)
112 -> typename fwd_storage<decltype(f(BOOST_SPIRIT_FAKE_CALL(A)))
113 , fwd_attrib>::type
114 {
115 return {};
116 }
117
118 template <typename F, typename A, typename B>
119 static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, ...)
120 -> typename fwd_storage<
121 decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)))
122 , fwd_attrib_context>::type
123 {
124 return {};
125 }
126
127 template <typename F, typename A, typename B, typename C>
128 static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, fwd_tag<C>, ...)
129 -> typename fwd_storage<
130 decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)
131 , BOOST_SPIRIT_FAKE_CALL(C)))
132 , fwd_attrib_context_pass>::type
133 {
134 return {};
135 }
136
137 // this function calls the forwarder and is responsible for
138 // stripping the tail of the parameters
139 template <typename F, typename... A>
140 static void caller(F && f, A && ... a)
141 {
142 do_call(f, fwd_tag<typename std::remove_reference<A>::type>()...)
143 (std::forward<F>(f), std::forward<A>(a)...);
144 }
145
146 #undef BOOST_SPIRIT_FAKE_CALL
147
148 public:
149 template <typename F, typename Attribute, typename Context>
150 bool operator()(F const& f, Attribute& attr, Context& context)
151 {
152 bool pass = true;
153 caller(f, attr, context, pass);
154 return pass;
155 }
156 #else
157 // general handler for everything not explicitly specialized below
158 template <typename F, typename Attribute, typename Context>
159 bool operator()(F const& f, Attribute& attr, Context& context)
160 {
161 bool pass = true;
162 f(attr, context, pass);
163 return pass;
164 }
165 #endif
166
167 // handler for phoenix actors
168
169 // If the component this action has to be invoked for is a tuple, we
170 // wrap any non-fusion tuple into a fusion tuple (done by pass_attribute)
171 // and pass through any fusion tuple.
172 template <typename Eval, typename Attribute, typename Context>
173 bool operator()(phoenix::actor<Eval> const& f
174 , Attribute& attr, Context& context)
175 {
176 bool pass = true;
177 typename pass_attribute<Component, Attribute>::type attr_wrap(attr);
178 f(attr_wrap, context, pass);
179 return pass;
180 }
181
182 // specializations for plain function pointers taking different number of
183 // arguments
184 template <typename RT, typename A0, typename A1, typename A2
185 , typename Attribute, typename Context>
186 bool operator()(RT(*f)(A0, A1, A2), Attribute& attr, Context& context)
187 {
188 bool pass = true;
189 f(attr, context, pass);
190 return pass;
191 }
192
193 template <typename RT, typename A0, typename A1
194 , typename Attribute, typename Context>
195 bool operator()(RT(*f)(A0, A1), Attribute& attr, Context& context)
196 {
197 f(attr, context);
198 return true;
199 }
200
201 template <typename RT, typename A0, typename Attribute, typename Context>
202 bool operator()(RT(*f)(A0), Attribute& attr, Context&)
203 {
204 f(attr);
205 return true;
206 }
207
208 template <typename RT, typename Attribute, typename Context>
209 bool operator()(RT(*f)(), Attribute&, Context&)
210 {
211 f();
212 return true;
213 }
214 };
215 }}}
216
217 #endif