fix doc example typo
[boost.git] / boost / functional / forward_adapter.hpp
blob0a4bc362566859e2de4f3b449aa34efc384ce6ba
1 /*=============================================================================
2 Copyright (c) 2007-2008 Tobias Schwinger
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 ==============================================================================*/
9 #ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
10 # ifndef BOOST_PP_IS_ITERATING
12 # include <boost/config.hpp>
13 # include <boost/detail/workaround.hpp>
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>
21 # include <boost/utility/result_of.hpp>
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
31 namespace boost
33 template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
34 class forward_adapter;
36 //----- ---- --- -- - - - -
38 namespace detail
40 template< class MostDerived, typename Function, typename FunctionConst,
41 int Arity, int MinArity >
42 struct forward_adapter_impl;
44 struct forward_adapter_result
46 template< typename Sig > struct apply;
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; };
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; };
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) >
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
77 public:
78 forward_adapter(Function const& f = Function())
79 : Function(f)
80 { }
82 typedef Function target_function_t;
83 typedef Function const target_function_const_t;
85 Function & target_function() { return *this; }
86 Function const & target_function() const { return *this; }
88 template< typename Sig > struct result
89 : detail::forward_adapter_result::template apply<Sig>
90 { };
92 using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
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
99 public:
100 forward_adapter(Function const& f = Function())
101 : Function(f)
104 typedef Function const target_function_t;
105 typedef Function const target_function_const_t;
107 Function const & target_function() const { return *this; }
109 template< typename Sig > struct result
110 : detail::forward_adapter_result::template apply<Sig>
111 { };
113 using BOOST_TMP_MACRO(Function const,Function const, Function const)
114 ::operator();
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)
120 Function& ref_function;
121 public:
122 forward_adapter(Function& f)
123 : ref_function(f)
126 typedef Function target_function_t;
127 typedef Function target_function_const_t;
129 Function & target_function() const { return this->ref_function; }
131 template< typename Sig > struct result
132 : detail::forward_adapter_result::template apply<Sig>
133 { };
135 using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
138 #undef BOOST_TMP_MACRO
140 namespace detail
142 template< class Self >
143 struct forward_adapter_result::apply< Self() >
144 : boost::result_of< typename c<Self>::t() >
145 { };
147 template< class MD, class F, class FC >
148 struct forward_adapter_impl<MD,F,FC,0,0>
150 inline typename boost::result_of< FC() >::type
151 operator()() const
153 return static_cast<MD const*>(this)->target_function()();
156 inline typename boost::result_of< F() >::type
157 operator()()
159 return static_cast<MD*>(this)->target_function()();
162 // closing brace gets generated by preprocessing code, below
164 # define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \
165 template< tpl_params > \
166 inline typename boost::result_of< FC(arg_types) >::type \
167 operator()(params) const \
169 return static_cast<MD const*>(this)->target_function()(args); \
171 template< tpl_params > \
172 inline typename boost::result_of< F(arg_types)>::type \
173 operator()(params) \
175 return static_cast<MD*>(this)->target_function()(args); \
178 # // This is the total number of iterations we need
179 # define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2)
181 # // Chain file iteration to virtually one loop
182 # if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 7
183 # define limit1 count
184 # define limit2 0
185 # define limit3 0
186 # else
187 # if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 15
188 # define limit1 (count >> 8)
189 # define limit2 255
190 # define limit3 0
191 # else
192 # define limit1 (count >> 16)
193 # define limit2 255
194 # define limit3 255
195 # endif
196 # endif
198 # define N 0
200 # define BOOST_PP_FILENAME_1 <boost/functional/forward_adapter.hpp>
201 # define BOOST_PP_ITERATION_LIMITS (0,limit1)
202 # include BOOST_PP_ITERATE()
204 # undef N
205 # undef limit3
206 # undef limit2
207 # undef limit1
208 # undef count
209 # undef BOOST_TMP_MACRO
213 } // namespace detail
215 template<class F, int A0, int A1>
216 struct result_of<boost::forward_adapter<F,A0,A1> const ()>
217 : boost::detail::forward_adapter_result::template apply<
218 boost::forward_adapter<F,A0,A1> const () >
219 { };
220 template<class F, int A0, int A1>
221 struct result_of<boost::forward_adapter<F,A0,A1>()>
222 : boost::detail::forward_adapter_result::template apply<
223 boost::forward_adapter<F,A0,A1>() >
224 { };
225 template<class F, int A0, int A1>
226 struct result_of<boost::forward_adapter<F,A0,A1> const& ()>
227 : boost::detail::forward_adapter_result::template apply<
228 boost::forward_adapter<F,A0,A1> const () >
229 { };
230 template<class F, int A0, int A1>
231 struct result_of<boost::forward_adapter<F,A0,A1>& ()>
232 : boost::detail::forward_adapter_result::template apply<
233 boost::forward_adapter<F,A0,A1>() >
234 { };
237 # define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
239 # elif BOOST_PP_ITERATION_DEPTH() == 1 && limit2
240 # define BOOST_PP_FILENAME_2 <boost/functional/forward_adapter.hpp>
241 # define BOOST_PP_ITERATION_LIMITS (0,limit2)
242 # include BOOST_PP_ITERATE()
243 # elif BOOST_PP_ITERATION_DEPTH() == 2 && limit3
244 # define BOOST_PP_FILENAME_3 <boost/functional/forward_adapter.hpp>
245 # define BOOST_PP_ITERATION_LIMITS (0,limit3)
246 # include BOOST_PP_ITERATE()
248 # else
250 # // I is the loop counter
251 # if limit2 && limit3
252 # define I (BOOST_PP_ITERATION_1 << 16 | BOOST_PP_ITERATION_2 << 8 | \
253 BOOST_PP_ITERATION_3)
254 # elif limit2
255 # define I (BOOST_PP_ITERATION_1 << 8 | BOOST_PP_ITERATION_2)
256 # else
257 # define I BOOST_PP_ITERATION_1
258 # endif
260 # if I < count
262 # // Done for this arity? Increment N
263 # if (I+2 >> N+1)
264 # if N == 0
265 # undef N
266 # define N 1
267 # elif N == 1
268 # undef N
269 # define N 2
270 # elif N == 2
271 # undef N
272 # define N 3
273 # elif N == 3
274 # undef N
275 # define N 4
276 # elif N == 4
277 # undef N
278 # define N 5
279 # elif N == 5
280 # undef N
281 # define N 6
282 # elif N == 6
283 # undef N
284 # define N 7
285 # elif N == 7
286 # undef N
287 # define N 8
288 # elif N == 8
289 # undef N
290 # define N 9
291 # elif N == 9
292 # undef N
293 # define N 10
294 # elif N == 10
295 # undef N
296 # define N 11
297 # elif N == 11
298 # undef N
299 # define N 12
300 # elif N == 12
301 # undef N
302 # define N 13
303 # elif N == 13
304 # undef N
305 # define N 14
306 # elif N == 14
307 # undef N
308 # define N 15
309 # elif N == 15
310 # undef N
311 # define N 16
312 # endif
316 template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
317 struct forward_adapter_result::apply< Self(BOOST_PP_ENUM_PARAMS(N,T)) >
318 : boost::result_of<
319 typename c<Self>::t(BOOST_PP_ENUM_BINARY_PARAMS(N,
320 typename q<T,>::t& BOOST_PP_INTERCEPT)) >
321 { };
323 template< class MD, class F, class FC >
324 struct forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
326 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
327 inline typename boost::result_of< F(
328 BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type
329 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
332 template< class MD, class F, class FC, int MinArity >
333 struct forward_adapter_impl<MD,F,FC,N,MinArity>
334 : forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
336 using forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>::operator();
338 # endif
340 # // Zero based count for each arity would be I-(1<<N)+2, but we don't
341 # // need it, unless we need a nicer order.
343 # // Macros for the parameter's type modifiers.
344 # if I & 0x000001
345 # define PT0 T0 &
346 # else
347 # define PT0 T0 const &
348 # endif
349 # if I & 0x000002
350 # define PT1 T1 &
351 # else
352 # define PT1 T1 const &
353 # endif
354 # if I & 0x000004
355 # define PT2 T2 &
356 # else
357 # define PT2 T2 const &
358 # endif
359 # if I & 0x000008
360 # define PT3 T3 &
361 # else
362 # define PT3 T3 const &
363 # endif
364 # if I & 0x000010
365 # define PT4 T4 &
366 # else
367 # define PT4 T4 const &
368 # endif
369 # if I & 0x000020
370 # define PT5 T5 &
371 # else
372 # define PT5 T5 const &
373 # endif
374 # if I & 0x000040
375 # define PT6 T6 &
376 # else
377 # define PT6 T6 const &
378 # endif
379 # if I & 0x000080
380 # define PT7 T7 &
381 # else
382 # define PT7 T7 const &
383 # endif
384 # if I & 0x000100
385 # define PT8 T8 &
386 # else
387 # define PT8 T8 const &
388 # endif
389 # if I & 0x000200
390 # define PT9 T9 &
391 # else
392 # define PT9 T9 const &
393 # endif
394 # if I & 0x000400
395 # define PT10 T10 &
396 # else
397 # define PT10 T10 const &
398 # endif
399 # if I & 0x000800
400 # define PT11 T11 &
401 # else
402 # define PT11 T11 const &
403 # endif
404 # if I & 0x001000
405 # define PT12 T12 &
406 # else
407 # define PT12 T12 const &
408 # endif
409 # if I & 0x002000
410 # define PT13 T13 &
411 # else
412 # define PT13 T13 const &
413 # endif
414 # if I & 0x004000
415 # define PT14 T14 &
416 # else
417 # define PT14 T14 const &
418 # endif
419 # if I & 0x008000
420 # define PT15 T15 &
421 # else
422 # define PT15 T15 const &
423 # endif
425 # if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
426 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
427 inline typename boost::result_of< FC(BOOST_PP_ENUM_PARAMS(N,PT))
428 >::type
429 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const
431 return static_cast<MD const* const>(this)
432 ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
434 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
435 inline typename boost::result_of< F(BOOST_PP_ENUM_PARAMS(N,PT))
436 >::type
437 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a))
439 return static_cast<MD* const>(this)
440 ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
442 # else
443 BOOST_TMP_MACRO(BOOST_PP_ENUM_PARAMS(N,typename T),
444 BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a),
445 BOOST_PP_ENUM_PARAMS(N,a) )
446 // ...generates uglier code but is faster - it caches ENUM_*
447 # endif
449 # undef PT0
450 # undef PT1
451 # undef PT2
452 # undef PT3
453 # undef PT4
454 # undef PT5
455 # undef PT6
456 # undef PT7
457 # undef PT8
458 # undef PT9
459 # undef PT10
460 # undef PT11
461 # undef PT12
462 # undef PT13
463 # undef PT14
464 # undef PT15
466 # endif // I < count
468 # undef I
469 # endif // defined(BOOST_PP_IS_ITERATING)
471 #endif // include guard