]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/functional/include/boost/functional/forward_adapter.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / functional / include / boost / functional / forward_adapter.hpp
1 /*=============================================================================
2 Copyright (c) 2007-2008 Tobias Schwinger
3
4 Use modification and distribution are subject to the Boost Software
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7 ==============================================================================*/
8
9 #ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
10 # ifndef BOOST_PP_IS_ITERATING
11
12 # include <boost/config.hpp>
13 # include <boost/detail/workaround.hpp>
14
15 # include <boost/preprocessor/iteration/iterate.hpp>
16 # include <boost/preprocessor/repetition/enum_params.hpp>
17 # include <boost/preprocessor/repetition/enum_binary_params.hpp>
18 # include <boost/preprocessor/facilities/intercept.hpp>
19 # include <boost/preprocessor/arithmetic/dec.hpp>
20
21 # include <boost/utility/result_of.hpp>
22
23 # ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
24 # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 6
25 # elif BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY < 3
26 # undef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
27 # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 3
28 # endif
29
30
31 namespace boost
32 {
33 template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
34 class forward_adapter;
35
36 //----- ---- --- -- - - - -
37
38 namespace detail
39 {
40 template< class MostDerived, typename Function, typename FunctionConst,
41 int Arity, int MinArity >
42 struct forward_adapter_impl;
43
44 struct forward_adapter_result
45 {
46 template< typename Sig > struct apply;
47
48 // Utility metafunction for qualification adjustment on arguments
49 template< typename T > struct q { typedef T const t; };
50 template< typename T > struct q<T const> { typedef T const t; };
51 template< typename T > struct q<T &> { typedef T t; };
52
53 // Utility metafunction to choose target function qualification
54 template< typename T > struct c
55 { typedef typename T::target_function_t t; };
56 template< typename T > struct c<T& >
57 { typedef typename T::target_function_t t; };
58 template< typename T > struct c<T const >
59 { typedef typename T::target_function_const_t t; };
60 template< typename T > struct c<T const&>
61 { typedef typename T::target_function_const_t t; };
62 };
63 }
64
65 # define BOOST_TMP_MACRO(f,fn,fc) \
66 boost::detail::forward_adapter_impl< \
67 forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
68 (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
69 :BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY), \
70 (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
71
72 template< typename Function, int Arity_Or_MinArity, int MaxArity >
73 class forward_adapter
74 : public BOOST_TMP_MACRO(Function,Function,Function const)
75 , private Function
76 {
77 public:
78 forward_adapter(Function const& f = Function())
79 : Function(f)
80 { }
81
82 typedef Function target_function_t;
83 typedef Function const target_function_const_t;
84
85 Function & target_function() { return *this; }
86 Function const & target_function() const { return *this; }
87
88 template< typename Sig > struct result
89 : detail::forward_adapter_result::template apply<Sig>
90 { };
91
92 using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
93 };
94 template< typename Function, int Arity_Or_MinArity, int MaxArity >
95 class forward_adapter< Function const, Arity_Or_MinArity, MaxArity >
96 : public BOOST_TMP_MACRO(Function const, Function const, Function const)
97 , private Function
98 {
99 public:
100 forward_adapter(Function const& f = Function())
101 : Function(f)
102 { }
103
104 typedef Function const target_function_t;
105 typedef Function const target_function_const_t;
106
107 Function const & target_function() const { return *this; }
108
109 template< typename Sig > struct result
110 : detail::forward_adapter_result::template apply<Sig>
111 { };
112
113 using BOOST_TMP_MACRO(Function const,Function const, Function const)
114 ::operator();
115 };
116 template< typename Function, int Arity_Or_MinArity, int MaxArity >
117 class forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
118 : public BOOST_TMP_MACRO(Function&, Function, Function)
119 {
120 Function& ref_function;
121 public:
122 forward_adapter(Function& f)
123 : ref_function(f)
124 { }
125
126 typedef Function target_function_t;
127 typedef Function target_function_const_t;
128
129 Function & target_function() const { return this->ref_function; }
130
131 template< typename Sig > struct result
132 : detail::forward_adapter_result::template apply<Sig>
133 { };
134
135 using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
136 };
137
138 #undef BOOST_TMP_MACRO
139
140 namespace detail
141 {
142 template< class Self >
143 struct forward_adapter_result::apply< Self() >
144 : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
145 { };
146
147 // WHen operator()() doesn't have any parameters, it can't
148 // be templatized and can't use SFINAE, so intead use class
149 // template parameter SFINAE to decide whether to instantiate it.
150
151 template <typename T, typename R = void>
152 struct forward_adapter_sfinae
153 {
154 typedef T type;
155 };
156
157 // This is the fallback for when there isn't an operator()(),
158 // need to create an operator() that will never instantiate
159 // so that using parent::operator() will work okay.
160 template< class MD, class F, class FC, class Enable = void>
161 struct forward_adapter_impl_zero
162 {
163 template <typename T> struct never_instantiate {};
164 template <typename T>
165 typename never_instantiate<T>::type operator()(T) const {}
166 };
167
168 template< class MD, class F, class FC>
169 struct forward_adapter_impl_zero<MD, F, FC,
170 typename forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
171 {
172 inline typename boost::result_of< FC() >::type
173 operator()() const
174 {
175 return static_cast<MD const*>(this)->target_function()();
176 }
177
178 inline typename boost::result_of< F() >::type
179 operator()()
180 {
181 return static_cast<MD*>(this)->target_function()();
182 }
183 };
184
185 template< class MD, class F, class FC >
186 struct forward_adapter_impl<MD,F,FC,0,0>
187 : forward_adapter_impl_zero<MD,F,FC>
188 {
189 using forward_adapter_impl_zero<MD,F,FC>::operator();
190
191 // closing brace gets generated by preprocessing code, below
192
193 # define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \
194 template< tpl_params > \
195 inline typename boost::result_of< FC(arg_types) >::type \
196 operator()(params) const \
197 { \
198 return static_cast<MD const*>(this)->target_function()(args); \
199 } \
200 template< tpl_params > \
201 inline typename boost::result_of< F(arg_types)>::type \
202 operator()(params) \
203 { \
204 return static_cast<MD*>(this)->target_function()(args); \
205 }
206
207 # // This is the total number of iterations we need
208 # define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2)
209
210 # // Chain file iteration to virtually one loop
211 # if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 7
212 # define limit1 count
213 # define limit2 0
214 # define limit3 0
215 # else
216 # if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 15
217 # define limit1 (count >> 8)
218 # define limit2 255
219 # define limit3 0
220 # else
221 # define limit1 (count >> 16)
222 # define limit2 255
223 # define limit3 255
224 # endif
225 # endif
226
227 # define N 0
228
229 # define BOOST_PP_FILENAME_1 <boost/functional/forward_adapter.hpp>
230 # define BOOST_PP_ITERATION_LIMITS (0,limit1)
231 # include BOOST_PP_ITERATE()
232
233 # undef N
234 # undef limit3
235 # undef limit2
236 # undef limit1
237 # undef count
238 # undef BOOST_TMP_MACRO
239
240 };
241
242 } // namespace detail
243
244 template<class F, int A0, int A1>
245 struct result_of<boost::forward_adapter<F,A0,A1> const ()>
246 : boost::detail::forward_adapter_result::template apply<
247 boost::forward_adapter<F,A0,A1> const () >
248 { };
249 template<class F, int A0, int A1>
250 struct result_of<boost::forward_adapter<F,A0,A1>()>
251 : boost::detail::forward_adapter_result::template apply<
252 boost::forward_adapter<F,A0,A1>() >
253 { };
254 template<class F, int A0, int A1>
255 struct result_of<boost::forward_adapter<F,A0,A1> const& ()>
256 : boost::detail::forward_adapter_result::template apply<
257 boost::forward_adapter<F,A0,A1> const () >
258 { };
259 template<class F, int A0, int A1>
260 struct result_of<boost::forward_adapter<F,A0,A1>& ()>
261 : boost::detail::forward_adapter_result::template apply<
262 boost::forward_adapter<F,A0,A1>() >
263 { };
264 }
265
266 # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
267
268 # elif BOOST_PP_ITERATION_DEPTH() == 1 && limit2
269 # define BOOST_PP_FILENAME_2 <boost/functional/forward_adapter.hpp>
270 # define BOOST_PP_ITERATION_LIMITS (0,limit2)
271 # include BOOST_PP_ITERATE()
272 # elif BOOST_PP_ITERATION_DEPTH() == 2 && limit3
273 # define BOOST_PP_FILENAME_3 <boost/functional/forward_adapter.hpp>
274 # define BOOST_PP_ITERATION_LIMITS (0,limit3)
275 # include BOOST_PP_ITERATE()
276
277 # else
278
279 # // I is the loop counter
280 # if limit2 && limit3
281 # define I (BOOST_PP_ITERATION_1 << 16 | BOOST_PP_ITERATION_2 << 8 | \
282 BOOST_PP_ITERATION_3)
283 # elif limit2
284 # define I (BOOST_PP_ITERATION_1 << 8 | BOOST_PP_ITERATION_2)
285 # else
286 # define I BOOST_PP_ITERATION_1
287 # endif
288
289 # if I < count
290
291 # // Done for this arity? Increment N
292 # if (I+2 >> N+1)
293 # if N == 0
294 # undef N
295 # define N 1
296 # elif N == 1
297 # undef N
298 # define N 2
299 # elif N == 2
300 # undef N
301 # define N 3
302 # elif N == 3
303 # undef N
304 # define N 4
305 # elif N == 4
306 # undef N
307 # define N 5
308 # elif N == 5
309 # undef N
310 # define N 6
311 # elif N == 6
312 # undef N
313 # define N 7
314 # elif N == 7
315 # undef N
316 # define N 8
317 # elif N == 8
318 # undef N
319 # define N 9
320 # elif N == 9
321 # undef N
322 # define N 10
323 # elif N == 10
324 # undef N
325 # define N 11
326 # elif N == 11
327 # undef N
328 # define N 12
329 # elif N == 12
330 # undef N
331 # define N 13
332 # elif N == 13
333 # undef N
334 # define N 14
335 # elif N == 14
336 # undef N
337 # define N 15
338 # elif N == 15
339 # undef N
340 # define N 16
341 # endif
342
343 };
344
345 template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
346 struct forward_adapter_result::apply< Self(BOOST_PP_ENUM_PARAMS(N,T)) >
347 : boost::result_of<
348 BOOST_DEDUCED_TYPENAME c<Self>::t(BOOST_PP_ENUM_BINARY_PARAMS(N,
349 typename q<T,>::t& BOOST_PP_INTERCEPT)) >
350 { };
351
352 template< class MD, class F, class FC >
353 struct forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
354 {
355 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
356 inline typename boost::result_of< F(
357 BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type
358 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
359 };
360
361 template< class MD, class F, class FC, int MinArity >
362 struct forward_adapter_impl<MD,F,FC,N,MinArity>
363 : forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
364 {
365 using forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>::operator();
366
367 # endif
368
369 # // Zero based count for each arity would be I-(1<<N)+2, but we don't
370 # // need it, unless we need a nicer order.
371
372 # // Macros for the parameter's type modifiers.
373 # if I & 0x000001
374 # define PT0 T0 &
375 # else
376 # define PT0 T0 const &
377 # endif
378 # if I & 0x000002
379 # define PT1 T1 &
380 # else
381 # define PT1 T1 const &
382 # endif
383 # if I & 0x000004
384 # define PT2 T2 &
385 # else
386 # define PT2 T2 const &
387 # endif
388 # if I & 0x000008
389 # define PT3 T3 &
390 # else
391 # define PT3 T3 const &
392 # endif
393 # if I & 0x000010
394 # define PT4 T4 &
395 # else
396 # define PT4 T4 const &
397 # endif
398 # if I & 0x000020
399 # define PT5 T5 &
400 # else
401 # define PT5 T5 const &
402 # endif
403 # if I & 0x000040
404 # define PT6 T6 &
405 # else
406 # define PT6 T6 const &
407 # endif
408 # if I & 0x000080
409 # define PT7 T7 &
410 # else
411 # define PT7 T7 const &
412 # endif
413 # if I & 0x000100
414 # define PT8 T8 &
415 # else
416 # define PT8 T8 const &
417 # endif
418 # if I & 0x000200
419 # define PT9 T9 &
420 # else
421 # define PT9 T9 const &
422 # endif
423 # if I & 0x000400
424 # define PT10 T10 &
425 # else
426 # define PT10 T10 const &
427 # endif
428 # if I & 0x000800
429 # define PT11 T11 &
430 # else
431 # define PT11 T11 const &
432 # endif
433 # if I & 0x001000
434 # define PT12 T12 &
435 # else
436 # define PT12 T12 const &
437 # endif
438 # if I & 0x002000
439 # define PT13 T13 &
440 # else
441 # define PT13 T13 const &
442 # endif
443 # if I & 0x004000
444 # define PT14 T14 &
445 # else
446 # define PT14 T14 const &
447 # endif
448 # if I & 0x008000
449 # define PT15 T15 &
450 # else
451 # define PT15 T15 const &
452 # endif
453
454 # if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
455 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
456 inline typename boost::result_of< FC(BOOST_PP_ENUM_PARAMS(N,PT))
457 >::type
458 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const
459 {
460 return static_cast<MD const* const>(this)
461 ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
462 }
463 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
464 inline typename boost::result_of< F(BOOST_PP_ENUM_PARAMS(N,PT))
465 >::type
466 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a))
467 {
468 return static_cast<MD* const>(this)
469 ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
470 }
471 # else
472 BOOST_TMP_MACRO(BOOST_PP_ENUM_PARAMS(N,typename T),
473 BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a),
474 BOOST_PP_ENUM_PARAMS(N,a) )
475 // ...generates uglier code but is faster - it caches ENUM_*
476 # endif
477
478 # undef PT0
479 # undef PT1
480 # undef PT2
481 # undef PT3
482 # undef PT4
483 # undef PT5
484 # undef PT6
485 # undef PT7
486 # undef PT8
487 # undef PT9
488 # undef PT10
489 # undef PT11
490 # undef PT12
491 # undef PT13
492 # undef PT14
493 # undef PT15
494
495 # endif // I < count
496
497 # undef I
498 # endif // defined(BOOST_PP_IS_ITERATING)
499
500 #endif // include guard
501