1 /*=============================================================================
2 Copyright (c) 2007 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_LIGHTWEIGHT_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/cat.hpp>
16 # include <boost/preprocessor/iteration/iterate.hpp>
17 # include <boost/preprocessor/repetition/enum.hpp>
18 # include <boost/preprocessor/repetition/enum_params.hpp>
19 # include <boost/preprocessor/repetition/enum_binary_params.hpp>
20 # include <boost/preprocessor/facilities/intercept.hpp>
22 # include <boost/utility/result_of.hpp>
23 # include <boost/ref.hpp>
25 # ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
26 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10
27 # elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3
28 # undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
29 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3
34 template< typename Function
, int Arity_Or_MinArity
= -1, int MaxArity
= -1 >
35 class lightweight_forward_adapter
;
37 //----- ---- --- -- - - - -
41 template< class MostDerived
, typename Function
, typename FunctionConst
,
42 int Arity
, int MinArity
>
43 struct lightweight_forward_adapter_impl
;
45 struct lightweight_forward_adapter_result
47 template< typename Sig
> struct apply
;
49 // Utility metafunction for argument transform
50 template< typename T
> struct x
{ typedef T
const& t
; };
51 template< typename T
> struct x
< boost::reference_wrapper
<T
> >
53 template< typename T
> struct x
<T
&> : x
<T
> { };
54 template< typename T
> struct x
<T
const&> : x
<T
> { };
55 template< typename T
> struct x
<T
const> : x
<T
> { };
57 // Utility metafunction to choose target function qualification
58 template< typename T
> struct c
59 { typedef typename
T::target_function_t t
; };
60 template< typename T
> struct c
<T
& >
61 { typedef typename
T::target_function_t t
; };
62 template< typename T
> struct c
<T
const >
63 { typedef typename
T::target_function_const_t t
; };
64 template< typename T
> struct c
<T
const&>
65 { typedef typename
T::target_function_const_t t
; };
69 # define BOOST_TMP_MACRO(f,fn,fc) \
70 boost::detail::lightweight_forward_adapter_impl< \
71 lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
72 (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
73 :BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \
74 (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
76 template< typename Function
, int Arity_Or_MinArity
, int MaxArity
>
77 class lightweight_forward_adapter
78 : public BOOST_TMP_MACRO(Function
,Function
,Function
const)
82 lightweight_forward_adapter(Function
const& f
= Function())
86 typedef Function target_function_t
;
87 typedef Function
const target_function_const_t
;
89 Function
& target_function() { return *this; }
90 Function
const & target_function() const { return *this; }
92 template< typename Sig
> struct result
93 : detail::lightweight_forward_adapter_result::template apply
<Sig
>
96 using BOOST_TMP_MACRO(Function
,Function
, Function
const)::operator();
98 template< typename Function
, int Arity_Or_MinArity
, int MaxArity
>
99 class lightweight_forward_adapter
< Function
const, Arity_Or_MinArity
,
101 : public BOOST_TMP_MACRO(Function
const, Function
const, Function
const)
105 lightweight_forward_adapter(Function
const& f
= Function())
109 typedef Function
const target_function_t
;
110 typedef Function
const target_function_const_t
;
112 Function
const & target_function() const { return *this; }
114 template< typename Sig
> struct result
115 : detail::lightweight_forward_adapter_result::template apply
<Sig
>
118 using BOOST_TMP_MACRO(Function
const,Function
const, Function
const)
121 template< typename Function
, int Arity_Or_MinArity
, int MaxArity
>
122 class lightweight_forward_adapter
< Function
&, Arity_Or_MinArity
, MaxArity
>
123 : public BOOST_TMP_MACRO(Function
&, Function
, Function
)
125 Function
& ref_function
;
127 lightweight_forward_adapter(Function
& f
)
131 typedef Function target_function_t
;
132 typedef Function target_function_const_t
;
134 Function
& target_function() const { return this->ref_function
; }
136 template< typename Sig
> struct result
137 : detail::lightweight_forward_adapter_result::template apply
<Sig
>
140 using BOOST_TMP_MACRO(Function
&, Function
, Function
)::operator();
143 #undef BOOST_TMP_MACRO
147 template< class Self
>
148 struct lightweight_forward_adapter_result::apply
< Self() >
149 : boost::result_of
< BOOST_DEDUCED_TYPENAME c
<Self
>::t() >
152 template< class MD
, class F
, class FC
>
153 struct lightweight_forward_adapter_impl
<MD
,F
,FC
,0,0>
154 : lightweight_forward_adapter_result
156 inline typename
boost::result_of
< FC() >::type
159 return static_cast<MD
const*>(this)->target_function()();
162 inline typename
boost::result_of
< F() >::type
165 return static_cast<MD
*>(this)->target_function()();
169 # define BOOST_PP_FILENAME_1 \
170 <boost/functional/lightweight_forward_adapter.hpp>
171 # define BOOST_PP_ITERATION_LIMITS \
172 (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY)
173 # include BOOST_PP_ITERATE()
175 } // namespace detail
177 template<class F
, int A0
, int A1
>
178 struct result_of
<boost::lightweight_forward_adapter
<F
,A0
,A1
> const ()>
179 : boost::detail::lightweight_forward_adapter_result::template apply
<
180 boost::lightweight_forward_adapter
<F
,A0
,A1
> const () >
182 template<class F
, int A0
, int A1
>
183 struct result_of
<boost::lightweight_forward_adapter
<F
,A0
,A1
>()>
184 : boost::detail::lightweight_forward_adapter_result::template apply
<
185 boost::lightweight_forward_adapter
<F
,A0
,A1
>() >
187 template<class F
, int A0
, int A1
>
188 struct result_of
<boost::lightweight_forward_adapter
<F
,A0
,A1
> const& ()>
189 : boost::detail::lightweight_forward_adapter_result::template apply
<
190 boost::lightweight_forward_adapter
<F
,A0
,A1
> const () >
192 template<class F
, int A0
, int A1
>
193 struct result_of
<boost::lightweight_forward_adapter
<F
,A0
,A1
>& ()>
194 : boost::detail::lightweight_forward_adapter_result::template apply
<
195 boost::lightweight_forward_adapter
<F
,A0
,A1
>() >
199 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
201 # else // defined(BOOST_PP_IS_ITERATING)
202 # define N BOOST_PP_ITERATION()
204 template< class Self
, BOOST_PP_ENUM_PARAMS(N
,typename T
) >
205 struct lightweight_forward_adapter_result::apply
<
206 Self (BOOST_PP_ENUM_PARAMS(N
,T
)) >
208 BOOST_DEDUCED_TYPENAME c
<Self
>::t (BOOST_PP_ENUM_BINARY_PARAMS(N
,
209 typename x
<T
,>::t BOOST_PP_INTERCEPT
)) >
212 template< class MD
, class F
, class FC
>
213 struct lightweight_forward_adapter_impl
<MD
,F
,FC
,BOOST_PP_DEC(N
),N
>
214 : lightweight_forward_adapter_result
216 template< BOOST_PP_ENUM_PARAMS(N
,typename T
) >
217 inline typename
boost::result_of
< F(BOOST_PP_ENUM_BINARY_PARAMS(N
,
218 T
,const& BOOST_PP_INTERCEPT
)) >::type
219 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N
,T
,& BOOST_PP_INTERCEPT
));
222 template< class MD
, class F
, class FC
, int MinArity
>
223 struct lightweight_forward_adapter_impl
<MD
,F
,FC
,N
,MinArity
>
224 : lightweight_forward_adapter_impl
<MD
,F
,FC
,BOOST_PP_DEC(N
),MinArity
>
226 using lightweight_forward_adapter_impl
<MD
,F
,FC
,BOOST_PP_DEC(N
),
227 MinArity
>::operator();
230 static_cast<typename d::template x<T##i>::t>(a##i)
232 template< BOOST_PP_ENUM_PARAMS(N
,typename T
) >
233 inline typename
lightweight_forward_adapter_result::template apply
<
234 MD
const (BOOST_PP_ENUM_BINARY_PARAMS(N
,
235 T
,const& BOOST_PP_INTERCEPT
)) >::type
236 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N
,T
,const& a
)) const
238 typedef lightweight_forward_adapter_result _
;
239 return static_cast<MD
const*>(this)->target_function()(
240 BOOST_PP_ENUM(N
,M
,_
));
242 template< BOOST_PP_ENUM_PARAMS(N
,typename T
) >
243 inline typename
lightweight_forward_adapter_result::template apply
<
244 MD (BOOST_PP_ENUM_BINARY_PARAMS(N
,
245 T
,const& BOOST_PP_INTERCEPT
)) >::type
246 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N
,T
,const& a
))
248 typedef lightweight_forward_adapter_result _
;
249 return static_cast<MD
*>(this)->target_function()(
250 BOOST_PP_ENUM(N
,M
,_
));
256 # endif // defined(BOOST_PP_IS_ITERATING)
258 #endif // include guard