ossrv_pub/boost_apis/boost/lambda/if.hpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ossrv_pub/boost_apis/boost/lambda/if.hpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,462 @@
+// Boost Lambda Library -- if.hpp ------------------------------------------
+
+// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
+// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
+// Copyright (C) 2001-2002 Joel de Guzman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see www.boost.org
+
+// --------------------------------------------------------------------------
+
+#if !defined(BOOST_LAMBDA_IF_HPP)
+#define BOOST_LAMBDA_IF_HPP
+
+#include "boost/lambda/core.hpp"
+
+// Arithmetic type promotion needed for if_then_else_return
+#include "boost/lambda/detail/operator_actions.hpp"
+#include "boost/lambda/detail/operator_return_type_traits.hpp"
+
+namespace boost { 
+namespace lambda {
+
+// -- if control construct actions ----------------------
+
+class ifthen_action {};
+class ifthenelse_action {};
+class ifthenelsereturn_action {};
+
+// Specialization for if_then.
+template<class Args>
+class 
+lambda_functor_base<ifthen_action, Args> {
+public:
+  Args args;
+  template <class T> struct sig { typedef void type; };
+public:
+  explicit lambda_functor_base(const Args& a) : args(a) {}
+
+  template<class RET, CALL_TEMPLATE_ARGS>
+  RET call(CALL_FORMAL_ARGS) const {
+    if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) 
+      detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); 
+  }
+};
+
+// If Then
+template <class Arg1, class Arg2>
+inline const 
+lambda_functor<
+  lambda_functor_base<
+    ifthen_action, 
+    tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
+  > 
+>
+if_then(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
+  return 
+    lambda_functor_base<
+      ifthen_action, 
+      tuple<lambda_functor<Arg1>, lambda_functor<Arg2> > 
+    > 
+    ( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2) );
+}
+
+
+// Specialization for if_then_else.
+template<class Args>
+class 
+lambda_functor_base<ifthenelse_action, Args> {
+public:
+  Args args;
+  template <class T> struct sig { typedef void type; };
+public:
+  explicit lambda_functor_base(const Args& a) : args(a) {}
+
+  template<class RET, CALL_TEMPLATE_ARGS>
+  RET call(CALL_FORMAL_ARGS) const {
+    if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) 
+      detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); 
+    else 
+      detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
+  }
+};
+
+
+
+// If then else
+
+template <class Arg1, class Arg2, class Arg3>
+inline const 
+lambda_functor<
+  lambda_functor_base<
+    ifthenelse_action, 
+    tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
+  > 
+>
+if_then_else(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2, 
+             const lambda_functor<Arg3>& a3) {
+  return 
+    lambda_functor_base<
+      ifthenelse_action, 
+      tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
+    > 
+    (tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
+       (a1, a2, a3) );
+}
+
+// Our version of operator?:()
+
+template <class Arg1, class Arg2, class Arg3>
+inline const 
+  lambda_functor<
+    lambda_functor_base<
+      other_action<ifthenelsereturn_action>, 
+      tuple<lambda_functor<Arg1>,
+          typename const_copy_argument<Arg2>::type,
+          typename const_copy_argument<Arg3>::type>
+  > 
+>
+if_then_else_return(const lambda_functor<Arg1>& a1, 
+                    const Arg2 & a2, 
+                    const Arg3 & a3) {
+  return 
+      lambda_functor_base<
+        other_action<ifthenelsereturn_action>, 
+        tuple<lambda_functor<Arg1>,
+              typename const_copy_argument<Arg2>::type,
+              typename const_copy_argument<Arg3>::type>
+      > ( tuple<lambda_functor<Arg1>,
+              typename const_copy_argument<Arg2>::type,
+              typename const_copy_argument<Arg3>::type> (a1, a2, a3) );
+}
+
+namespace detail {
+
+// return type specialization for conditional expression begins -----------
+// start reading below and move upwards
+
+// PHASE 6:1 
+// check if A is conbertible to B and B to A
+template<int Phase, bool AtoB, bool BtoA, bool SameType, class A, class B>
+struct return_type_2_ifthenelsereturn;
+
+// if A can be converted to B and vice versa -> ambiguous
+template<int Phase, class A, class B>
+struct return_type_2_ifthenelsereturn<Phase, true, true, false, A, B> {
+  typedef 
+    detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
+  // ambiguous type in conditional expression
+};
+// if A can be converted to B and vice versa and are of same type
+template<int Phase, class A, class B>
+struct return_type_2_ifthenelsereturn<Phase, true, true, true, A, B> {
+  typedef A type;
+};
+
+
+// A can be converted to B
+template<int Phase, class A, class B>
+struct return_type_2_ifthenelsereturn<Phase, true, false, false, A, B> {
+  typedef B type;
+};
+
+// B can be converted to A
+template<int Phase, class A, class B>
+struct return_type_2_ifthenelsereturn<Phase, false, true, false, A, B> {
+  typedef A type;
+};
+
+// neither can be converted. Then we drop the potential references, and
+// try again
+template<class A, class B>
+struct return_type_2_ifthenelsereturn<1, false, false, false, A, B> {
+  // it is safe to add const, since the result will be an rvalue and thus
+  // const anyway. The const are needed eg. if the types 
+  // are 'const int*' and 'void *'. The remaining type should be 'const void*'
+  typedef const typename boost::remove_reference<A>::type plainA; 
+  typedef const typename boost::remove_reference<B>::type plainB; 
+  // TODO: Add support for volatile ?
+
+  typedef typename
+       return_type_2_ifthenelsereturn<
+         2,
+         boost::is_convertible<plainA,plainB>::value, 
+         boost::is_convertible<plainB,plainA>::value,
+         boost::is_same<plainA,plainB>::value,
+         plainA, 
+         plainB>::type type;
+};
+
+// PHASE 6:2
+template<class A, class B>
+struct return_type_2_ifthenelsereturn<2, false, false, false, A, B> {
+  typedef 
+    detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
+  // types_do_not_match_in_conditional_expression 
+};
+
+
+
+// PHASE 5: now we know that types are not arithmetic.
+template<class A, class B>
+struct non_numeric_types {
+  typedef typename 
+    return_type_2_ifthenelsereturn<
+      1, // phase 1 
+      is_convertible<A,B>::value, 
+      is_convertible<B,A>::value, 
+      is_same<A,B>::value,
+      A, 
+      B>::type type;
+};
+
+// PHASE 4 : 
+// the base case covers arithmetic types with differing promote codes
+// use the type deduction of arithmetic_actions
+template<int CodeA, int CodeB, class A, class B>
+struct arithmetic_or_not {
+  typedef typename
+    return_type_2<arithmetic_action<plus_action>, A, B>::type type; 
+  // plus_action is just a random pick, has to be a concrete instance
+};
+
+// this case covers the case of artihmetic types with the same promote codes. 
+// non numeric deduction is used since e.g. integral promotion is not 
+// performed with operator ?: 
+template<int CodeA, class A, class B>
+struct arithmetic_or_not<CodeA, CodeA, A, B> {
+  typedef typename non_numeric_types<A, B>::type type; 
+};
+
+// if either A or B has promote code -1 it is not an arithmetic type
+template<class A, class B>
+struct arithmetic_or_not <-1, -1, A, B> {
+  typedef typename non_numeric_types<A, B>::type type;
+};
+template<int CodeB, class A, class B>
+struct arithmetic_or_not <-1, CodeB, A, B> {
+  typedef typename non_numeric_types<A, B>::type type;
+};
+template<int CodeA, class A, class B>
+struct arithmetic_or_not <CodeA, -1, A, B> {
+  typedef typename non_numeric_types<A, B>::type type;
+};
+
+
+
+
+// PHASE 3 : Are the types same?
+// No, check if they are arithmetic or not
+template <class A, class B>
+struct same_or_not {
+  typedef typename detail::remove_reference_and_cv<A>::type plainA;
+  typedef typename detail::remove_reference_and_cv<B>::type plainB;
+
+  typedef typename 
+    arithmetic_or_not<
+      detail::promote_code<plainA>::value, 
+      detail::promote_code<plainB>::value, 
+      A, 
+      B>::type type;
+};
+// Yes, clear.
+template <class A> struct same_or_not<A, A> {
+  typedef A type;
+};
+
+} // detail
+
+// PHASE 2 : Perform first the potential array_to_pointer conversion 
+template<class A, class B>
+struct return_type_2<other_action<ifthenelsereturn_action>, A, B> { 
+
+  typedef typename detail::array_to_pointer<A>::type A1;
+  typedef typename detail::array_to_pointer<B>::type B1;
+
+  typedef typename 
+    boost::add_const<typename detail::same_or_not<A1, B1>::type>::type type;
+};
+
+// PHASE 1 : Deduction is based on the second and third operand
+
+
+// return type specialization for conditional expression ends -----------
+
+
+// Specialization of lambda_functor_base for if_then_else_return.
+template<class Args>
+class 
+lambda_functor_base<other_action<ifthenelsereturn_action>, Args> {
+public:
+  Args args;
+
+  template <class SigArgs> struct sig {
+  private:
+    typedef typename detail::nth_return_type_sig<1, Args, SigArgs>::type ret1;
+    typedef typename detail::nth_return_type_sig<2, Args, SigArgs>::type ret2;
+  public:
+    typedef typename return_type_2<
+      other_action<ifthenelsereturn_action>, ret1, ret2
+    >::type type;
+  };
+
+public:
+  explicit lambda_functor_base(const Args& a) : args(a) {}
+
+  template<class RET, CALL_TEMPLATE_ARGS>
+  RET call(CALL_FORMAL_ARGS) const {
+    return (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) ?
+       detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS) 
+    : 
+       detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
+  }
+};
+
+  // The code below is from Joel de Guzman, some name changes etc. 
+  // has been made.
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  if_then_else_composite
+//
+//      This composite has two (2) forms:
+//
+//          if_(condition)
+//          [
+//              statement
+//          ]
+//
+//      and
+//
+//          if_(condition)
+//          [
+//              true_statement
+//          ]
+//          .else_
+//          [
+//              false_statement
+//          ]
+//
+//      where condition is an lambda_functor that evaluates to bool. If condition
+//      is true, the true_statement (again an lambda_functor) is executed
+//      otherwise, the false_statement (another lambda_functor) is executed. The
+//      result type of this is void. Note the trailing underscore after
+//      if_ and the the leading dot and the trailing underscore before
+//      and after .else_.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename CondT, typename ThenT, typename ElseT>
+struct if_then_else_composite {
+
+    typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
+
+    template <class SigArgs>
+    struct sig { typedef void type; };
+
+    if_then_else_composite(
+        CondT const& cond_,
+        ThenT const& then_,
+        ElseT const& else__)
+    :   cond(cond_), then(then_), else_(else__) {}
+
+    template <class Ret, CALL_TEMPLATE_ARGS>
+    Ret call(CALL_FORMAL_ARGS) const
+    {
+        if (cond.internal_call(CALL_ACTUAL_ARGS))
+            then.internal_call(CALL_ACTUAL_ARGS);
+        else
+            else_.internal_call(CALL_ACTUAL_ARGS);
+    }
+
+    CondT cond; ThenT then; ElseT else_; //  lambda_functors
+};
+
+//////////////////////////////////
+template <typename CondT, typename ThenT>
+struct else_gen {
+
+    else_gen(CondT const& cond_, ThenT const& then_)
+    :   cond(cond_), then(then_) {}
+
+    template <typename ElseT>
+    lambda_functor<if_then_else_composite<CondT, ThenT,
+        typename as_lambda_functor<ElseT>::type> >
+    operator[](ElseT const& else_)
+    {
+        typedef if_then_else_composite<CondT, ThenT,
+            typename as_lambda_functor<ElseT>::type>
+        result;
+
+        return result(cond, then, to_lambda_functor(else_));
+    }
+
+    CondT cond; ThenT then;
+};
+
+//////////////////////////////////
+template <typename CondT, typename ThenT>
+struct if_then_composite {
+
+    template <class SigArgs>
+    struct sig { typedef void type; };
+
+    if_then_composite(CondT const& cond_, ThenT const& then_)
+    :   cond(cond_), then(then_), else_(cond, then) {}
+
+    template <class Ret, CALL_TEMPLATE_ARGS>
+    Ret call(CALL_FORMAL_ARGS) const
+    {
+      if (cond.internal_call(CALL_ACTUAL_ARGS))
+            then.internal_call(CALL_ACTUAL_ARGS);
+    }
+
+    CondT cond; ThenT then; //  lambda_functors
+    else_gen<CondT, ThenT> else_;
+};
+
+//////////////////////////////////
+template <typename CondT>
+struct if_gen {
+
+    if_gen(CondT const& cond_)
+    :   cond(cond_) {}
+
+    template <typename ThenT>
+    lambda_functor<if_then_composite<
+        typename as_lambda_functor<CondT>::type,
+        typename as_lambda_functor<ThenT>::type> >
+    operator[](ThenT const& then) const
+    {
+        typedef if_then_composite<
+            typename as_lambda_functor<CondT>::type,
+            typename as_lambda_functor<ThenT>::type>
+        result;
+
+        return result(
+            to_lambda_functor(cond),
+            to_lambda_functor(then));
+    }
+
+    CondT cond;
+};
+
+//////////////////////////////////
+template <typename CondT>
+inline if_gen<CondT>
+if_(CondT const& cond)
+{
+    return if_gen<CondT>(cond);
+}
+
+
+
+} // lambda
+} // boost
+
+#endif // BOOST_LAMBDA_IF_HPP
+
+