--- /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
+
+