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