Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2007 Tobias Schwinger
|
Chris@16
|
3
|
Chris@16
|
4 Use modification and distribution are subject to the Boost Software
|
Chris@16
|
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt).
|
Chris@16
|
7 ==============================================================================*/
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
|
Chris@16
|
10 # ifndef BOOST_PP_IS_ITERATING
|
Chris@16
|
11
|
Chris@16
|
12 # include <boost/config.hpp>
|
Chris@16
|
13 # include <boost/detail/workaround.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 # include <boost/preprocessor/cat.hpp>
|
Chris@16
|
16 # include <boost/preprocessor/iteration/iterate.hpp>
|
Chris@16
|
17 # include <boost/preprocessor/repetition/enum.hpp>
|
Chris@16
|
18 # include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
19 # include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
Chris@16
|
20 # include <boost/preprocessor/facilities/intercept.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 # include <boost/utility/result_of.hpp>
|
Chris@16
|
23 # include <boost/ref.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 # ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
|
Chris@16
|
26 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10
|
Chris@16
|
27 # elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3
|
Chris@16
|
28 # undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
|
Chris@16
|
29 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3
|
Chris@16
|
30 # endif
|
Chris@16
|
31
|
Chris@16
|
32 namespace boost
|
Chris@16
|
33 {
|
Chris@16
|
34 template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
|
Chris@16
|
35 class lightweight_forward_adapter;
|
Chris@16
|
36
|
Chris@16
|
37 //----- ---- --- -- - - - -
|
Chris@16
|
38
|
Chris@16
|
39 namespace detail
|
Chris@16
|
40 {
|
Chris@16
|
41 template< class MostDerived, typename Function, typename FunctionConst,
|
Chris@16
|
42 int Arity, int MinArity >
|
Chris@16
|
43 struct lightweight_forward_adapter_impl;
|
Chris@16
|
44
|
Chris@16
|
45 struct lightweight_forward_adapter_result
|
Chris@16
|
46 {
|
Chris@16
|
47 template< typename Sig > struct apply;
|
Chris@16
|
48
|
Chris@16
|
49 // Utility metafunction for argument transform
|
Chris@16
|
50 template< typename T > struct x { typedef T const& t; };
|
Chris@16
|
51 template< typename T > struct x< boost::reference_wrapper<T> >
|
Chris@16
|
52 { typedef T& t; };
|
Chris@16
|
53 template< typename T > struct x<T&> : x<T> { };
|
Chris@16
|
54 template< typename T > struct x<T const&> : x<T> { };
|
Chris@16
|
55 template< typename T > struct x<T const> : x<T> { };
|
Chris@16
|
56
|
Chris@16
|
57 // Utility metafunction to choose target function qualification
|
Chris@16
|
58 template< typename T > struct c
|
Chris@16
|
59 { typedef typename T::target_function_t t; };
|
Chris@16
|
60 template< typename T > struct c<T& >
|
Chris@16
|
61 { typedef typename T::target_function_t t; };
|
Chris@16
|
62 template< typename T > struct c<T const >
|
Chris@16
|
63 { typedef typename T::target_function_const_t t; };
|
Chris@16
|
64 template< typename T > struct c<T const&>
|
Chris@16
|
65 { typedef typename T::target_function_const_t t; };
|
Chris@16
|
66 };
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 # define BOOST_TMP_MACRO(f,fn,fc) \
|
Chris@16
|
70 boost::detail::lightweight_forward_adapter_impl< \
|
Chris@16
|
71 lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
|
Chris@16
|
72 (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
|
Chris@16
|
73 :BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \
|
Chris@16
|
74 (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
|
Chris@16
|
75
|
Chris@16
|
76 template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
Chris@16
|
77 class lightweight_forward_adapter
|
Chris@16
|
78 : public BOOST_TMP_MACRO(Function,Function,Function const)
|
Chris@16
|
79 , private Function
|
Chris@16
|
80 {
|
Chris@16
|
81 public:
|
Chris@16
|
82 lightweight_forward_adapter(Function const& f = Function())
|
Chris@16
|
83 : Function(f)
|
Chris@16
|
84 { }
|
Chris@16
|
85
|
Chris@16
|
86 typedef Function target_function_t;
|
Chris@16
|
87 typedef Function const target_function_const_t;
|
Chris@16
|
88
|
Chris@16
|
89 Function & target_function() { return *this; }
|
Chris@16
|
90 Function const & target_function() const { return *this; }
|
Chris@16
|
91
|
Chris@16
|
92 template< typename Sig > struct result
|
Chris@16
|
93 : detail::lightweight_forward_adapter_result::template apply<Sig>
|
Chris@16
|
94 { };
|
Chris@16
|
95
|
Chris@16
|
96 using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
|
Chris@16
|
97 };
|
Chris@16
|
98 template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
Chris@16
|
99 class lightweight_forward_adapter< Function const, Arity_Or_MinArity,
|
Chris@16
|
100 MaxArity >
|
Chris@16
|
101 : public BOOST_TMP_MACRO(Function const, Function const, Function const)
|
Chris@16
|
102 , private Function
|
Chris@16
|
103 {
|
Chris@16
|
104 public:
|
Chris@16
|
105 lightweight_forward_adapter(Function const& f = Function())
|
Chris@16
|
106 : Function(f)
|
Chris@16
|
107 { }
|
Chris@16
|
108
|
Chris@16
|
109 typedef Function const target_function_t;
|
Chris@16
|
110 typedef Function const target_function_const_t;
|
Chris@16
|
111
|
Chris@16
|
112 Function const & target_function() const { return *this; }
|
Chris@16
|
113
|
Chris@16
|
114 template< typename Sig > struct result
|
Chris@16
|
115 : detail::lightweight_forward_adapter_result::template apply<Sig>
|
Chris@16
|
116 { };
|
Chris@16
|
117
|
Chris@16
|
118 using BOOST_TMP_MACRO(Function const,Function const, Function const)
|
Chris@16
|
119 ::operator();
|
Chris@16
|
120 };
|
Chris@16
|
121 template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
Chris@16
|
122 class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
|
Chris@16
|
123 : public BOOST_TMP_MACRO(Function&, Function, Function)
|
Chris@16
|
124 {
|
Chris@16
|
125 Function& ref_function;
|
Chris@16
|
126 public:
|
Chris@16
|
127 lightweight_forward_adapter(Function& f)
|
Chris@16
|
128 : ref_function(f)
|
Chris@16
|
129 { }
|
Chris@16
|
130
|
Chris@16
|
131 typedef Function target_function_t;
|
Chris@16
|
132 typedef Function target_function_const_t;
|
Chris@16
|
133
|
Chris@16
|
134 Function & target_function() const { return this->ref_function; }
|
Chris@16
|
135
|
Chris@16
|
136 template< typename Sig > struct result
|
Chris@16
|
137 : detail::lightweight_forward_adapter_result::template apply<Sig>
|
Chris@16
|
138 { };
|
Chris@16
|
139
|
Chris@16
|
140 using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
|
Chris@16
|
141 };
|
Chris@16
|
142
|
Chris@16
|
143 #undef BOOST_TMP_MACRO
|
Chris@16
|
144
|
Chris@16
|
145 namespace detail
|
Chris@16
|
146 {
|
Chris@16
|
147 template< class Self >
|
Chris@16
|
148 struct lightweight_forward_adapter_result::apply< Self() >
|
Chris@16
|
149 : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
|
Chris@16
|
150 { };
|
Chris@16
|
151
|
Chris@16
|
152 template< class MD, class F, class FC >
|
Chris@16
|
153 struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
|
Chris@16
|
154 : lightweight_forward_adapter_result
|
Chris@16
|
155 {
|
Chris@16
|
156 inline typename boost::result_of< FC() >::type
|
Chris@16
|
157 operator()() const
|
Chris@16
|
158 {
|
Chris@16
|
159 return static_cast<MD const*>(this)->target_function()();
|
Chris@16
|
160 }
|
Chris@16
|
161
|
Chris@16
|
162 inline typename boost::result_of< F() >::type
|
Chris@16
|
163 operator()()
|
Chris@16
|
164 {
|
Chris@16
|
165 return static_cast<MD*>(this)->target_function()();
|
Chris@16
|
166 }
|
Chris@16
|
167 };
|
Chris@16
|
168
|
Chris@16
|
169 # define BOOST_PP_FILENAME_1 \
|
Chris@16
|
170 <boost/functional/lightweight_forward_adapter.hpp>
|
Chris@16
|
171 # define BOOST_PP_ITERATION_LIMITS \
|
Chris@16
|
172 (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY)
|
Chris@16
|
173 # include BOOST_PP_ITERATE()
|
Chris@16
|
174
|
Chris@16
|
175 } // namespace detail
|
Chris@16
|
176
|
Chris@16
|
177 template<class F, int A0, int A1>
|
Chris@16
|
178 struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const ()>
|
Chris@16
|
179 : boost::detail::lightweight_forward_adapter_result::template apply<
|
Chris@16
|
180 boost::lightweight_forward_adapter<F,A0,A1> const () >
|
Chris@16
|
181 { };
|
Chris@16
|
182 template<class F, int A0, int A1>
|
Chris@16
|
183 struct result_of<boost::lightweight_forward_adapter<F,A0,A1>()>
|
Chris@16
|
184 : boost::detail::lightweight_forward_adapter_result::template apply<
|
Chris@16
|
185 boost::lightweight_forward_adapter<F,A0,A1>() >
|
Chris@16
|
186 { };
|
Chris@16
|
187 template<class F, int A0, int A1>
|
Chris@16
|
188 struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const& ()>
|
Chris@16
|
189 : boost::detail::lightweight_forward_adapter_result::template apply<
|
Chris@16
|
190 boost::lightweight_forward_adapter<F,A0,A1> const () >
|
Chris@16
|
191 { };
|
Chris@16
|
192 template<class F, int A0, int A1>
|
Chris@16
|
193 struct result_of<boost::lightweight_forward_adapter<F,A0,A1>& ()>
|
Chris@16
|
194 : boost::detail::lightweight_forward_adapter_result::template apply<
|
Chris@16
|
195 boost::lightweight_forward_adapter<F,A0,A1>() >
|
Chris@16
|
196 { };
|
Chris@16
|
197 }
|
Chris@16
|
198
|
Chris@16
|
199 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
|
Chris@16
|
200
|
Chris@16
|
201 # else // defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
202 # define N BOOST_PP_ITERATION()
|
Chris@16
|
203
|
Chris@16
|
204 template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
|
Chris@16
|
205 struct lightweight_forward_adapter_result::apply<
|
Chris@16
|
206 Self (BOOST_PP_ENUM_PARAMS(N,T)) >
|
Chris@16
|
207 : boost::result_of<
|
Chris@16
|
208 BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N,
|
Chris@16
|
209 typename x<T,>::t BOOST_PP_INTERCEPT)) >
|
Chris@16
|
210 { };
|
Chris@16
|
211
|
Chris@16
|
212 template< class MD, class F, class FC >
|
Chris@16
|
213 struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
|
Chris@16
|
214 : lightweight_forward_adapter_result
|
Chris@16
|
215 {
|
Chris@16
|
216 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
Chris@16
|
217 inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N,
|
Chris@16
|
218 T,const& BOOST_PP_INTERCEPT)) >::type
|
Chris@16
|
219 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
|
Chris@16
|
220 };
|
Chris@16
|
221
|
Chris@16
|
222 template< class MD, class F, class FC, int MinArity >
|
Chris@16
|
223 struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity>
|
Chris@16
|
224 : lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
|
Chris@16
|
225 {
|
Chris@16
|
226 using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),
|
Chris@16
|
227 MinArity>::operator();
|
Chris@16
|
228
|
Chris@16
|
229 # define M(z,i,d) \
|
Chris@16
|
230 static_cast<typename d::template x<T##i>::t>(a##i)
|
Chris@16
|
231
|
Chris@16
|
232 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
Chris@16
|
233 inline typename lightweight_forward_adapter_result::template apply<
|
Chris@16
|
234 MD const (BOOST_PP_ENUM_BINARY_PARAMS(N,
|
Chris@16
|
235 T,const& BOOST_PP_INTERCEPT)) >::type
|
Chris@16
|
236 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const
|
Chris@16
|
237 {
|
Chris@16
|
238 typedef lightweight_forward_adapter_result _;
|
Chris@16
|
239 return static_cast<MD const*>(this)->target_function()(
|
Chris@16
|
240 BOOST_PP_ENUM(N,M,_));
|
Chris@16
|
241 }
|
Chris@16
|
242 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
Chris@16
|
243 inline typename lightweight_forward_adapter_result::template apply<
|
Chris@16
|
244 MD (BOOST_PP_ENUM_BINARY_PARAMS(N,
|
Chris@16
|
245 T,const& BOOST_PP_INTERCEPT)) >::type
|
Chris@16
|
246 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a))
|
Chris@16
|
247 {
|
Chris@16
|
248 typedef lightweight_forward_adapter_result _;
|
Chris@16
|
249 return static_cast<MD*>(this)->target_function()(
|
Chris@16
|
250 BOOST_PP_ENUM(N,M,_));
|
Chris@16
|
251 }
|
Chris@16
|
252 # undef M
|
Chris@16
|
253 };
|
Chris@16
|
254
|
Chris@16
|
255 # undef N
|
Chris@16
|
256 # endif // defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
257
|
Chris@16
|
258 #endif // include guard
|
Chris@16
|
259
|