[857] | 1 | // Boost Lambda Library -- control_structures_impl.hpp ---------------------
|
---|
| 2 |
|
---|
| 3 | // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
---|
| 4 | // Copyright (C) 2000 Gary Powell (powellg@amazon.com)
|
---|
| 5 | //
|
---|
| 6 | // Distributed under the Boost Software License, Version 1.0. (See
|
---|
| 7 | // accompanying file LICENSE_1_0.txt or copy at
|
---|
| 8 | // http://www.boost.org/LICENSE_1_0.txt)
|
---|
| 9 | //
|
---|
| 10 | // For more information, see www.boost.org
|
---|
| 11 |
|
---|
| 12 | // --------------------------------------------------------------------------
|
---|
| 13 |
|
---|
| 14 | #if !defined(BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP)
|
---|
| 15 | #define BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP
|
---|
| 16 |
|
---|
| 17 | namespace boost {
|
---|
| 18 | namespace lambda {
|
---|
| 19 |
|
---|
| 20 | // -- void return control actions ----------------------
|
---|
| 21 |
|
---|
| 22 | class forloop_action {};
|
---|
| 23 | class forloop_no_body_action {};
|
---|
| 24 | class ifthen_action {};
|
---|
| 25 | class ifthenelse_action {};
|
---|
| 26 | class whileloop_action {};
|
---|
| 27 | class whileloop_no_body_action {};
|
---|
| 28 | class dowhileloop_action {};
|
---|
| 29 | class dowhileloop_no_body_action {};
|
---|
| 30 | // -- nonvoid return control actions ----------------------
|
---|
| 31 |
|
---|
| 32 | class ifthenelsereturn_action {};
|
---|
| 33 |
|
---|
| 34 | // For loop
|
---|
| 35 | template <class Arg1, class Arg2, class Arg3, class Arg4>
|
---|
| 36 | inline const
|
---|
| 37 | lambda_functor<
|
---|
| 38 | lambda_functor_base<
|
---|
| 39 | forloop_action,
|
---|
| 40 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
|
---|
| 41 | lambda_functor<Arg3>, lambda_functor<Arg4> >
|
---|
| 42 | >
|
---|
| 43 | >
|
---|
| 44 | for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
|
---|
| 45 | const lambda_functor<Arg3>& a3, const lambda_functor<Arg4>& a4) {
|
---|
| 46 | return
|
---|
| 47 | lambda_functor_base<
|
---|
| 48 | forloop_action,
|
---|
| 49 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
|
---|
| 50 | lambda_functor<Arg3>, lambda_functor<Arg4> >
|
---|
| 51 | >
|
---|
| 52 | ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
|
---|
| 53 | lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
|
---|
| 54 | );
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | // No body case.
|
---|
| 58 | template <class Arg1, class Arg2, class Arg3>
|
---|
| 59 | inline const
|
---|
| 60 | lambda_functor<
|
---|
| 61 | lambda_functor_base<
|
---|
| 62 | forloop_no_body_action,
|
---|
| 63 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
|
---|
| 64 | >
|
---|
| 65 | >
|
---|
| 66 | for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
|
---|
| 67 | const lambda_functor<Arg3>& a3) {
|
---|
| 68 | return
|
---|
| 69 | lambda_functor_base<
|
---|
| 70 | forloop_no_body_action,
|
---|
| 71 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
|
---|
| 72 | lambda_functor<Arg3> >
|
---|
| 73 | >
|
---|
| 74 | ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
|
---|
| 75 | lambda_functor<Arg3> >(a1, a2, a3) );
|
---|
| 76 | }
|
---|
| 77 |
|
---|
| 78 | // While loop
|
---|
| 79 | template <class Arg1, class Arg2>
|
---|
| 80 | inline const
|
---|
| 81 | lambda_functor<
|
---|
| 82 | lambda_functor_base<
|
---|
| 83 | whileloop_action,
|
---|
| 84 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
|
---|
| 85 | >
|
---|
| 86 | >
|
---|
| 87 | while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
|
---|
| 88 | return
|
---|
| 89 | lambda_functor_base<
|
---|
| 90 | whileloop_action,
|
---|
| 91 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
|
---|
| 92 | >
|
---|
| 93 | ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
|
---|
| 94 | }
|
---|
| 95 |
|
---|
| 96 | // No body case.
|
---|
| 97 | template <class Arg1>
|
---|
| 98 | inline const
|
---|
| 99 | lambda_functor<
|
---|
| 100 | lambda_functor_base<
|
---|
| 101 | whileloop_no_body_action,
|
---|
| 102 | tuple<lambda_functor<Arg1> >
|
---|
| 103 | >
|
---|
| 104 | >
|
---|
| 105 | while_loop(const lambda_functor<Arg1>& a1) {
|
---|
| 106 | return
|
---|
| 107 | lambda_functor_base<
|
---|
| 108 | whileloop_no_body_action,
|
---|
| 109 | tuple<lambda_functor<Arg1> >
|
---|
| 110 | >
|
---|
| 111 | ( tuple<lambda_functor<Arg1> >(a1) );
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 |
|
---|
| 115 | // Do While loop
|
---|
| 116 | template <class Arg1, class Arg2>
|
---|
| 117 | inline const
|
---|
| 118 | lambda_functor<
|
---|
| 119 | lambda_functor_base<
|
---|
| 120 | dowhileloop_action,
|
---|
| 121 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
|
---|
| 122 | >
|
---|
| 123 | >
|
---|
| 124 | do_while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
|
---|
| 125 | return
|
---|
| 126 | lambda_functor_base<
|
---|
| 127 | dowhileloop_action,
|
---|
| 128 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
|
---|
| 129 | >
|
---|
| 130 | ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
|
---|
| 131 | }
|
---|
| 132 |
|
---|
| 133 | // No body case.
|
---|
| 134 | template <class Arg1>
|
---|
| 135 | inline const
|
---|
| 136 | lambda_functor<
|
---|
| 137 | lambda_functor_base<
|
---|
| 138 | dowhileloop_no_body_action,
|
---|
| 139 | tuple<lambda_functor<Arg1> >
|
---|
| 140 | >
|
---|
| 141 | >
|
---|
| 142 | do_while_loop(const lambda_functor<Arg1>& a1) {
|
---|
| 143 | return
|
---|
| 144 | lambda_functor_base<
|
---|
| 145 | dowhileloop_no_body_action,
|
---|
| 146 | tuple<lambda_functor<Arg1> >
|
---|
| 147 | >
|
---|
| 148 | ( tuple<lambda_functor<Arg1> >(a1));
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 |
|
---|
| 152 | // If Then
|
---|
| 153 | template <class Arg1, class Arg2>
|
---|
| 154 | inline const
|
---|
| 155 | lambda_functor<
|
---|
| 156 | lambda_functor_base<
|
---|
| 157 | ifthen_action,
|
---|
| 158 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
|
---|
| 159 | >
|
---|
| 160 | >
|
---|
| 161 | if_then(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
|
---|
| 162 | return
|
---|
| 163 | lambda_functor_base<
|
---|
| 164 | ifthen_action,
|
---|
| 165 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
|
---|
| 166 | >
|
---|
| 167 | ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2) );
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | // If then else
|
---|
| 171 |
|
---|
| 172 | template <class Arg1, class Arg2, class Arg3>
|
---|
| 173 | inline const
|
---|
| 174 | lambda_functor<
|
---|
| 175 | lambda_functor_base<
|
---|
| 176 | ifthenelse_action,
|
---|
| 177 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
|
---|
| 178 | >
|
---|
| 179 | >
|
---|
| 180 | if_then_else(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
|
---|
| 181 | const lambda_functor<Arg3>& a3) {
|
---|
| 182 | return
|
---|
| 183 | lambda_functor_base<
|
---|
| 184 | ifthenelse_action,
|
---|
| 185 | tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
|
---|
| 186 | >
|
---|
| 187 | (tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
|
---|
| 188 | (a1, a2, a3) );
|
---|
| 189 | }
|
---|
| 190 |
|
---|
| 191 | // Our version of operator?:()
|
---|
| 192 |
|
---|
| 193 | template <class Arg1, class Arg2, class Arg3>
|
---|
| 194 | inline const
|
---|
| 195 | lambda_functor<
|
---|
| 196 | lambda_functor_base<
|
---|
| 197 | other_action<ifthenelsereturn_action>,
|
---|
| 198 | tuple<lambda_functor<Arg1>,
|
---|
| 199 | typename const_copy_argument<Arg2>::type,
|
---|
| 200 | typename const_copy_argument<Arg3>::type>
|
---|
| 201 | >
|
---|
| 202 | >
|
---|
| 203 | if_then_else_return(const lambda_functor<Arg1>& a1,
|
---|
| 204 | const Arg2 & a2,
|
---|
| 205 | const Arg3 & a3) {
|
---|
| 206 | return
|
---|
| 207 | lambda_functor_base<
|
---|
| 208 | other_action<ifthenelsereturn_action>,
|
---|
| 209 | tuple<lambda_functor<Arg1>,
|
---|
| 210 | typename const_copy_argument<Arg2>::type,
|
---|
| 211 | typename const_copy_argument<Arg3>::type>
|
---|
| 212 | > ( tuple<lambda_functor<Arg1>,
|
---|
| 213 | typename const_copy_argument<Arg2>::type,
|
---|
| 214 | typename const_copy_argument<Arg3>::type> (a1, a2, a3) );
|
---|
| 215 | }
|
---|
| 216 |
|
---|
| 217 | namespace detail {
|
---|
| 218 |
|
---|
| 219 | // return type specialization for conditional expression begins -----------
|
---|
| 220 | // start reading below and move upwards
|
---|
| 221 |
|
---|
| 222 | // PHASE 6:1
|
---|
| 223 | // check if A is conbertible to B and B to A
|
---|
| 224 | template<int Phase, bool AtoB, bool BtoA, bool SameType, class A, class B>
|
---|
| 225 | struct return_type_2_ifthenelsereturn;
|
---|
| 226 |
|
---|
| 227 | // if A can be converted to B and vice versa -> ambiguous
|
---|
| 228 | template<int Phase, class A, class B>
|
---|
| 229 | struct return_type_2_ifthenelsereturn<Phase, true, true, false, A, B> {
|
---|
| 230 | typedef
|
---|
| 231 | detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
|
---|
| 232 | // ambiguous type in conditional expression
|
---|
| 233 | };
|
---|
| 234 | // if A can be converted to B and vice versa and are of same type
|
---|
| 235 | template<int Phase, class A, class B>
|
---|
| 236 | struct return_type_2_ifthenelsereturn<Phase, true, true, true, A, B> {
|
---|
| 237 | typedef A type;
|
---|
| 238 | };
|
---|
| 239 |
|
---|
| 240 |
|
---|
| 241 | // A can be converted to B
|
---|
| 242 | template<int Phase, class A, class B>
|
---|
| 243 | struct return_type_2_ifthenelsereturn<Phase, true, false, false, A, B> {
|
---|
| 244 | typedef B type;
|
---|
| 245 | };
|
---|
| 246 |
|
---|
| 247 | // B can be converted to A
|
---|
| 248 | template<int Phase, class A, class B>
|
---|
| 249 | struct return_type_2_ifthenelsereturn<Phase, false, true, false, A, B> {
|
---|
| 250 | typedef A type;
|
---|
| 251 | };
|
---|
| 252 |
|
---|
| 253 | // neither can be converted. Then we drop the potential references, and
|
---|
| 254 | // try again
|
---|
| 255 | template<class A, class B>
|
---|
| 256 | struct return_type_2_ifthenelsereturn<1, false, false, false, A, B> {
|
---|
| 257 | // it is safe to add const, since the result will be an rvalue and thus
|
---|
| 258 | // const anyway. The const are needed eg. if the types
|
---|
| 259 | // are 'const int*' and 'void *'. The remaining type should be 'const void*'
|
---|
| 260 | typedef const typename boost::remove_reference<A>::type plainA;
|
---|
| 261 | typedef const typename boost::remove_reference<B>::type plainB;
|
---|
| 262 | // TODO: Add support for volatile ?
|
---|
| 263 |
|
---|
| 264 | typedef typename
|
---|
| 265 | return_type_2_ifthenelsereturn<
|
---|
| 266 | 2,
|
---|
| 267 | boost::is_convertible<plainA,plainB>::value,
|
---|
| 268 | boost::is_convertible<plainB,plainA>::value,
|
---|
| 269 | boost::is_same<plainA,plainB>::value,
|
---|
| 270 | plainA,
|
---|
| 271 | plainB>::type type;
|
---|
| 272 | };
|
---|
| 273 |
|
---|
| 274 | // PHASE 6:2
|
---|
| 275 | template<class A, class B>
|
---|
| 276 | struct return_type_2_ifthenelsereturn<2, false, false, false, A, B> {
|
---|
| 277 | typedef
|
---|
| 278 | detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
|
---|
| 279 | // types_do_not_match_in_conditional_expression
|
---|
| 280 | };
|
---|
| 281 |
|
---|
| 282 |
|
---|
| 283 |
|
---|
| 284 | // PHASE 5: now we know that types are not arithmetic.
|
---|
| 285 | template<class A, class B>
|
---|
| 286 | struct non_numeric_types {
|
---|
| 287 | typedef typename
|
---|
| 288 | return_type_2_ifthenelsereturn<
|
---|
| 289 | 1, // phase 1
|
---|
| 290 | is_convertible<A,B>::value,
|
---|
| 291 | is_convertible<B,A>::value,
|
---|
| 292 | is_same<A,B>::value,
|
---|
| 293 | A,
|
---|
| 294 | B>::type type;
|
---|
| 295 | };
|
---|
| 296 |
|
---|
| 297 | // PHASE 4 :
|
---|
| 298 | // the base case covers arithmetic types with differing promote codes
|
---|
| 299 | // use the type deduction of arithmetic_actions
|
---|
| 300 | template<int CodeA, int CodeB, class A, class B>
|
---|
| 301 | struct arithmetic_or_not {
|
---|
| 302 | typedef typename
|
---|
| 303 | return_type_2<arithmetic_action<plus_action>, A, B>::type type;
|
---|
| 304 | // plus_action is just a random pick, has to be a concrete instance
|
---|
| 305 | };
|
---|
| 306 |
|
---|
| 307 | // this case covers the case of artihmetic types with the same promote codes.
|
---|
| 308 | // non numeric deduction is used since e.g. integral promotion is not
|
---|
| 309 | // performed with operator ?:
|
---|
| 310 | template<int CodeA, class A, class B>
|
---|
| 311 | struct arithmetic_or_not<CodeA, CodeA, A, B> {
|
---|
| 312 | typedef typename non_numeric_types<A, B>::type type;
|
---|
| 313 | };
|
---|
| 314 |
|
---|
| 315 | // if either A or B has promote code -1 it is not an arithmetic type
|
---|
| 316 | template<class A, class B>
|
---|
| 317 | struct arithmetic_or_not <-1, -1, A, B> {
|
---|
| 318 | typedef typename non_numeric_types<A, B>::type type;
|
---|
| 319 | };
|
---|
| 320 | template<int CodeB, class A, class B>
|
---|
| 321 | struct arithmetic_or_not <-1, CodeB, A, B> {
|
---|
| 322 | typedef typename non_numeric_types<A, B>::type type;
|
---|
| 323 | };
|
---|
| 324 | template<int CodeA, class A, class B>
|
---|
| 325 | struct arithmetic_or_not <CodeA, -1, A, B> {
|
---|
| 326 | typedef typename non_numeric_types<A, B>::type type;
|
---|
| 327 | };
|
---|
| 328 |
|
---|
| 329 |
|
---|
| 330 |
|
---|
| 331 |
|
---|
| 332 | // PHASE 3 : Are the types same?
|
---|
| 333 | // No, check if they are arithmetic or not
|
---|
| 334 | template <class A, class B>
|
---|
| 335 | struct same_or_not {
|
---|
| 336 | typedef typename detail::remove_reference_and_cv<A>::type plainA;
|
---|
| 337 | typedef typename detail::remove_reference_and_cv<B>::type plainB;
|
---|
| 338 |
|
---|
| 339 | typedef typename
|
---|
| 340 | arithmetic_or_not<
|
---|
| 341 | detail::promote_code<plainA>::value,
|
---|
| 342 | detail::promote_code<plainB>::value,
|
---|
| 343 | A,
|
---|
| 344 | B>::type type;
|
---|
| 345 | };
|
---|
| 346 | // Yes, clear.
|
---|
| 347 | template <class A> struct same_or_not<A, A> {
|
---|
| 348 | typedef A type;
|
---|
| 349 | };
|
---|
| 350 |
|
---|
| 351 | } // detail
|
---|
| 352 |
|
---|
| 353 | // PHASE 2 : Perform first the potential array_to_pointer conversion
|
---|
| 354 | template<class A, class B>
|
---|
| 355 | struct return_type_2<other_action<ifthenelsereturn_action>, A, B> {
|
---|
| 356 |
|
---|
| 357 | typedef typename detail::array_to_pointer<A>::type A1;
|
---|
| 358 | typedef typename detail::array_to_pointer<B>::type B1;
|
---|
| 359 |
|
---|
| 360 | typedef typename
|
---|
| 361 | boost::add_const<typename detail::same_or_not<A1, B1>::type>::type type;
|
---|
| 362 | };
|
---|
| 363 |
|
---|
| 364 | // PHASE 1 : Deduction is based on the second and third operand
|
---|
| 365 |
|
---|
| 366 |
|
---|
| 367 | // return type specialization for conditional expression ends -----------
|
---|
| 368 |
|
---|
| 369 |
|
---|
| 370 |
|
---|
| 371 |
|
---|
| 372 | // Control loop lambda_functor_base specializations.
|
---|
| 373 |
|
---|
| 374 | // Specialization for for_loop.
|
---|
| 375 | template<class Args>
|
---|
| 376 | class
|
---|
| 377 | lambda_functor_base<forloop_action, Args> {
|
---|
| 378 | public:
|
---|
| 379 | Args args;
|
---|
| 380 | template <class T> struct sig { typedef void type; };
|
---|
| 381 | public:
|
---|
| 382 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 383 |
|
---|
| 384 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 385 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 386 | for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
|
---|
| 387 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
| 388 | detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS))
|
---|
| 389 |
|
---|
| 390 | detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS);
|
---|
| 391 | }
|
---|
| 392 | };
|
---|
| 393 |
|
---|
| 394 | // No body case
|
---|
| 395 | template<class Args>
|
---|
| 396 | class
|
---|
| 397 | lambda_functor_base<forloop_no_body_action, Args> {
|
---|
| 398 | public:
|
---|
| 399 | Args args;
|
---|
| 400 | template <class T> struct sig { typedef void type; };
|
---|
| 401 | public:
|
---|
| 402 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 403 |
|
---|
| 404 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 405 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 406 | for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
|
---|
| 407 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
| 408 | detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {}
|
---|
| 409 | }
|
---|
| 410 | };
|
---|
| 411 |
|
---|
| 412 |
|
---|
| 413 | // Specialization for while_loop.
|
---|
| 414 | template<class Args>
|
---|
| 415 | class
|
---|
| 416 | lambda_functor_base<whileloop_action, Args> {
|
---|
| 417 | public:
|
---|
| 418 | Args args;
|
---|
| 419 | template <class T> struct sig { typedef void type; };
|
---|
| 420 | public:
|
---|
| 421 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 422 |
|
---|
| 423 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 424 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 425 | while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
|
---|
| 426 |
|
---|
| 427 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
| 428 | }
|
---|
| 429 | };
|
---|
| 430 |
|
---|
| 431 | // No body case
|
---|
| 432 | template<class Args>
|
---|
| 433 | class
|
---|
| 434 | lambda_functor_base<whileloop_no_body_action, Args> {
|
---|
| 435 | public:
|
---|
| 436 | Args args;
|
---|
| 437 | template <class T> struct sig { typedef void type; };
|
---|
| 438 | public:
|
---|
| 439 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 440 |
|
---|
| 441 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 442 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 443 | while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {}
|
---|
| 444 | }
|
---|
| 445 | };
|
---|
| 446 |
|
---|
| 447 | // Specialization for do_while_loop.
|
---|
| 448 | // Note that the first argument is the condition.
|
---|
| 449 | template<class Args>
|
---|
| 450 | class
|
---|
| 451 | lambda_functor_base<dowhileloop_action, Args> {
|
---|
| 452 | public:
|
---|
| 453 | Args args;
|
---|
| 454 | template <class T> struct sig { typedef void type; };
|
---|
| 455 | public:
|
---|
| 456 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 457 |
|
---|
| 458 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 459 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 460 | do {
|
---|
| 461 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
| 462 | } while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
|
---|
| 463 | }
|
---|
| 464 | };
|
---|
| 465 |
|
---|
| 466 | // No body case
|
---|
| 467 | template<class Args>
|
---|
| 468 | class
|
---|
| 469 | lambda_functor_base<dowhileloop_no_body_action, Args> {
|
---|
| 470 | public:
|
---|
| 471 | Args args;
|
---|
| 472 | template <class T> struct sig { typedef void type; };
|
---|
| 473 | public:
|
---|
| 474 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 475 |
|
---|
| 476 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 477 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 478 | do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
|
---|
| 479 | }
|
---|
| 480 | };
|
---|
| 481 |
|
---|
| 482 |
|
---|
| 483 | // Specialization for if_then.
|
---|
| 484 | template<class Args>
|
---|
| 485 | class
|
---|
| 486 | lambda_functor_base<ifthen_action, Args> {
|
---|
| 487 | public:
|
---|
| 488 | Args args;
|
---|
| 489 | template <class T> struct sig { typedef void type; };
|
---|
| 490 | public:
|
---|
| 491 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 492 |
|
---|
| 493 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 494 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 495 | if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
| 496 | }
|
---|
| 497 | };
|
---|
| 498 |
|
---|
| 499 | // Specialization for if_then_else.
|
---|
| 500 | template<class Args>
|
---|
| 501 | class
|
---|
| 502 | lambda_functor_base<ifthenelse_action, Args> {
|
---|
| 503 | public:
|
---|
| 504 | Args args;
|
---|
| 505 | template <class T> struct sig { typedef void type; };
|
---|
| 506 | public:
|
---|
| 507 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 508 |
|
---|
| 509 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 510 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 511 | if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
|
---|
| 512 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
| 513 | else
|
---|
| 514 | detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
|
---|
| 515 | }
|
---|
| 516 | };
|
---|
| 517 |
|
---|
| 518 | // Specialization of lambda_functor_base for if_then_else_return.
|
---|
| 519 | template<class Args>
|
---|
| 520 | class
|
---|
| 521 | lambda_functor_base<other_action<ifthenelsereturn_action>, Args> {
|
---|
| 522 | public:
|
---|
| 523 | Args args;
|
---|
| 524 |
|
---|
| 525 | template <class SigArgs> struct sig {
|
---|
| 526 | private:
|
---|
| 527 | typedef typename detail::nth_return_type_sig<1, Args, SigArgs>::type ret1;
|
---|
| 528 | typedef typename detail::nth_return_type_sig<2, Args, SigArgs>::type ret2;
|
---|
| 529 | public:
|
---|
| 530 | typedef typename return_type_2<
|
---|
| 531 | other_action<ifthenelsereturn_action>, ret1, ret2
|
---|
| 532 | >::type type;
|
---|
| 533 | };
|
---|
| 534 |
|
---|
| 535 | public:
|
---|
| 536 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
| 537 |
|
---|
| 538 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
| 539 | RET call(CALL_FORMAL_ARGS) const {
|
---|
| 540 | return (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) ?
|
---|
| 541 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)
|
---|
| 542 | :
|
---|
| 543 | detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
|
---|
| 544 | }
|
---|
| 545 | };
|
---|
| 546 |
|
---|
| 547 | } // lambda
|
---|
| 548 | } // boost
|
---|
| 549 |
|
---|
| 550 | #endif // BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP
|
---|