CGAL is a collaborative effort of several sites in Europe and Israel. The goal is to make the most i

源代码在线查看: if.hpp

软件大小: 8963 K
上传用户: fairbank
关键词: collaborative several Europe Israel
下载地址: 免注册下载 普通下载 VIP

相关代码

				// Boost Lambda Library -- if.hpp ------------------------------------------								// Copyright (C) 1999, 2000 Jaakko J鋜vi (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 				lambda_functor_base {				public:				  Args args;				  template  struct sig { typedef void type; };				public:				  explicit lambda_functor_base(const Args& a) : args(a) {}								  template				  RET call(CALL_FORMAL_ARGS) const {				    if (detail::select(boost::tuples::get(args), CALL_ACTUAL_ARGS)) 				      detail::select(boost::tuples::get(args), CALL_ACTUAL_ARGS); 				  }				};								// If Then				template 				inline const 				lambda_functor				  lambda_functor_base				    ifthen_action, 				    tuple				  > 				>				if_then(const lambda_functor& a1, const lambda_functor& a2) {				  return 				    lambda_functor_base				      ifthen_action, 				      tuple 				    > 				    ( tuple(a1, a2) );				}												// Specialization for if_then_else.				template				class 				lambda_functor_base {				public:				  Args args;				  template  struct sig { typedef void type; };				public:				  explicit lambda_functor_base(const Args& a) : args(a) {}								  template				  RET call(CALL_FORMAL_ARGS) const {				    if (detail::select(boost::tuples::get(args), CALL_ACTUAL_ARGS)) 				      detail::select(boost::tuples::get(args), CALL_ACTUAL_ARGS); 				    else 				      detail::select(boost::tuples::get(args), CALL_ACTUAL_ARGS);				  }				};																// If then else								template 				inline const 				lambda_functor				  lambda_functor_base				    ifthenelse_action, 				    tuple				  > 				>				if_then_else(const lambda_functor& a1, const lambda_functor& a2, 				             const lambda_functor& a3) {				  return 				    lambda_functor_base				      ifthenelse_action, 				      tuple				    > 				    (tuple				       (a1, a2, a3) );				}								// Our version of operator?:()								template 				inline const 				  lambda_functor				    lambda_functor_base				      other_action, 				      tuple				          typename const_copy_argument::type,				          typename const_copy_argument::type>				  > 				>				if_then_else_return(const lambda_functor& a1, 				                    const Arg2 & a2, 				                    const Arg3 & a3) {				  return 				      lambda_functor_base				        other_action, 				        tuple				              typename const_copy_argument::type,				              typename const_copy_argument::type>				      > ( tuple				              typename const_copy_argument::type,				              typename const_copy_argument::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				struct return_type_2_ifthenelsereturn;								// if A can be converted to B and vice versa -> ambiguous				template				struct return_type_2_ifthenelsereturn {				  typedef 				    detail::return_type_deduction_failure type;				  // ambiguous type in conditional expression				};				// if A can be converted to B and vice versa and are of same type				template				struct return_type_2_ifthenelsereturn {				  typedef A type;				};												// A can be converted to B				template				struct return_type_2_ifthenelsereturn {				  typedef B type;				};								// B can be converted to A				template				struct return_type_2_ifthenelsereturn {				  typedef A type;				};								// neither can be converted. Then we drop the potential references, and				// try again				template				struct return_type_2_ifthenelsereturn {				  // 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::type plainA; 				  typedef const typename boost::remove_reference::type plainB; 				  // TODO: Add support for volatile ?								  typedef typename				       return_type_2_ifthenelsereturn				         2,				         boost::is_convertible::value, 				         boost::is_convertible::value,				         boost::is_same::value,				         plainA, 				         plainB>::type type;				};								// PHASE 6:2				template				struct return_type_2_ifthenelsereturn {				  typedef 				    detail::return_type_deduction_failure type;				  // types_do_not_match_in_conditional_expression 				};																// PHASE 5: now we know that types are not arithmetic.				template				struct non_numeric_types {				  typedef typename 				    return_type_2_ifthenelsereturn				      1, // phase 1 				      is_convertible::value, 				      is_convertible::value, 				      is_same::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				struct arithmetic_or_not {				  typedef typename				    return_type_2::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				struct arithmetic_or_not {				  typedef typename non_numeric_types::type type; 				};								// if either A or B has promote code -1 it is not an arithmetic type				template				struct arithmetic_or_not  {				  typedef typename non_numeric_types::type type;				};				template				struct arithmetic_or_not  {				  typedef typename non_numeric_types::type type;				};				template				struct arithmetic_or_not  {				  typedef typename non_numeric_types::type type;				};																				// PHASE 3 : Are the types same?				// No, check if they are arithmetic or not				template 				struct same_or_not {				  typedef typename detail::remove_reference_and_cv::type plainA;				  typedef typename detail::remove_reference_and_cv::type plainB;								  typedef typename 				    arithmetic_or_not				      detail::promote_code::value, 				      detail::promote_code::value, 				      A, 				      B>::type type;				};				// Yes, clear.				template  struct same_or_not {				  typedef A type;				};								} // detail								// PHASE 2 : Perform first the potential array_to_pointer conversion 				template				struct return_type_2 { 								  typedef typename detail::array_to_pointer::type A1;				  typedef typename detail::array_to_pointer::type B1;								  typedef typename 				    boost::add_const::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 				lambda_functor_base {				public:				  Args args;								  template  struct sig {				  private:				    typedef typename detail::nth_return_type_sig::type ret1;				    typedef typename detail::nth_return_type_sig::type ret2;				  public:				    typedef typename return_type_2				      other_action, ret1, ret2				    >::type type;				  };								public:				  explicit lambda_functor_base(const Args& a) : args(a) {}								  template				  RET call(CALL_FORMAL_ARGS) const {				    return (detail::select(boost::tuples::get(args), CALL_ACTUAL_ARGS)) ?				       detail::select(boost::tuples::get(args), CALL_ACTUAL_ARGS) 				    : 				       detail::select(boost::tuples::get(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 				struct if_then_else_composite {								    typedef if_then_else_composite self_t;								    template 				    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 				    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 				struct else_gen {								    else_gen(CondT const& cond_, ThenT const& then_)				    :   cond(cond_), then(then_) {}								    template 				    lambda_functor				        typename as_lambda_functor::type> >				    operator[](ElseT const& else_)				    {				        typedef if_then_else_composite				            typename as_lambda_functor::type>				        result;								        return result(cond, then, to_lambda_functor(else_));				    }								    CondT cond; ThenT then;				};								//////////////////////////////////				template 				struct if_then_composite {								    template 				    struct sig { typedef void type; };								    if_then_composite(CondT const& cond_, ThenT const& then_)				    :   cond(cond_), then(then_), else_(cond, then) {}								    template 				    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 else_;				};								//////////////////////////////////				template 				struct if_gen {								    if_gen(CondT const& cond_)				    :   cond(cond_) {}								    template 				    lambda_functor				        typename as_lambda_functor::type,				        typename as_lambda_functor::type> >				    operator[](ThenT const& then) const				    {				        typedef if_then_composite				            typename as_lambda_functor::type,				            typename as_lambda_functor::type>				        result;								        return result(				            to_lambda_functor(cond),				            to_lambda_functor(then));				    }								    CondT cond;				};								//////////////////////////////////				template 				inline if_gen				if_(CondT const& cond)				{				    return if_gen(cond);				}																} // lambda				} // boost								#endif // BOOST_LAMBDA_IF_HPP															

相关资源