File indexing completed on 2025-01-18 09:39:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #if !defined(BOOST_LAMBDA_IF_HPP)
0016 #define BOOST_LAMBDA_IF_HPP
0017
0018 #include "boost/lambda/core.hpp"
0019
0020
0021 #include "boost/lambda/detail/operator_actions.hpp"
0022 #include "boost/lambda/detail/operator_return_type_traits.hpp"
0023
0024 namespace boost {
0025 namespace lambda {
0026
0027
0028
0029 class ifthen_action {};
0030 class ifthenelse_action {};
0031 class ifthenelsereturn_action {};
0032
0033
0034 template<class Args>
0035 class
0036 lambda_functor_base<ifthen_action, Args> {
0037 public:
0038 Args args;
0039 template <class T> struct sig { typedef void type; };
0040 public:
0041 explicit lambda_functor_base(const Args& a) : args(a) {}
0042
0043 template<class RET, CALL_TEMPLATE_ARGS>
0044 RET call(CALL_FORMAL_ARGS) const {
0045 if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
0046 detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
0047 }
0048 };
0049
0050
0051 template <class Arg1, class Arg2>
0052 inline const
0053 lambda_functor<
0054 lambda_functor_base<
0055 ifthen_action,
0056 tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
0057 >
0058 >
0059 if_then(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
0060 return
0061 lambda_functor_base<
0062 ifthen_action,
0063 tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
0064 >
0065 ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2) );
0066 }
0067
0068
0069
0070 template<class Args>
0071 class
0072 lambda_functor_base<ifthenelse_action, Args> {
0073 public:
0074 Args args;
0075 template <class T> struct sig { typedef void type; };
0076 public:
0077 explicit lambda_functor_base(const Args& a) : args(a) {}
0078
0079 template<class RET, CALL_TEMPLATE_ARGS>
0080 RET call(CALL_FORMAL_ARGS) const {
0081 if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
0082 detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
0083 else
0084 detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
0085 }
0086 };
0087
0088
0089
0090
0091
0092 template <class Arg1, class Arg2, class Arg3>
0093 inline const
0094 lambda_functor<
0095 lambda_functor_base<
0096 ifthenelse_action,
0097 tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
0098 >
0099 >
0100 if_then_else(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
0101 const lambda_functor<Arg3>& a3) {
0102 return
0103 lambda_functor_base<
0104 ifthenelse_action,
0105 tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
0106 >
0107 (tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
0108 (a1, a2, a3) );
0109 }
0110
0111
0112
0113 template <class Arg1, class Arg2, class Arg3>
0114 inline const
0115 lambda_functor<
0116 lambda_functor_base<
0117 other_action<ifthenelsereturn_action>,
0118 tuple<lambda_functor<Arg1>,
0119 typename const_copy_argument<Arg2>::type,
0120 typename const_copy_argument<Arg3>::type>
0121 >
0122 >
0123 if_then_else_return(const lambda_functor<Arg1>& a1,
0124 const Arg2 & a2,
0125 const Arg3 & a3) {
0126 return
0127 lambda_functor_base<
0128 other_action<ifthenelsereturn_action>,
0129 tuple<lambda_functor<Arg1>,
0130 typename const_copy_argument<Arg2>::type,
0131 typename const_copy_argument<Arg3>::type>
0132 > ( tuple<lambda_functor<Arg1>,
0133 typename const_copy_argument<Arg2>::type,
0134 typename const_copy_argument<Arg3>::type> (a1, a2, a3) );
0135 }
0136
0137 namespace detail {
0138
0139
0140
0141
0142
0143
0144 template<int Phase, bool AtoB, bool BtoA, bool SameType, class A, class B>
0145 struct return_type_2_ifthenelsereturn;
0146
0147
0148 template<int Phase, class A, class B>
0149 struct return_type_2_ifthenelsereturn<Phase, true, true, false, A, B> {
0150 typedef
0151 detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
0152
0153 };
0154
0155 template<int Phase, class A, class B>
0156 struct return_type_2_ifthenelsereturn<Phase, true, true, true, A, B> {
0157 typedef A type;
0158 };
0159
0160
0161
0162 template<int Phase, class A, class B>
0163 struct return_type_2_ifthenelsereturn<Phase, true, false, false, A, B> {
0164 typedef B type;
0165 };
0166
0167
0168 template<int Phase, class A, class B>
0169 struct return_type_2_ifthenelsereturn<Phase, false, true, false, A, B> {
0170 typedef A type;
0171 };
0172
0173
0174
0175 template<class A, class B>
0176 struct return_type_2_ifthenelsereturn<1, false, false, false, A, B> {
0177
0178
0179
0180 typedef const typename boost::remove_reference<A>::type plainA;
0181 typedef const typename boost::remove_reference<B>::type plainB;
0182
0183
0184 typedef typename
0185 return_type_2_ifthenelsereturn<
0186 2,
0187 boost::is_convertible<plainA,plainB>::value,
0188 boost::is_convertible<plainB,plainA>::value,
0189 boost::is_same<plainA,plainB>::value,
0190 plainA,
0191 plainB>::type type;
0192 };
0193
0194
0195 template<class A, class B>
0196 struct return_type_2_ifthenelsereturn<2, false, false, false, A, B> {
0197 typedef
0198 detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
0199
0200 };
0201
0202
0203
0204
0205 template<class A, class B>
0206 struct non_numeric_types {
0207 typedef typename
0208 return_type_2_ifthenelsereturn<
0209 1,
0210 is_convertible<A,B>::value,
0211 is_convertible<B,A>::value,
0212 is_same<A,B>::value,
0213 A,
0214 B>::type type;
0215 };
0216
0217
0218
0219
0220 template<int CodeA, int CodeB, class A, class B>
0221 struct arithmetic_or_not {
0222 typedef typename
0223 return_type_2<arithmetic_action<plus_action>, A, B>::type type;
0224
0225 };
0226
0227
0228
0229
0230 template<int CodeA, class A, class B>
0231 struct arithmetic_or_not<CodeA, CodeA, A, B> {
0232 typedef typename non_numeric_types<A, B>::type type;
0233 };
0234
0235
0236 template<class A, class B>
0237 struct arithmetic_or_not <-1, -1, A, B> {
0238 typedef typename non_numeric_types<A, B>::type type;
0239 };
0240 template<int CodeB, class A, class B>
0241 struct arithmetic_or_not <-1, CodeB, A, B> {
0242 typedef typename non_numeric_types<A, B>::type type;
0243 };
0244 template<int CodeA, class A, class B>
0245 struct arithmetic_or_not <CodeA, -1, A, B> {
0246 typedef typename non_numeric_types<A, B>::type type;
0247 };
0248
0249
0250
0251
0252
0253
0254 template <class A, class B>
0255 struct same_or_not {
0256 typedef typename detail::remove_reference_and_cv<A>::type plainA;
0257 typedef typename detail::remove_reference_and_cv<B>::type plainB;
0258
0259 typedef typename
0260 arithmetic_or_not<
0261 detail::promote_code<plainA>::value,
0262 detail::promote_code<plainB>::value,
0263 A,
0264 B>::type type;
0265 };
0266
0267 template <class A> struct same_or_not<A, A> {
0268 typedef A type;
0269 };
0270
0271 }
0272
0273
0274 template<class A, class B>
0275 struct return_type_2<other_action<ifthenelsereturn_action>, A, B> {
0276
0277 typedef typename detail::array_to_pointer<A>::type A1;
0278 typedef typename detail::array_to_pointer<B>::type B1;
0279
0280 typedef typename
0281 boost::add_const<typename detail::same_or_not<A1, B1>::type>::type type;
0282 };
0283
0284
0285
0286
0287
0288
0289
0290
0291 template<class Args>
0292 class
0293 lambda_functor_base<other_action<ifthenelsereturn_action>, Args> {
0294 public:
0295 Args args;
0296
0297 template <class SigArgs> struct sig {
0298 private:
0299 typedef typename detail::nth_return_type_sig<1, Args, SigArgs>::type ret1;
0300 typedef typename detail::nth_return_type_sig<2, Args, SigArgs>::type ret2;
0301 public:
0302 typedef typename return_type_2<
0303 other_action<ifthenelsereturn_action>, ret1, ret2
0304 >::type type;
0305 };
0306
0307 public:
0308 explicit lambda_functor_base(const Args& a) : args(a) {}
0309
0310 template<class RET, CALL_TEMPLATE_ARGS>
0311 RET call(CALL_FORMAL_ARGS) const {
0312 return (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) ?
0313 detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)
0314 :
0315 detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
0316 }
0317 };
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352 template <typename CondT, typename ThenT, typename ElseT>
0353 struct if_then_else_composite {
0354
0355 typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
0356
0357 template <class SigArgs>
0358 struct sig { typedef void type; };
0359
0360 if_then_else_composite(
0361 CondT const& cond_,
0362 ThenT const& then_,
0363 ElseT const& else__)
0364 : cond(cond_), then(then_), else_(else__) {}
0365
0366 template <class Ret, CALL_TEMPLATE_ARGS>
0367 Ret call(CALL_FORMAL_ARGS) const
0368 {
0369 if (cond.internal_call(CALL_ACTUAL_ARGS))
0370 then.internal_call(CALL_ACTUAL_ARGS);
0371 else
0372 else_.internal_call(CALL_ACTUAL_ARGS);
0373 }
0374
0375 CondT cond; ThenT then; ElseT else_;
0376 };
0377
0378
0379 template <typename CondT, typename ThenT>
0380 struct else_gen {
0381
0382 else_gen(CondT const& cond_, ThenT const& then_)
0383 : cond(cond_), then(then_) {}
0384
0385 template <typename ElseT>
0386 lambda_functor<if_then_else_composite<CondT, ThenT,
0387 typename as_lambda_functor<ElseT>::type> >
0388 operator[](ElseT const& else_)
0389 {
0390 typedef if_then_else_composite<CondT, ThenT,
0391 typename as_lambda_functor<ElseT>::type>
0392 result;
0393
0394 return result(cond, then, to_lambda_functor(else_));
0395 }
0396
0397 CondT cond; ThenT then;
0398 };
0399
0400
0401 template <typename CondT, typename ThenT>
0402 struct if_then_composite {
0403
0404 template <class SigArgs>
0405 struct sig { typedef void type; };
0406
0407 if_then_composite(CondT const& cond_, ThenT const& then_)
0408 : cond(cond_), then(then_), else_(cond, then) {}
0409
0410 template <class Ret, CALL_TEMPLATE_ARGS>
0411 Ret call(CALL_FORMAL_ARGS) const
0412 {
0413 if (cond.internal_call(CALL_ACTUAL_ARGS))
0414 then.internal_call(CALL_ACTUAL_ARGS);
0415 }
0416
0417 CondT cond; ThenT then;
0418 else_gen<CondT, ThenT> else_;
0419 };
0420
0421
0422 template <typename CondT>
0423 struct if_gen {
0424
0425 if_gen(CondT const& cond_)
0426 : cond(cond_) {}
0427
0428 template <typename ThenT>
0429 lambda_functor<if_then_composite<
0430 typename as_lambda_functor<CondT>::type,
0431 typename as_lambda_functor<ThenT>::type> >
0432 operator[](ThenT const& then) const
0433 {
0434 typedef if_then_composite<
0435 typename as_lambda_functor<CondT>::type,
0436 typename as_lambda_functor<ThenT>::type>
0437 result;
0438
0439 return result(
0440 to_lambda_functor(cond),
0441 to_lambda_functor(then));
0442 }
0443
0444 CondT cond;
0445 };
0446
0447
0448 template <typename CondT>
0449 inline if_gen<CondT>
0450 if_(CondT const& cond)
0451 {
0452 return if_gen<CondT>(cond);
0453 }
0454
0455
0456
0457 }
0458 }
0459
0460 #endif
0461
0462