source: XIOS/dev/dev_olga/src/extern/boost/include/boost/functional/forward_adapter.hpp @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 14.8 KB
Line 
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< typename c<Self>::t() >
145        { };
146
147        template< class MD, class F, class FC >
148        struct forward_adapter_impl<MD,F,FC,0,0>
149        {
150            inline typename boost::result_of< FC() >::type
151            operator()() const
152            {
153                return static_cast<MD const*>(this)->target_function()();
154            }
155
156            inline typename boost::result_of< F() >::type
157            operator()()
158            {
159                return static_cast<MD*>(this)->target_function()();
160            }
161
162        // closing brace gets generated by preprocessing code, below
163
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                                           \
168            {                                                                  \
169                return static_cast<MD const*>(this)->target_function()(args);  \
170            }                                                                  \
171            template< tpl_params >                                             \
172            inline typename boost::result_of< F(arg_types)>::type              \
173            operator()(params)                                                 \
174            {                                                                  \
175                return static_cast<MD*>(this)->target_function()(args);        \
176            }
177
178#       // This is the total number of iterations we need
179#       define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2)
180
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
197
198#       define N 0
199
200#       define  BOOST_PP_FILENAME_1 <boost/functional/forward_adapter.hpp>
201#       define  BOOST_PP_ITERATION_LIMITS (0,limit1)
202#       include BOOST_PP_ITERATE()
203
204#       undef N
205#       undef limit3
206#       undef limit2
207#       undef limit1
208#       undef count
209#       undef BOOST_TMP_MACRO
210
211        };
212
213    } // namespace detail
214
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    { };
235}
236
237#       define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
238
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()
247
248#   else
249
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
259
260#     if I < count
261
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
313
314        };
315
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        { };
322
323        template< class MD, class F, class FC >
324        struct forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
325        {
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));
330        };
331
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>
335        {
336            using forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>::operator();
337
338#       endif
339
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.
342
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
424
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
430            {
431                return static_cast<MD const* const>(this)
432                    ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
433            }
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))
438            {
439                return static_cast<MD* const>(this)
440                    ->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
441            }
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
448
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
465
466#     endif // I < count
467
468#     undef I
469#   endif // defined(BOOST_PP_IS_ITERATING)
470
471#endif // include guard
472
Note: See TracBrowser for help on using the repository browser.