os/ossrv/ossrv_pub/boost_apis/boost/lambda/if.hpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/lambda/if.hpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,462 @@
     1.4 +// Boost Lambda Library -- if.hpp ------------------------------------------
     1.5 +
     1.6 +// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
     1.7 +// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
     1.8 +// Copyright (C) 2001-2002 Joel de Guzman
     1.9 +//
    1.10 +// Distributed under the Boost Software License, Version 1.0. (See
    1.11 +// accompanying file LICENSE_1_0.txt or copy at
    1.12 +// http://www.boost.org/LICENSE_1_0.txt)
    1.13 +//
    1.14 +// For more information, see www.boost.org
    1.15 +
    1.16 +// --------------------------------------------------------------------------
    1.17 +
    1.18 +#if !defined(BOOST_LAMBDA_IF_HPP)
    1.19 +#define BOOST_LAMBDA_IF_HPP
    1.20 +
    1.21 +#include "boost/lambda/core.hpp"
    1.22 +
    1.23 +// Arithmetic type promotion needed for if_then_else_return
    1.24 +#include "boost/lambda/detail/operator_actions.hpp"
    1.25 +#include "boost/lambda/detail/operator_return_type_traits.hpp"
    1.26 +
    1.27 +namespace boost { 
    1.28 +namespace lambda {
    1.29 +
    1.30 +// -- if control construct actions ----------------------
    1.31 +
    1.32 +class ifthen_action {};
    1.33 +class ifthenelse_action {};
    1.34 +class ifthenelsereturn_action {};
    1.35 +
    1.36 +// Specialization for if_then.
    1.37 +template<class Args>
    1.38 +class 
    1.39 +lambda_functor_base<ifthen_action, Args> {
    1.40 +public:
    1.41 +  Args args;
    1.42 +  template <class T> struct sig { typedef void type; };
    1.43 +public:
    1.44 +  explicit lambda_functor_base(const Args& a) : args(a) {}
    1.45 +
    1.46 +  template<class RET, CALL_TEMPLATE_ARGS>
    1.47 +  RET call(CALL_FORMAL_ARGS) const {
    1.48 +    if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) 
    1.49 +      detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); 
    1.50 +  }
    1.51 +};
    1.52 +
    1.53 +// If Then
    1.54 +template <class Arg1, class Arg2>
    1.55 +inline const 
    1.56 +lambda_functor<
    1.57 +  lambda_functor_base<
    1.58 +    ifthen_action, 
    1.59 +    tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
    1.60 +  > 
    1.61 +>
    1.62 +if_then(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
    1.63 +  return 
    1.64 +    lambda_functor_base<
    1.65 +      ifthen_action, 
    1.66 +      tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > 
    1.67 +    > 
    1.68 +    ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2) );
    1.69 +}
    1.70 +
    1.71 +
    1.72 +// Specialization for if_then_else.
    1.73 +template<class Args>
    1.74 +class 
    1.75 +lambda_functor_base<ifthenelse_action, Args> {
    1.76 +public:
    1.77 +  Args args;
    1.78 +  template <class T> struct sig { typedef void type; };
    1.79 +public:
    1.80 +  explicit lambda_functor_base(const Args& a) : args(a) {}
    1.81 +
    1.82 +  template<class RET, CALL_TEMPLATE_ARGS>
    1.83 +  RET call(CALL_FORMAL_ARGS) const {
    1.84 +    if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) 
    1.85 +      detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); 
    1.86 +    else 
    1.87 +      detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
    1.88 +  }
    1.89 +};
    1.90 +
    1.91 +
    1.92 +
    1.93 +// If then else
    1.94 +
    1.95 +template <class Arg1, class Arg2, class Arg3>
    1.96 +inline const 
    1.97 +lambda_functor<
    1.98 +  lambda_functor_base<
    1.99 +    ifthenelse_action, 
   1.100 +    tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
   1.101 +  > 
   1.102 +>
   1.103 +if_then_else(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2, 
   1.104 +             const lambda_functor<Arg3>& a3) {
   1.105 +  return 
   1.106 +    lambda_functor_base<
   1.107 +      ifthenelse_action, 
   1.108 +      tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
   1.109 +    > 
   1.110 +    (tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
   1.111 +       (a1, a2, a3) );
   1.112 +}
   1.113 +
   1.114 +// Our version of operator?:()
   1.115 +
   1.116 +template <class Arg1, class Arg2, class Arg3>
   1.117 +inline const 
   1.118 +  lambda_functor<
   1.119 +    lambda_functor_base<
   1.120 +      other_action<ifthenelsereturn_action>, 
   1.121 +      tuple<lambda_functor<Arg1>,
   1.122 +          typename const_copy_argument<Arg2>::type,
   1.123 +          typename const_copy_argument<Arg3>::type>
   1.124 +  > 
   1.125 +>
   1.126 +if_then_else_return(const lambda_functor<Arg1>& a1, 
   1.127 +                    const Arg2 & a2, 
   1.128 +                    const Arg3 & a3) {
   1.129 +  return 
   1.130 +      lambda_functor_base<
   1.131 +        other_action<ifthenelsereturn_action>, 
   1.132 +        tuple<lambda_functor<Arg1>,
   1.133 +              typename const_copy_argument<Arg2>::type,
   1.134 +              typename const_copy_argument<Arg3>::type>
   1.135 +      > ( tuple<lambda_functor<Arg1>,
   1.136 +              typename const_copy_argument<Arg2>::type,
   1.137 +              typename const_copy_argument<Arg3>::type> (a1, a2, a3) );
   1.138 +}
   1.139 +
   1.140 +namespace detail {
   1.141 +
   1.142 +// return type specialization for conditional expression begins -----------
   1.143 +// start reading below and move upwards
   1.144 +
   1.145 +// PHASE 6:1 
   1.146 +// check if A is conbertible to B and B to A
   1.147 +template<int Phase, bool AtoB, bool BtoA, bool SameType, class A, class B>
   1.148 +struct return_type_2_ifthenelsereturn;
   1.149 +
   1.150 +// if A can be converted to B and vice versa -> ambiguous
   1.151 +template<int Phase, class A, class B>
   1.152 +struct return_type_2_ifthenelsereturn<Phase, true, true, false, A, B> {
   1.153 +  typedef 
   1.154 +    detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
   1.155 +  // ambiguous type in conditional expression
   1.156 +};
   1.157 +// if A can be converted to B and vice versa and are of same type
   1.158 +template<int Phase, class A, class B>
   1.159 +struct return_type_2_ifthenelsereturn<Phase, true, true, true, A, B> {
   1.160 +  typedef A type;
   1.161 +};
   1.162 +
   1.163 +
   1.164 +// A can be converted to B
   1.165 +template<int Phase, class A, class B>
   1.166 +struct return_type_2_ifthenelsereturn<Phase, true, false, false, A, B> {
   1.167 +  typedef B type;
   1.168 +};
   1.169 +
   1.170 +// B can be converted to A
   1.171 +template<int Phase, class A, class B>
   1.172 +struct return_type_2_ifthenelsereturn<Phase, false, true, false, A, B> {
   1.173 +  typedef A type;
   1.174 +};
   1.175 +
   1.176 +// neither can be converted. Then we drop the potential references, and
   1.177 +// try again
   1.178 +template<class A, class B>
   1.179 +struct return_type_2_ifthenelsereturn<1, false, false, false, A, B> {
   1.180 +  // it is safe to add const, since the result will be an rvalue and thus
   1.181 +  // const anyway. The const are needed eg. if the types 
   1.182 +  // are 'const int*' and 'void *'. The remaining type should be 'const void*'
   1.183 +  typedef const typename boost::remove_reference<A>::type plainA; 
   1.184 +  typedef const typename boost::remove_reference<B>::type plainB; 
   1.185 +  // TODO: Add support for volatile ?
   1.186 +
   1.187 +  typedef typename
   1.188 +       return_type_2_ifthenelsereturn<
   1.189 +         2,
   1.190 +         boost::is_convertible<plainA,plainB>::value, 
   1.191 +         boost::is_convertible<plainB,plainA>::value,
   1.192 +         boost::is_same<plainA,plainB>::value,
   1.193 +         plainA, 
   1.194 +         plainB>::type type;
   1.195 +};
   1.196 +
   1.197 +// PHASE 6:2
   1.198 +template<class A, class B>
   1.199 +struct return_type_2_ifthenelsereturn<2, false, false, false, A, B> {
   1.200 +  typedef 
   1.201 +    detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
   1.202 +  // types_do_not_match_in_conditional_expression 
   1.203 +};
   1.204 +
   1.205 +
   1.206 +
   1.207 +// PHASE 5: now we know that types are not arithmetic.
   1.208 +template<class A, class B>
   1.209 +struct non_numeric_types {
   1.210 +  typedef typename 
   1.211 +    return_type_2_ifthenelsereturn<
   1.212 +      1, // phase 1 
   1.213 +      is_convertible<A,B>::value, 
   1.214 +      is_convertible<B,A>::value, 
   1.215 +      is_same<A,B>::value,
   1.216 +      A, 
   1.217 +      B>::type type;
   1.218 +};
   1.219 +
   1.220 +// PHASE 4 : 
   1.221 +// the base case covers arithmetic types with differing promote codes
   1.222 +// use the type deduction of arithmetic_actions
   1.223 +template<int CodeA, int CodeB, class A, class B>
   1.224 +struct arithmetic_or_not {
   1.225 +  typedef typename
   1.226 +    return_type_2<arithmetic_action<plus_action>, A, B>::type type; 
   1.227 +  // plus_action is just a random pick, has to be a concrete instance
   1.228 +};
   1.229 +
   1.230 +// this case covers the case of artihmetic types with the same promote codes. 
   1.231 +// non numeric deduction is used since e.g. integral promotion is not 
   1.232 +// performed with operator ?: 
   1.233 +template<int CodeA, class A, class B>
   1.234 +struct arithmetic_or_not<CodeA, CodeA, A, B> {
   1.235 +  typedef typename non_numeric_types<A, B>::type type; 
   1.236 +};
   1.237 +
   1.238 +// if either A or B has promote code -1 it is not an arithmetic type
   1.239 +template<class A, class B>
   1.240 +struct arithmetic_or_not <-1, -1, A, B> {
   1.241 +  typedef typename non_numeric_types<A, B>::type type;
   1.242 +};
   1.243 +template<int CodeB, class A, class B>
   1.244 +struct arithmetic_or_not <-1, CodeB, A, B> {
   1.245 +  typedef typename non_numeric_types<A, B>::type type;
   1.246 +};
   1.247 +template<int CodeA, class A, class B>
   1.248 +struct arithmetic_or_not <CodeA, -1, A, B> {
   1.249 +  typedef typename non_numeric_types<A, B>::type type;
   1.250 +};
   1.251 +
   1.252 +
   1.253 +
   1.254 +
   1.255 +// PHASE 3 : Are the types same?
   1.256 +// No, check if they are arithmetic or not
   1.257 +template <class A, class B>
   1.258 +struct same_or_not {
   1.259 +  typedef typename detail::remove_reference_and_cv<A>::type plainA;
   1.260 +  typedef typename detail::remove_reference_and_cv<B>::type plainB;
   1.261 +
   1.262 +  typedef typename 
   1.263 +    arithmetic_or_not<
   1.264 +      detail::promote_code<plainA>::value, 
   1.265 +      detail::promote_code<plainB>::value, 
   1.266 +      A, 
   1.267 +      B>::type type;
   1.268 +};
   1.269 +// Yes, clear.
   1.270 +template <class A> struct same_or_not<A, A> {
   1.271 +  typedef A type;
   1.272 +};
   1.273 +
   1.274 +} // detail
   1.275 +
   1.276 +// PHASE 2 : Perform first the potential array_to_pointer conversion 
   1.277 +template<class A, class B>
   1.278 +struct return_type_2<other_action<ifthenelsereturn_action>, A, B> { 
   1.279 +
   1.280 +  typedef typename detail::array_to_pointer<A>::type A1;
   1.281 +  typedef typename detail::array_to_pointer<B>::type B1;
   1.282 +
   1.283 +  typedef typename 
   1.284 +    boost::add_const<typename detail::same_or_not<A1, B1>::type>::type type;
   1.285 +};
   1.286 +
   1.287 +// PHASE 1 : Deduction is based on the second and third operand
   1.288 +
   1.289 +
   1.290 +// return type specialization for conditional expression ends -----------
   1.291 +
   1.292 +
   1.293 +// Specialization of lambda_functor_base for if_then_else_return.
   1.294 +template<class Args>
   1.295 +class 
   1.296 +lambda_functor_base<other_action<ifthenelsereturn_action>, Args> {
   1.297 +public:
   1.298 +  Args args;
   1.299 +
   1.300 +  template <class SigArgs> struct sig {
   1.301 +  private:
   1.302 +    typedef typename detail::nth_return_type_sig<1, Args, SigArgs>::type ret1;
   1.303 +    typedef typename detail::nth_return_type_sig<2, Args, SigArgs>::type ret2;
   1.304 +  public:
   1.305 +    typedef typename return_type_2<
   1.306 +      other_action<ifthenelsereturn_action>, ret1, ret2
   1.307 +    >::type type;
   1.308 +  };
   1.309 +
   1.310 +public:
   1.311 +  explicit lambda_functor_base(const Args& a) : args(a) {}
   1.312 +
   1.313 +  template<class RET, CALL_TEMPLATE_ARGS>
   1.314 +  RET call(CALL_FORMAL_ARGS) const {
   1.315 +    return (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) ?
   1.316 +       detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS) 
   1.317 +    : 
   1.318 +       detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
   1.319 +  }
   1.320 +};
   1.321 +
   1.322 +  // The code below is from Joel de Guzman, some name changes etc. 
   1.323 +  // has been made.
   1.324 +
   1.325 +///////////////////////////////////////////////////////////////////////////////
   1.326 +//
   1.327 +//  if_then_else_composite
   1.328 +//
   1.329 +//      This composite has two (2) forms:
   1.330 +//
   1.331 +//          if_(condition)
   1.332 +//          [
   1.333 +//              statement
   1.334 +//          ]
   1.335 +//
   1.336 +//      and
   1.337 +//
   1.338 +//          if_(condition)
   1.339 +//          [
   1.340 +//              true_statement
   1.341 +//          ]
   1.342 +//          .else_
   1.343 +//          [
   1.344 +//              false_statement
   1.345 +//          ]
   1.346 +//
   1.347 +//      where condition is an lambda_functor that evaluates to bool. If condition
   1.348 +//      is true, the true_statement (again an lambda_functor) is executed
   1.349 +//      otherwise, the false_statement (another lambda_functor) is executed. The
   1.350 +//      result type of this is void. Note the trailing underscore after
   1.351 +//      if_ and the the leading dot and the trailing underscore before
   1.352 +//      and after .else_.
   1.353 +//
   1.354 +///////////////////////////////////////////////////////////////////////////////
   1.355 +template <typename CondT, typename ThenT, typename ElseT>
   1.356 +struct if_then_else_composite {
   1.357 +
   1.358 +    typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
   1.359 +
   1.360 +    template <class SigArgs>
   1.361 +    struct sig { typedef void type; };
   1.362 +
   1.363 +    if_then_else_composite(
   1.364 +        CondT const& cond_,
   1.365 +        ThenT const& then_,
   1.366 +        ElseT const& else__)
   1.367 +    :   cond(cond_), then(then_), else_(else__) {}
   1.368 +
   1.369 +    template <class Ret, CALL_TEMPLATE_ARGS>
   1.370 +    Ret call(CALL_FORMAL_ARGS) const
   1.371 +    {
   1.372 +        if (cond.internal_call(CALL_ACTUAL_ARGS))
   1.373 +            then.internal_call(CALL_ACTUAL_ARGS);
   1.374 +        else
   1.375 +            else_.internal_call(CALL_ACTUAL_ARGS);
   1.376 +    }
   1.377 +
   1.378 +    CondT cond; ThenT then; ElseT else_; //  lambda_functors
   1.379 +};
   1.380 +
   1.381 +//////////////////////////////////
   1.382 +template <typename CondT, typename ThenT>
   1.383 +struct else_gen {
   1.384 +
   1.385 +    else_gen(CondT const& cond_, ThenT const& then_)
   1.386 +    :   cond(cond_), then(then_) {}
   1.387 +
   1.388 +    template <typename ElseT>
   1.389 +    lambda_functor<if_then_else_composite<CondT, ThenT,
   1.390 +        typename as_lambda_functor<ElseT>::type> >
   1.391 +    operator[](ElseT const& else_)
   1.392 +    {
   1.393 +        typedef if_then_else_composite<CondT, ThenT,
   1.394 +            typename as_lambda_functor<ElseT>::type>
   1.395 +        result;
   1.396 +
   1.397 +        return result(cond, then, to_lambda_functor(else_));
   1.398 +    }
   1.399 +
   1.400 +    CondT cond; ThenT then;
   1.401 +};
   1.402 +
   1.403 +//////////////////////////////////
   1.404 +template <typename CondT, typename ThenT>
   1.405 +struct if_then_composite {
   1.406 +
   1.407 +    template <class SigArgs>
   1.408 +    struct sig { typedef void type; };
   1.409 +
   1.410 +    if_then_composite(CondT const& cond_, ThenT const& then_)
   1.411 +    :   cond(cond_), then(then_), else_(cond, then) {}
   1.412 +
   1.413 +    template <class Ret, CALL_TEMPLATE_ARGS>
   1.414 +    Ret call(CALL_FORMAL_ARGS) const
   1.415 +    {
   1.416 +      if (cond.internal_call(CALL_ACTUAL_ARGS))
   1.417 +            then.internal_call(CALL_ACTUAL_ARGS);
   1.418 +    }
   1.419 +
   1.420 +    CondT cond; ThenT then; //  lambda_functors
   1.421 +    else_gen<CondT, ThenT> else_;
   1.422 +};
   1.423 +
   1.424 +//////////////////////////////////
   1.425 +template <typename CondT>
   1.426 +struct if_gen {
   1.427 +
   1.428 +    if_gen(CondT const& cond_)
   1.429 +    :   cond(cond_) {}
   1.430 +
   1.431 +    template <typename ThenT>
   1.432 +    lambda_functor<if_then_composite<
   1.433 +        typename as_lambda_functor<CondT>::type,
   1.434 +        typename as_lambda_functor<ThenT>::type> >
   1.435 +    operator[](ThenT const& then) const
   1.436 +    {
   1.437 +        typedef if_then_composite<
   1.438 +            typename as_lambda_functor<CondT>::type,
   1.439 +            typename as_lambda_functor<ThenT>::type>
   1.440 +        result;
   1.441 +
   1.442 +        return result(
   1.443 +            to_lambda_functor(cond),
   1.444 +            to_lambda_functor(then));
   1.445 +    }
   1.446 +
   1.447 +    CondT cond;
   1.448 +};
   1.449 +
   1.450 +//////////////////////////////////
   1.451 +template <typename CondT>
   1.452 +inline if_gen<CondT>
   1.453 +if_(CondT const& cond)
   1.454 +{
   1.455 +    return if_gen<CondT>(cond);
   1.456 +}
   1.457 +
   1.458 +
   1.459 +
   1.460 +} // lambda
   1.461 +} // boost
   1.462 +
   1.463 +#endif // BOOST_LAMBDA_IF_HPP
   1.464 +
   1.465 +