]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/functional/include/boost/functional/forward_adapter.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / functional / include / boost / functional / forward_adapter.hpp
CommitLineData
7c673cae
FG
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
31namespace 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