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< 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 | 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 | |
---|