]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/local_function/include/boost/local_function/aux_/function.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / local_function / include / boost / local_function / aux_ / function.hpp
CommitLineData
7c673cae
FG
1
2// Copyright (C) 2009-2012 Lorenzo Caminiti
3// Distributed under the Boost Software License, Version 1.0
4// (see accompanying file LICENSE_1_0.txt or a copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6// Home at http://www.boost.org/libs/local_function
7
8#if !BOOST_PP_IS_ITERATING
9# ifndef BOOST_LOCAL_FUNCTION_AUX_FUNCTION_HPP_
10# define BOOST_LOCAL_FUNCTION_AUX_FUNCTION_HPP_
11
12# include <boost/local_function/config.hpp>
13# include <boost/local_function/aux_/member.hpp>
14# include <boost/call_traits.hpp>
15# include <boost/typeof/typeof.hpp>
16# include <boost/config.hpp>
17# include <boost/preprocessor/iteration/iterate.hpp>
18# include <boost/preprocessor/repetition/repeat.hpp>
19# include <boost/preprocessor/repetition/enum.hpp>
20# include <boost/preprocessor/punctuation/comma_if.hpp>
21# include <boost/preprocessor/arithmetic/add.hpp>
22# include <boost/preprocessor/arithmetic/sub.hpp>
23# include <boost/preprocessor/arithmetic/inc.hpp>
24# include <boost/preprocessor/control/iif.hpp>
25# include <boost/preprocessor/cat.hpp>
26
27// PRIVATE //
28
29#define BOOST_LOCAL_FUNCTION_AUX_FUNCTION_THIS_FILE_ \
30 "boost/local_function/aux_/function.hpp"
31
32// PUBLIC //
33
34#define BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC \
35 BOOST_LOCAL_FUNCTION_AUX_SYMBOL( (init_call) )
36
37#define BOOST_LOCAL_FUNCTION_AUX_typename_seq(z, n, unused) \
38 (typename)
39
40#define BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, unused) \
41 BOOST_PP_CAT(Arg, arg_n)
42
43#define BOOST_LOCAL_FUNCTION_AUX_arg_typedef(z, arg_n, unused) \
44 typedef \
45 BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, ~) \
46 /* name must follow Boost.FunctionTraits arg1_type, arg2_type, ... */ \
47 BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(arg_n)), _type) \
48 ;
49
50#define BOOST_LOCAL_FUNCTION_AUX_comma_arg_tparam(z, arg_n, unused) \
51 , typename BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, ~)
52
53#define BOOST_LOCAL_FUNCTION_AUX_arg_param_type(z, arg_n, comma01) \
54 BOOST_PP_COMMA_IF(comma01) \
55 typename ::boost::call_traits< \
56 BOOST_LOCAL_FUNCTION_AUX_arg_type(z, arg_n, ~) \
57 >::param_type
58
59#define BOOST_LOCAL_FUNCTION_AUX_arg_name(z, arg_n, comma01) \
60 BOOST_PP_COMMA_IF(comma01) \
61 BOOST_PP_CAT(arg, arg_n)
62
63#define BOOST_LOCAL_FUNCTION_AUX_arg_param_decl(z, arg_n, unused) \
64 BOOST_LOCAL_FUNCTION_AUX_arg_param_type(z, arg_n, 0 /* no leading comma */)\
65 BOOST_LOCAL_FUNCTION_AUX_arg_name(z, arg_n, 0 /* no leading comma */)
66
67#define BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, unused) \
68 BOOST_PP_CAT(Bind, bind_n)
69
70#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_type(z, bind_n, unused) \
71 , BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~)
72
73#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_ref(z, bind_n, unused) \
74 , BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) &
75
76#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam(z, bind_n, unused) \
77 , typename BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~)
78
79#define BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, unused) \
80 BOOST_PP_CAT(bing, bind_n)
81
82#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_param_decl(z, bind_n, unused) \
83 , \
84 BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) & \
85 BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, ~)
86
87#define BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, unsued) \
88 BOOST_PP_CAT(BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, ~), _)
89
90#define BOOST_LOCAL_FUNCTION_AUX_comma_bind_member_deref(z, bind_n, unsued) \
91 , member_deref< BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) >( \
92 BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, ~))
93
94#define BOOST_LOCAL_FUNCTION_AUX_bind_member_init(z, bind_n, unused) \
95 BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, ~) = member_addr( \
96 BOOST_LOCAL_FUNCTION_AUX_bind_name(z, bind_n, ~));
97
98#define BOOST_LOCAL_FUNCTION_AUX_bind_member_decl(z, bind_n, unused) \
99 /* must be ptr (not ref) so can use default constr */ \
100 typename member_type< \
101 BOOST_LOCAL_FUNCTION_AUX_bind_type(z, bind_n, ~) \
102 >::pointer BOOST_LOCAL_FUNCTION_AUX_bind_member(z, bind_n, ~) ;
103
104#define BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, unused) \
105 BOOST_PP_CAT(call_ptr, n)
106
107#define BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, unused) \
108 BOOST_PP_CAT(call, n)
109
110#define BOOST_LOCAL_FUNCTION_AUX_call_member(z, n, unused) \
111 BOOST_PP_CAT(BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, unused), _)
112
113#define BOOST_LOCAL_FUNCTION_AUX_call_typedef(z, n, arity) \
114 typedef R (*BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, ~))( \
115 object_ptr \
116 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS, \
117 BOOST_PP_TUPLE_EAT(3) \
118 , \
119 BOOST_PP_REPEAT_ ## z \
120 )(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \
121 BOOST_LOCAL_FUNCTION_AUX_comma_bind_ref, ~) \
122 BOOST_PP_REPEAT_ ## z(BOOST_PP_SUB(arity, n), \
123 BOOST_LOCAL_FUNCTION_AUX_arg_param_type, 1 /* leading comma */)\
124 );
125
126#define BOOST_LOCAL_FUNCTION_AUX_comma_call_param_decl(z, n, unused) \
127 , \
128 BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, ~) \
129 BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, ~)
130
131#define BOOST_LOCAL_FUNCTION_AUX_call_decl(z, n, unused) \
132 BOOST_LOCAL_FUNCTION_AUX_call_ptr(z, n, ~) \
133 BOOST_LOCAL_FUNCTION_AUX_call_member(z, n, ~);
134
135#define BOOST_LOCAL_FUNCTION_AUX_call_init(z, n, unused) \
136 BOOST_LOCAL_FUNCTION_AUX_call_member(z, n, ~) = \
137 BOOST_LOCAL_FUNCTION_AUX_call_name(z, n, ~);
138
139#define BOOST_LOCAL_FUNCTION_AUX_operator_call(z, defaults_n, arity) \
140 /* precondition: object_ && call_function_ */ \
141 inline R operator()( \
142 BOOST_PP_ENUM_ ## z(BOOST_PP_SUB(arity, defaults_n), \
143 BOOST_LOCAL_FUNCTION_AUX_arg_param_decl, ~) \
144 ) /* cannot be const because of binds (same as for local ftor) */ { \
145 /* run-time: do not assert preconditions here for efficiency */ \
146 /* run-time: this function call is done via a function pointer */ \
147 /* so unfortunately does not allow for compiler inlining */ \
148 /* optimizations (an alternative using virtual function was also */ \
149 /* investigated but also virtual functions cannot be optimized */ \
150 /* plus they require virtual table lookups to the alternative */ \
151 /* performed worst) */ \
152 return BOOST_LOCAL_FUNCTION_AUX_call_member(z, defaults_n, ~)( \
153 object_ \
154 BOOST_PP_IIF( \
155 BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,\
156 BOOST_PP_TUPLE_EAT(3) \
157 , \
158 BOOST_PP_REPEAT_ ## z \
159 )(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX, \
160 BOOST_LOCAL_FUNCTION_AUX_comma_bind_member_deref, ~) \
161 BOOST_PP_REPEAT_ ## z(BOOST_PP_SUB(arity, defaults_n), \
162 BOOST_LOCAL_FUNCTION_AUX_arg_name, 1 /* leading comma */) \
163 ); \
164 }
165
166namespace boost { namespace local_function { namespace aux {
167
168template<
169 typename F
170 , size_t defaults
171#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS
172 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX,
173 BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam, ~)
174#endif
175>
176class function {}; // Empty template, only use its specializations.
177
178// Iterate within namespace.
179# define BOOST_PP_ITERATION_PARAMS_1 \
180 (3, (0, BOOST_LOCAL_FUNCTION_CONFIG_FUNCTION_ARITY_MAX, \
181 BOOST_LOCAL_FUNCTION_AUX_FUNCTION_THIS_FILE_))
182# include BOOST_PP_ITERATE() // Iterate over function arity.
183
184} } } // namespace
185
186// Register type for type-of emu (NAME use TYPEOF to deduce this fctor type).
187#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
188BOOST_TYPEOF_REGISTER_TEMPLATE(boost::local_function::aux::function,
189 (typename) // For `F` tparam.
190 (size_t) // For `defaults` tparam.
191 // MSVC error if using #if instead of PP_IIF here.
192 BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS,
193 BOOST_PP_TUPLE_EAT(3) // Nothing.
194 ,
195 BOOST_PP_REPEAT // For bind tparams.
196 )(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX,
197 BOOST_LOCAL_FUNCTION_AUX_typename_seq, ~)
198)
199
200#undef BOOST_LOCAL_FUNCTION_AUX_typename_seq
201#undef BOOST_LOCAL_FUNCTION_AUX_arg_type
202#undef BOOST_LOCAL_FUNCTION_AUX_arg_typedef
203#undef BOOST_LOCAL_FUNCTION_AUX_comma_arg_tparam
204#undef BOOST_LOCAL_FUNCTION_AUX_arg_param_type
205#undef BOOST_LOCAL_FUNCTION_AUX_arg_name
206#undef BOOST_LOCAL_FUNCTION_AUX_arg_param_decl
207#undef BOOST_LOCAL_FUNCTION_AUX_bind_type
208#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_type
209#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_ref
210#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam
211#undef BOOST_LOCAL_FUNCTION_AUX_bind_name
212#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_param_decl
213#undef BOOST_LOCAL_FUNCTION_AUX_bind_member
214#undef BOOST_LOCAL_FUNCTION_AUX_comma_bind_member_deref
215#undef BOOST_LOCAL_FUNCTION_AUX_bind_member_init
216#undef BOOST_LOCAL_FUNCTION_AUX_bind_member_decl
217#undef BOOST_LOCAL_FUNCTION_AUX_call_ptr
218#undef BOOST_LOCAL_FUNCTION_AUX_call_name
219#undef BOOST_LOCAL_FUNCTION_AUX_call_member
220#undef BOOST_LOCAL_FUNCTION_AUX_call_typedef
221#undef BOOST_LOCAL_FUNCTION_AUX_comma_call_param_decl
222#undef BOOST_LOCAL_FUNCTION_AUX_call_decl
223#undef BOOST_LOCAL_FUNCTION_AUX_call_init
224#undef BOOST_LOCAL_FUNCTION_AUX_operator_call
225
226# endif // #include guard
227
228#elif BOOST_PP_ITERATION_DEPTH() == 1
229# define BOOST_LOCAL_FUNCTION_AUX_arity BOOST_PP_FRAME_ITERATION(1)
230# define BOOST_PP_ITERATION_PARAMS_2 \
231 (3, (0, BOOST_LOCAL_FUNCTION_AUX_arity, \
232 BOOST_LOCAL_FUNCTION_AUX_FUNCTION_THIS_FILE_))
233# include BOOST_PP_ITERATE() // Iterate over default params count.
234# undef BOOST_LOCAL_FUNCTION_AUX_arity
235
236#elif BOOST_PP_ITERATION_DEPTH() == 2
237# define BOOST_LOCAL_FUNCTION_AUX_defaults BOOST_PP_FRAME_ITERATION(2)
238
239template<
240 typename R
241 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_AUX_arity,
242 BOOST_LOCAL_FUNCTION_AUX_comma_arg_tparam, ~)
243#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS
244 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX,
245 BOOST_LOCAL_FUNCTION_AUX_comma_bind_tparam, ~)
246#endif
247>
248class function<
249 R (
250 BOOST_PP_ENUM(BOOST_LOCAL_FUNCTION_AUX_arity,
251 BOOST_LOCAL_FUNCTION_AUX_arg_type, ~)
252 )
253 , BOOST_LOCAL_FUNCTION_AUX_defaults
254#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS
255 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX,
256 BOOST_LOCAL_FUNCTION_AUX_comma_bind_type, ~)
257#endif
258> {
259 // The object type will actually be a local class which cannot be passed as
260 // a template parameter so a generic `void*` pointer is used to hold the
261 // object (this pointer will then be cased by the call-function implemented
262 // by the local class itself). This is the trick used to pass a local
263 // function as a template parameter. This trick uses function pointers for
264 // the call-functions and function pointers cannot always be optimized by
265 // the compiler (they cannot be inlined) thus this trick increased run-time
266 // (another trick using virtual functions for the local class was also
267 // investigated but also virtual functions cannot be inlined plus they
268 // require virtual tables lookups so the virtual functions trick measured
269 // worst run-time performance than the function pointer trick).
270 typedef void* object_ptr;
271 BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults),
272 BOOST_LOCAL_FUNCTION_AUX_call_typedef, // INC for no defaults.
273 BOOST_LOCAL_FUNCTION_AUX_arity)
274
275public:
276 // Provide public type interface following Boost.Function names
277 // (traits must be defined in both this and the local functor).
278 BOOST_STATIC_CONSTANT(size_t, arity = BOOST_LOCAL_FUNCTION_AUX_arity);
279 typedef R result_type;
280 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_AUX_arity,
281 BOOST_LOCAL_FUNCTION_AUX_arg_typedef, ~)
282
283 // NOTE: Must have default constructor for init without function name in
284 // function macro expansion.
285
286 // Cannot be private but it should never be used by programmers directly
287 // so used internal symbol.
288 inline void BOOST_LOCAL_FUNCTION_AUX_FUNCTION_INIT_CALL_FUNC(
289 object_ptr object
290#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS
291 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX,
292 BOOST_LOCAL_FUNCTION_AUX_comma_bind_param_decl, ~)
293#endif
294 BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults),
295 BOOST_LOCAL_FUNCTION_AUX_comma_call_param_decl, ~)
296 ) {
297 object_ = object;
298#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS
299 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX,
300 BOOST_LOCAL_FUNCTION_AUX_bind_member_init, ~)
301#endif
302 BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults),
303 BOOST_LOCAL_FUNCTION_AUX_call_init, ~) // INC for no defaults.
304 unused_ = 0; // To avoid a GCC uninitialized warning.
305 }
306
307 // Result operator(Arg1, ..., ArgN-1, ArgN) -- iff defaults >= 0
308 // Result operator(Arg1, ..., ArgN-1) -- iff defaults >= 1
309 // ... -- etc
310 BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults),
311 BOOST_LOCAL_FUNCTION_AUX_operator_call, // INC for no defaults.
312 BOOST_LOCAL_FUNCTION_AUX_arity)
313
314private:
315 object_ptr object_;
316#if !BOOST_LOCAL_FUNCTION_CONFIG_LOCALS_AS_TPARAMS
317 BOOST_PP_REPEAT(BOOST_LOCAL_FUNCTION_CONFIG_BIND_MAX,
318 BOOST_LOCAL_FUNCTION_AUX_bind_member_decl, ~)
319#endif
320 BOOST_PP_REPEAT(BOOST_PP_INC(BOOST_LOCAL_FUNCTION_AUX_defaults),
321 BOOST_LOCAL_FUNCTION_AUX_call_decl, ~) // INC for no defaults.
322
323 // run-time: this unused void* member variable allows for compiler
324 // optimizations (at least on MSVC it reduces invocation time of about 50%)
325 void* unused_;
326};
327
328# undef BOOST_LOCAL_FUNCTION_AUX_defaults
329#endif // iteration
330