Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/lambda/detail/ret.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Boost Lambda Library ret.hpp ----------------------------------------- | |
2 | |
3 // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) | |
4 // | |
5 // Distributed under the Boost Software License, Version 1.0. (See | |
6 // accompanying file LICENSE_1_0.txt or copy at | |
7 // http://www.boost.org/LICENSE_1_0.txt) | |
8 // | |
9 // For more information, see www.boost.org | |
10 | |
11 | |
12 #ifndef BOOST_LAMBDA_RET_HPP | |
13 #define BOOST_LAMBDA_RET_HPP | |
14 | |
15 namespace boost { | |
16 namespace lambda { | |
17 | |
18 // TODO: | |
19 | |
20 // Add specializations for function references for ret, protect and unlambda | |
21 // e.g void foo(); unlambda(foo); fails, as it would add a const qualifier | |
22 // for a function type. | |
23 // on the other hand unlambda(*foo) does work | |
24 | |
25 | |
26 // -- ret ------------------------- | |
27 // the explicit return type template | |
28 | |
29 // TODO: It'd be nice to make ret a nop for other than lambda functors | |
30 // but causes an ambiguiyty with gcc (not with KCC), check what is the | |
31 // right interpretation. | |
32 | |
33 // // ret for others than lambda functors has no effect | |
34 // template <class U, class T> | |
35 // inline const T& ret(const T& t) { return t; } | |
36 | |
37 | |
38 template<class RET, class Arg> | |
39 inline const | |
40 lambda_functor< | |
41 lambda_functor_base< | |
42 explicit_return_type_action<RET>, | |
43 tuple<lambda_functor<Arg> > | |
44 > | |
45 > | |
46 ret(const lambda_functor<Arg>& a1) | |
47 { | |
48 return | |
49 lambda_functor_base< | |
50 explicit_return_type_action<RET>, | |
51 tuple<lambda_functor<Arg> > | |
52 > | |
53 (tuple<lambda_functor<Arg> >(a1)); | |
54 } | |
55 | |
56 // protect ------------------ | |
57 | |
58 // protecting others than lambda functors has no effect | |
59 template <class T> | |
60 inline const T& protect(const T& t) { return t; } | |
61 | |
62 template<class Arg> | |
63 inline const | |
64 lambda_functor< | |
65 lambda_functor_base< | |
66 protect_action, | |
67 tuple<lambda_functor<Arg> > | |
68 > | |
69 > | |
70 protect(const lambda_functor<Arg>& a1) | |
71 { | |
72 return | |
73 lambda_functor_base< | |
74 protect_action, | |
75 tuple<lambda_functor<Arg> > | |
76 > | |
77 (tuple<lambda_functor<Arg> >(a1)); | |
78 } | |
79 | |
80 // ------------------------------------------------------------------- | |
81 | |
82 // Hides the lambda functorness of a lambda functor. | |
83 // After this, the functor is immune to argument substitution, etc. | |
84 // This can be used, e.g. to make it safe to pass lambda functors as | |
85 // arguments to functions, which might use them as target functions | |
86 | |
87 // note, unlambda and protect are different things. Protect hides the lambda | |
88 // functor for one application, unlambda for good. | |
89 | |
90 template <class LambdaFunctor> | |
91 class non_lambda_functor | |
92 { | |
93 LambdaFunctor lf; | |
94 public: | |
95 | |
96 // This functor defines the result_type typedef. | |
97 // The result type must be deducible without knowing the arguments | |
98 | |
99 template <class SigArgs> struct sig { | |
100 typedef typename | |
101 LambdaFunctor::inherited:: | |
102 template sig<typename SigArgs::tail_type>::type type; | |
103 }; | |
104 | |
105 explicit non_lambda_functor(const LambdaFunctor& a) : lf(a) {} | |
106 | |
107 typename LambdaFunctor::nullary_return_type | |
108 operator()() const { | |
109 return lf.template | |
110 call<typename LambdaFunctor::nullary_return_type> | |
111 (cnull_type(), cnull_type(), cnull_type(), cnull_type()); | |
112 } | |
113 | |
114 template<class A> | |
115 typename sig<tuple<const non_lambda_functor, A&> >::type | |
116 operator()(A& a) const { | |
117 return lf.template call<typename sig<tuple<const non_lambda_functor, A&> >::type >(a, cnull_type(), cnull_type(), cnull_type()); | |
118 } | |
119 | |
120 template<class A, class B> | |
121 typename sig<tuple<const non_lambda_functor, A&, B&> >::type | |
122 operator()(A& a, B& b) const { | |
123 return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&> >::type >(a, b, cnull_type(), cnull_type()); | |
124 } | |
125 | |
126 template<class A, class B, class C> | |
127 typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type | |
128 operator()(A& a, B& b, C& c) const { | |
129 return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type>(a, b, c, cnull_type()); | |
130 } | |
131 }; | |
132 | |
133 template <class Arg> | |
134 inline const Arg& unlambda(const Arg& a) { return a; } | |
135 | |
136 template <class Arg> | |
137 inline const non_lambda_functor<lambda_functor<Arg> > | |
138 unlambda(const lambda_functor<Arg>& a) | |
139 { | |
140 return non_lambda_functor<lambda_functor<Arg> >(a); | |
141 } | |
142 | |
143 // Due to a language restriction, lambda functors cannot be made to | |
144 // accept non-const rvalue arguments. Usually iterators do not return | |
145 // temporaries, but sometimes they do. That's why a workaround is provided. | |
146 // Note, that this potentially breaks const correctness, so be careful! | |
147 | |
148 // any lambda functor can be turned into a const_incorrect_lambda_functor | |
149 // The operator() takes arguments as consts and then casts constness | |
150 // away. So this breaks const correctness!!! but is a necessary workaround | |
151 // in some cases due to language limitations. | |
152 // Note, that this is not a lambda_functor anymore, so it can not be used | |
153 // as a sub lambda expression. | |
154 | |
155 template <class LambdaFunctor> | |
156 struct const_incorrect_lambda_functor { | |
157 LambdaFunctor lf; | |
158 public: | |
159 | |
160 explicit const_incorrect_lambda_functor(const LambdaFunctor& a) : lf(a) {} | |
161 | |
162 template <class SigArgs> struct sig { | |
163 typedef typename | |
164 LambdaFunctor::inherited::template | |
165 sig<typename SigArgs::tail_type>::type type; | |
166 }; | |
167 | |
168 // The nullary case is not needed (no arguments, no parameter type problems) | |
169 | |
170 template<class A> | |
171 typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type | |
172 operator()(const A& a) const { | |
173 return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type >(const_cast<A&>(a), cnull_type(), cnull_type(), cnull_type()); | |
174 } | |
175 | |
176 template<class A, class B> | |
177 typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type | |
178 operator()(const A& a, const B& b) const { | |
179 return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type >(const_cast<A&>(a), const_cast<B&>(b), cnull_type(), cnull_type()); | |
180 } | |
181 | |
182 template<class A, class B, class C> | |
183 typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type | |
184 operator()(const A& a, const B& b, const C& c) const { | |
185 return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type>(const_cast<A&>(a), const_cast<B&>(b), const_cast<C&>(c), cnull_type()); | |
186 } | |
187 }; | |
188 | |
189 // ------------------------------------------------------------------------ | |
190 // any lambda functor can be turned into a const_parameter_lambda_functor | |
191 // The operator() takes arguments as const. | |
192 // This is useful if lambda functors are called with non-const rvalues. | |
193 // Note, that this is not a lambda_functor anymore, so it can not be used | |
194 // as a sub lambda expression. | |
195 | |
196 template <class LambdaFunctor> | |
197 struct const_parameter_lambda_functor { | |
198 LambdaFunctor lf; | |
199 public: | |
200 | |
201 explicit const_parameter_lambda_functor(const LambdaFunctor& a) : lf(a) {} | |
202 | |
203 template <class SigArgs> struct sig { | |
204 typedef typename | |
205 LambdaFunctor::inherited::template | |
206 sig<typename SigArgs::tail_type>::type type; | |
207 }; | |
208 | |
209 // The nullary case is not needed: no arguments, no constness problems. | |
210 | |
211 template<class A> | |
212 typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type | |
213 operator()(const A& a) const { | |
214 return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type >(a, cnull_type(), cnull_type(), cnull_type()); | |
215 } | |
216 | |
217 template<class A, class B> | |
218 typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type | |
219 operator()(const A& a, const B& b) const { | |
220 return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type >(a, b, cnull_type(), cnull_type()); | |
221 } | |
222 | |
223 template<class A, class B, class C> | |
224 typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&> | |
225 >::type | |
226 operator()(const A& a, const B& b, const C& c) const { | |
227 return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&> >::type>(a, b, c, cnull_type()); | |
228 } | |
229 }; | |
230 | |
231 template <class Arg> | |
232 inline const const_incorrect_lambda_functor<lambda_functor<Arg> > | |
233 break_const(const lambda_functor<Arg>& lf) | |
234 { | |
235 return const_incorrect_lambda_functor<lambda_functor<Arg> >(lf); | |
236 } | |
237 | |
238 | |
239 template <class Arg> | |
240 inline const const_parameter_lambda_functor<lambda_functor<Arg> > | |
241 const_parameters(const lambda_functor<Arg>& lf) | |
242 { | |
243 return const_parameter_lambda_functor<lambda_functor<Arg> >(lf); | |
244 } | |
245 | |
246 // make void ------------------------------------------------ | |
247 // make_void( x ) turns a lambda functor x with some return type y into | |
248 // another lambda functor, which has a void return type | |
249 // when called, the original return type is discarded | |
250 | |
251 // we use this action. The action class will be called, which means that | |
252 // the wrapped lambda functor is evaluated, but we just don't do anything | |
253 // with the result. | |
254 struct voidifier_action { | |
255 template<class Ret, class A> static void apply(A&) {} | |
256 }; | |
257 | |
258 template<class Args> struct return_type_N<voidifier_action, Args> { | |
259 typedef void type; | |
260 }; | |
261 | |
262 template<class Arg1> | |
263 inline const | |
264 lambda_functor< | |
265 lambda_functor_base< | |
266 action<1, voidifier_action>, | |
267 tuple<lambda_functor<Arg1> > | |
268 > | |
269 > | |
270 make_void(const lambda_functor<Arg1>& a1) { | |
271 return | |
272 lambda_functor_base< | |
273 action<1, voidifier_action>, | |
274 tuple<lambda_functor<Arg1> > | |
275 > | |
276 (tuple<lambda_functor<Arg1> > (a1)); | |
277 } | |
278 | |
279 // for non-lambda functors, make_void does nothing | |
280 // (the argument gets evaluated immediately) | |
281 | |
282 template<class Arg1> | |
283 inline const | |
284 lambda_functor< | |
285 lambda_functor_base<do_nothing_action, null_type> | |
286 > | |
287 make_void(const Arg1&) { | |
288 return | |
289 lambda_functor_base<do_nothing_action, null_type>(); | |
290 } | |
291 | |
292 // std_functor ----------------------------------------------------- | |
293 | |
294 // The STL uses the result_type typedef as the convention to let binders know | |
295 // the return type of a function object. | |
296 // LL uses the sig template. | |
297 // To let LL know that the function object has the result_type typedef | |
298 // defined, it can be wrapped with the std_functor function. | |
299 | |
300 | |
301 // Just inherit form the template parameter (the standard functor), | |
302 // and provide a sig template. So we have a class which is still the | |
303 // same functor + the sig template. | |
304 | |
305 template<class T> | |
306 struct result_type_to_sig : public T { | |
307 template<class Args> struct sig { typedef typename T::result_type type; }; | |
308 result_type_to_sig(const T& t) : T(t) {} | |
309 }; | |
310 | |
311 template<class F> | |
312 inline result_type_to_sig<F> std_functor(const F& f) { return f; } | |
313 | |
314 | |
315 } // namespace lambda | |
316 } // namespace boost | |
317 | |
318 #endif | |
319 | |
320 | |
321 | |
322 | |
323 | |
324 | |
325 |