1 | |
2 | #if !defined(BOOST_PP_IS_ITERATING) |
3 | |
4 | ///// header body |
5 | |
6 | #ifndef BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED |
7 | #define BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED |
8 | |
9 | // Copyright Aleksey Gurtovoy 2001-2004 |
10 | // |
11 | // Distributed under the Boost Software License, Version 1.0. |
12 | // (See accompanying file LICENSE_1_0.txt or copy at |
13 | // http://www.boost.org/LICENSE_1_0.txt) |
14 | // |
15 | // See http://www.boost.org/libs/mpl for documentation. |
16 | |
17 | // $Id$ |
18 | // $Date$ |
19 | // $Revision$ |
20 | |
21 | #if !defined(BOOST_MPL_PREPROCESSING_MODE) |
22 | # include <boost/mpl/lambda_fwd.hpp> |
23 | # include <boost/mpl/bind_fwd.hpp> |
24 | # include <boost/mpl/protect.hpp> |
25 | # include <boost/mpl/quote.hpp> |
26 | # include <boost/mpl/arg.hpp> |
27 | # include <boost/mpl/bool.hpp> |
28 | # include <boost/mpl/int_fwd.hpp> |
29 | # include <boost/mpl/aux_/template_arity.hpp> |
30 | # include <boost/mpl/aux_/na_spec.hpp> |
31 | # include <boost/mpl/aux_/config/ttp.hpp> |
32 | # if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) |
33 | # include <boost/mpl/if.hpp> |
34 | # endif |
35 | #endif |
36 | |
37 | #include <boost/mpl/aux_/lambda_arity_param.hpp> |
38 | #include <boost/mpl/aux_/config/use_preprocessed.hpp> |
39 | |
40 | #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \ |
41 | && !defined(BOOST_MPL_PREPROCESSING_MODE) |
42 | |
43 | # define full_lambda.hpp |
44 | # include <boost/mpl/aux_/include_preprocessed.hpp> |
45 | |
46 | #else |
47 | |
48 | # include <boost/mpl/limits/arity.hpp> |
49 | # include <boost/mpl/aux_/preprocessor/default_params.hpp> |
50 | # include <boost/mpl/aux_/preprocessor/params.hpp> |
51 | # include <boost/mpl/aux_/preprocessor/enum.hpp> |
52 | # include <boost/mpl/aux_/preprocessor/repeat.hpp> |
53 | # include <boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp> |
54 | |
55 | # include <boost/preprocessor/iterate.hpp> |
56 | # include <boost/preprocessor/comma_if.hpp> |
57 | # include <boost/preprocessor/inc.hpp> |
58 | # include <boost/preprocessor/cat.hpp> |
59 | |
60 | namespace boost { namespace mpl { |
61 | |
62 | // local macros, #undef-ined at the end of the header |
63 | # define AUX778076_LAMBDA_PARAMS(i_, param) \ |
64 | BOOST_MPL_PP_PARAMS(i_, param) \ |
65 | /**/ |
66 | |
67 | # define AUX778076_BIND_PARAMS(param) \ |
68 | BOOST_MPL_PP_PARAMS( \ |
69 | BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ |
70 | , param \ |
71 | ) \ |
72 | /**/ |
73 | |
74 | # define AUX778076_BIND_N_PARAMS(i_, param) \ |
75 | BOOST_PP_COMMA_IF(i_) \ |
76 | BOOST_MPL_PP_PARAMS(i_, param) \ |
77 | /**/ |
78 | |
79 | # define AUX778076_ARITY_PARAM(param) \ |
80 | BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param) \ |
81 | /**/ |
82 | |
83 | |
84 | #define n_ BOOST_MPL_LIMIT_METAFUNCTION_ARITY |
85 | namespace aux { |
86 | |
87 | template< |
88 | BOOST_MPL_PP_DEFAULT_PARAMS(n_,bool C,false) |
89 | > |
90 | struct lambda_or |
91 | : true_ |
92 | { |
93 | }; |
94 | |
95 | template<> |
96 | struct lambda_or< BOOST_MPL_PP_ENUM(n_,false) > |
97 | : false_ |
98 | { |
99 | }; |
100 | |
101 | } // namespace aux |
102 | #undef n_ |
103 | |
104 | template< |
105 | typename T |
106 | , typename Tag |
107 | AUX778076_ARITY_PARAM(typename Arity) |
108 | > |
109 | struct lambda |
110 | { |
111 | typedef false_ is_le; |
112 | typedef T result_; |
113 | typedef T type; |
114 | }; |
115 | |
116 | template< |
117 | typename T |
118 | > |
119 | struct is_lambda_expression |
120 | : lambda<T>::is_le |
121 | { |
122 | }; |
123 | |
124 | |
125 | template< int N, typename Tag > |
126 | struct lambda< arg<N>,Tag AUX778076_ARITY_PARAM(int_<-1>) > |
127 | { |
128 | typedef true_ is_le; |
129 | typedef mpl::arg<N> result_; // qualified for the sake of MIPSpro 7.41 |
130 | typedef mpl::protect<result_> type; |
131 | }; |
132 | |
133 | |
134 | #define BOOST_PP_ITERATION_PARAMS_1 \ |
135 | (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/aux_/full_lambda.hpp>)) |
136 | #include BOOST_PP_ITERATE() |
137 | |
138 | /// special case for 'protect' |
139 | template< typename T, typename Tag > |
140 | struct lambda< mpl::protect<T>,Tag AUX778076_ARITY_PARAM(int_<1>) > |
141 | { |
142 | typedef false_ is_le; |
143 | typedef mpl::protect<T> result_; |
144 | typedef result_ type; |
145 | }; |
146 | |
147 | /// specializations for the main 'bind' form |
148 | template< |
149 | typename F, AUX778076_BIND_PARAMS(typename T) |
150 | , typename Tag |
151 | > |
152 | struct lambda< |
153 | bind<F,AUX778076_BIND_PARAMS(T)> |
154 | , Tag |
155 | AUX778076_ARITY_PARAM(int_<BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)>) |
156 | > |
157 | { |
158 | typedef false_ is_le; |
159 | typedef bind<F, AUX778076_BIND_PARAMS(T)> result_; |
160 | typedef result_ type; |
161 | }; |
162 | |
163 | |
164 | #if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) |
165 | |
166 | template< |
167 | typename F |
168 | , typename Tag1 |
169 | , typename Tag2 |
170 | , typename Arity |
171 | > |
172 | struct lambda< |
173 | lambda<F,Tag1,Arity> |
174 | , Tag2 |
175 | , int_<3> |
176 | > |
177 | { |
178 | typedef lambda< F,Tag2 > l1; |
179 | typedef lambda< Tag1,Tag2 > l2; |
180 | |
181 | typedef typename l1::is_le is_le; |
182 | typedef bind1< quote1<aux::template_arity>, typename l1::result_ > arity_; |
183 | typedef lambda< typename if_<is_le,arity_,Arity>::type,Tag2 > l3; |
184 | |
185 | typedef aux::le_result3<is_le, Tag2, mpl::lambda, l1, l2, l3> le_result_; |
186 | typedef typename le_result_::result_ result_; |
187 | typedef typename le_result_::type type; |
188 | }; |
189 | |
190 | #elif !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS) |
191 | |
192 | /// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars |
193 | template< |
194 | typename F, typename Tag1, typename Tag2 |
195 | > |
196 | struct lambda< |
197 | lambda< F,Tag1 > |
198 | , Tag2 |
199 | > |
200 | { |
201 | typedef lambda< F,Tag2 > l1; |
202 | typedef lambda< Tag1,Tag2 > l2; |
203 | |
204 | typedef typename l1::is_le is_le; |
205 | typedef aux::le_result2<is_le, Tag2, mpl::lambda, l1, l2> le_result_; |
206 | typedef typename le_result_::result_ result_; |
207 | typedef typename le_result_::type type; |
208 | }; |
209 | |
210 | #endif |
211 | |
212 | # undef AUX778076_ARITY_PARAM |
213 | # undef AUX778076_BIND_N_PARAMS |
214 | # undef AUX778076_BIND_PARAMS |
215 | # undef AUX778076_LAMBDA_PARAMS |
216 | |
217 | #if !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) |
218 | BOOST_MPL_AUX_NA_SPEC(2, lambda) |
219 | #else |
220 | BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda) |
221 | #endif |
222 | |
223 | }} |
224 | |
225 | #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS |
226 | #endif // BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED |
227 | |
228 | ///// iteration, depth == 1 |
229 | |
230 | // For gcc 4.4 compatability, we must include the |
231 | // BOOST_PP_ITERATION_DEPTH test inside an #else clause. |
232 | #else // BOOST_PP_IS_ITERATING |
233 | #if BOOST_PP_ITERATION_DEPTH() == 1 |
234 | #define i_ BOOST_PP_FRAME_ITERATION(1) |
235 | |
236 | #if i_ > 0 |
237 | |
238 | namespace aux { |
239 | |
240 | # define AUX778076_RESULT(unused, i_, T) \ |
241 | BOOST_PP_COMMA_IF(i_) \ |
242 | typename BOOST_PP_CAT(T, BOOST_PP_INC(i_))::result_ \ |
243 | /**/ |
244 | |
245 | # define AUX778076_TYPE(unused, i_, T) \ |
246 | BOOST_PP_COMMA_IF(i_) \ |
247 | typename BOOST_PP_CAT(T, BOOST_PP_INC(i_))::type \ |
248 | /**/ |
249 | |
250 | template< |
251 | typename IsLE, typename Tag |
252 | , template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F |
253 | , AUX778076_LAMBDA_PARAMS(i_, typename L) |
254 | > |
255 | struct BOOST_PP_CAT(le_result,i_) |
256 | { |
257 | typedef F< |
258 | BOOST_MPL_PP_REPEAT(i_, AUX778076_TYPE, L) |
259 | > result_; |
260 | |
261 | typedef result_ type; |
262 | }; |
263 | |
264 | template< |
265 | typename Tag |
266 | , template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F |
267 | , AUX778076_LAMBDA_PARAMS(i_, typename L) |
268 | > |
269 | struct BOOST_PP_CAT(le_result,i_)< true_,Tag,F,AUX778076_LAMBDA_PARAMS(i_, L) > |
270 | { |
271 | typedef BOOST_PP_CAT(bind,i_)< |
272 | BOOST_PP_CAT(quote,i_)<F,Tag> |
273 | , BOOST_MPL_PP_REPEAT(i_, AUX778076_RESULT, L) |
274 | > result_; |
275 | |
276 | typedef mpl::protect<result_> type; |
277 | }; |
278 | |
279 | # undef AUX778076_TYPE |
280 | # undef AUX778076_RESULT |
281 | |
282 | } // namespace aux |
283 | |
284 | |
285 | # define AUX778076_LAMBDA_TYPEDEF(unused, i_, T) \ |
286 | typedef lambda< BOOST_PP_CAT(T, BOOST_PP_INC(i_)), Tag > \ |
287 | BOOST_PP_CAT(l,BOOST_PP_INC(i_)); \ |
288 | /**/ |
289 | |
290 | # define AUX778076_IS_LE_TYPEDEF(unused, i_, unused2) \ |
291 | typedef typename BOOST_PP_CAT(l,BOOST_PP_INC(i_))::is_le \ |
292 | BOOST_PP_CAT(is_le,BOOST_PP_INC(i_)); \ |
293 | /**/ |
294 | |
295 | # define AUX778076_IS_LAMBDA_EXPR(unused, i_, unused2) \ |
296 | BOOST_PP_COMMA_IF(i_) \ |
297 | BOOST_PP_CAT(is_le,BOOST_PP_INC(i_))::value \ |
298 | /**/ |
299 | |
300 | template< |
301 | template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F |
302 | , AUX778076_LAMBDA_PARAMS(i_, typename T) |
303 | , typename Tag |
304 | > |
305 | struct lambda< |
306 | F<AUX778076_LAMBDA_PARAMS(i_, T)> |
307 | , Tag |
308 | AUX778076_ARITY_PARAM(int_<i_>) |
309 | > |
310 | { |
311 | BOOST_MPL_PP_REPEAT(i_, AUX778076_LAMBDA_TYPEDEF, T) |
312 | BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LE_TYPEDEF, unused) |
313 | |
314 | typedef typename aux::lambda_or< |
315 | BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LAMBDA_EXPR, unused) |
316 | >::type is_le; |
317 | |
318 | typedef aux::BOOST_PP_CAT(le_result,i_)< |
319 | is_le, Tag, F, AUX778076_LAMBDA_PARAMS(i_, l) |
320 | > le_result_; |
321 | |
322 | typedef typename le_result_::result_ result_; |
323 | typedef typename le_result_::type type; |
324 | }; |
325 | |
326 | |
327 | # undef AUX778076_IS_LAMBDA_EXPR |
328 | # undef AUX778076_IS_LE_TYPEDEF |
329 | # undef AUX778076_LAMBDA_TYPEDEF |
330 | |
331 | #endif // i_ > 0 |
332 | |
333 | template< |
334 | typename F AUX778076_BIND_N_PARAMS(i_, typename T) |
335 | , typename Tag |
336 | > |
337 | struct lambda< |
338 | BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_, T)> |
339 | , Tag |
340 | AUX778076_ARITY_PARAM(int_<BOOST_PP_INC(i_)>) |
341 | > |
342 | { |
343 | typedef false_ is_le; |
344 | typedef BOOST_PP_CAT(bind,i_)< |
345 | F |
346 | AUX778076_BIND_N_PARAMS(i_, T) |
347 | > result_; |
348 | |
349 | typedef result_ type; |
350 | }; |
351 | |
352 | #undef i_ |
353 | #endif // BOOST_PP_ITERATION_DEPTH() |
354 | #endif // BOOST_PP_IS_ITERATING |
355 | |