1 | /*============================================================================= |
2 | Copyright (c) 2007 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_LIGHTWEIGHT_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/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> |
21 | |
22 | # include <boost/utility/result_of.hpp> |
23 | # include <boost/ref.hpp> |
24 | |
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 |
30 | # endif |
31 | |
32 | namespace boost |
33 | { |
34 | template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 > |
35 | class lightweight_forward_adapter; |
36 | |
37 | //----- ---- --- -- - - - - |
38 | |
39 | namespace detail |
40 | { |
41 | template< class MostDerived, typename Function, typename FunctionConst, |
42 | int Arity, int MinArity > |
43 | struct lightweight_forward_adapter_impl; |
44 | |
45 | struct lightweight_forward_adapter_result |
46 | { |
47 | template< typename Sig > struct apply; |
48 | |
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> > |
52 | { typedef T& 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> { }; |
56 | |
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; }; |
66 | }; |
67 | } |
68 | |
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) > |
75 | |
76 | template< typename Function, int Arity_Or_MinArity, int MaxArity > |
77 | class lightweight_forward_adapter |
78 | : public BOOST_TMP_MACRO(Function,Function,Function const) |
79 | , private Function |
80 | { |
81 | public: |
82 | lightweight_forward_adapter(Function const& f = Function()) |
83 | : Function(f) |
84 | { } |
85 | |
86 | typedef Function target_function_t; |
87 | typedef Function const target_function_const_t; |
88 | |
89 | Function & target_function() { return *this; } |
90 | Function const & target_function() const { return *this; } |
91 | |
92 | template< typename Sig > struct result |
93 | : detail::lightweight_forward_adapter_result::template apply<Sig> |
94 | { }; |
95 | |
96 | using BOOST_TMP_MACRO(Function,Function, Function const)::operator(); |
97 | }; |
98 | template< typename Function, int Arity_Or_MinArity, int MaxArity > |
99 | class lightweight_forward_adapter< Function const, Arity_Or_MinArity, |
100 | MaxArity > |
101 | : public BOOST_TMP_MACRO(Function const, Function const, Function const) |
102 | , private Function |
103 | { |
104 | public: |
105 | lightweight_forward_adapter(Function const& f = Function()) |
106 | : Function(f) |
107 | { } |
108 | |
109 | typedef Function const target_function_t; |
110 | typedef Function const target_function_const_t; |
111 | |
112 | Function const & target_function() const { return *this; } |
113 | |
114 | template< typename Sig > struct result |
115 | : detail::lightweight_forward_adapter_result::template apply<Sig> |
116 | { }; |
117 | |
118 | using BOOST_TMP_MACRO(Function const,Function const, Function const) |
119 | ::operator(); |
120 | }; |
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) |
124 | { |
125 | Function& ref_function; |
126 | public: |
127 | lightweight_forward_adapter(Function& f) |
128 | : ref_function(f) |
129 | { } |
130 | |
131 | typedef Function target_function_t; |
132 | typedef Function target_function_const_t; |
133 | |
134 | Function & target_function() const { return this->ref_function; } |
135 | |
136 | template< typename Sig > struct result |
137 | : detail::lightweight_forward_adapter_result::template apply<Sig> |
138 | { }; |
139 | |
140 | using BOOST_TMP_MACRO(Function&, Function, Function)::operator(); |
141 | }; |
142 | |
143 | #undef BOOST_TMP_MACRO |
144 | |
145 | namespace detail |
146 | { |
147 | template< class Self > |
148 | struct lightweight_forward_adapter_result::apply< Self() > |
149 | : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() > |
150 | { }; |
151 | |
152 | template< class MD, class F, class FC > |
153 | struct lightweight_forward_adapter_impl<MD,F,FC,0,0> |
154 | : lightweight_forward_adapter_result |
155 | { |
156 | inline typename boost::result_of< FC() >::type |
157 | operator()() const |
158 | { |
159 | return static_cast<MD const*>(this)->target_function()(); |
160 | } |
161 | |
162 | inline typename boost::result_of< F() >::type |
163 | operator()() |
164 | { |
165 | return static_cast<MD*>(this)->target_function()(); |
166 | } |
167 | }; |
168 | |
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() |
174 | |
175 | } // namespace detail |
176 | |
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 () > |
181 | { }; |
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>() > |
186 | { }; |
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 () > |
191 | { }; |
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>() > |
196 | { }; |
197 | } |
198 | |
199 | # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED |
200 | |
201 | # else // defined(BOOST_PP_IS_ITERATING) |
202 | # define N BOOST_PP_ITERATION() |
203 | |
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)) > |
207 | : boost::result_of< |
208 | BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N, |
209 | typename x<T,>::t BOOST_PP_INTERCEPT)) > |
210 | { }; |
211 | |
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 |
215 | { |
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)); |
220 | }; |
221 | |
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> |
225 | { |
226 | using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N), |
227 | MinArity>::operator(); |
228 | |
229 | # define M(z,i,d) \ |
230 | static_cast<typename d::template x<T##i>::t>(a##i) |
231 | |
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 |
237 | { |
238 | typedef lightweight_forward_adapter_result _; |
239 | return static_cast<MD const*>(this)->target_function()( |
240 | BOOST_PP_ENUM(N,M,_)); |
241 | } |
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)) |
247 | { |
248 | typedef lightweight_forward_adapter_result _; |
249 | return static_cast<MD*>(this)->target_function()( |
250 | BOOST_PP_ENUM(N,M,_)); |
251 | } |
252 | # undef M |
253 | }; |
254 | |
255 | # undef N |
256 | # endif // defined(BOOST_PP_IS_ITERATING) |
257 | |
258 | #endif // include guard |
259 | |
260 | |