lambda_functor_base.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 600 行 · 第 1/2 页

HPP
600
字号
// Boost Lambda Library  lambda_functor_base.hpp -----------------------------//// Copyright (C) 1999, 2000 Jaakko J鋜vi (jaakko.jarvi@cs.utu.fi)//// 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// ------------------------------------------------------------#ifndef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP#define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPPnamespace boost { namespace lambda {  // for return type deductions we wrap bound argument to this class,  // which fulfils the base class contract for lambda_functorstemplate <class T>class identity {  T elem;public:    typedef T element_t;  // take all parameters as const rererences. Note that non-const references  // stay as they are.  typedef typename boost::add_reference<    typename boost::add_const<T>::type  >::type par_t;  explicit identity(par_t t) : elem(t) {}  template <typename SigArgs>   struct sig { typedef element_t type; };  template<class RET, CALL_TEMPLATE_ARGS>  RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return elem; }};template <class T> inline lambda_functor<identity<T&> > var(T& t) { return identity<T&>(t); }  // for lambda functors, var is an identity operator. It was forbidden  // at some point, but we might want to var something that can be a   // non-lambda functor or a lambda functor.template <class T>lambda_functor<T> var(const lambda_functor<T>& t) { return t; }template <class T> struct var_type {  typedef lambda_functor<identity<T&> > type;};template <class T> inline lambda_functor<identity<typename bound_argument_conversion<const T>::type> >constant(const T& t) {   return identity<typename bound_argument_conversion<const T>::type>(t); }template <class T>lambda_functor<T> constant(const lambda_functor<T>& t) { return t; }template <class T> struct constant_type {  typedef    lambda_functor<     identity<typename bound_argument_conversion<const T>::type>    > type;};template <class T> inline lambda_functor<identity<const T&> > constant_ref(const T& t) {   return identity<const T&>(t); }template <class T>lambda_functor<T> constant_ref(const lambda_functor<T>& t) { return t; }template <class T> struct constant_ref_type {  typedef    lambda_functor<identity<const T&> > type;};  // as_lambda_functor turns any types to lambda functors   // non-lambda_functors will be bound argument typestemplate <class T>struct as_lambda_functor {   typedef typename     detail::remove_reference_and_cv<T>::type plain_T;  typedef typename     detail::IF<is_lambda_functor<plain_T>::value,       plain_T,      lambda_functor<        identity<typename bound_argument_conversion<T>::type>       >    >::RET type; };// turns arbitrary objects into lambda functorstemplate <class T> inline lambda_functor<identity<typename bound_argument_conversion<const T>::type> > to_lambda_functor(const T& t) {   return identity<typename bound_argument_conversion<const T>::type>(t);}template <class T> inline lambda_functor<T> to_lambda_functor(const lambda_functor<T>& t) {   return t;}namespace detail {   // In a call constify_rvals<T>::go(x)// x should be of type T. If T is a non-reference type, do// returns x as const reference. // Otherwise the type doesn't change.// The purpose of this class is to avoid // 'cannot bind temporaries to non-const references' errors.template <class T> struct constify_rvals {  template<class U>  static inline const U& go(const U& u) { return u; }};template <class T> struct constify_rvals<T&> {  template<class U>  static inline U& go(U& u) { return u; }};  // check whether one of the elements of a tuple (cons list) is of type  // null_type. Needed, because the compiler goes ahead and instantiates  // sig template for nullary case even if the nullary operator() is not  // calledtemplate <class T> struct is_null_type { BOOST_STATIC_CONSTANT(bool, value = false); };template <> struct is_null_type<null_type> { BOOST_STATIC_CONSTANT(bool, value = true); };template<class Tuple> struct has_null_type {  BOOST_STATIC_CONSTANT(bool, value = (is_null_type<typename Tuple::head_type>::value || has_null_type<typename Tuple::tail_type>::value));};template<> struct has_null_type<null_type> {  BOOST_STATIC_CONSTANT(bool, value = false);};// helpers -------------------template<class Args, class SigArgs>class deduce_argument_types_ {  typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;  typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;  public:  typedef    boost::tuples::cons<      el_t,       typename deduce_argument_types_<typename Args::tail_type, SigArgs>::type    > type;};template<class SigArgs>class deduce_argument_types_<null_type, SigArgs> {public:  typedef null_type type; };//  // note that tuples cannot have plain function types as elements.//  // Hence, all other types will be non-const, except references to //  // functions.//  template <class T> struct remove_reference_except_from_functions {//    typedef typename boost::remove_reference<T>::type t;//    typedef typename detail::IF<boost::is_function<t>::value, T, t>::RET type;//  };template<class Args, class SigArgs>class deduce_non_ref_argument_types_ {  typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;  typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;  public:  typedef    boost::tuples::cons<  //      typename detail::remove_reference_except_from_functions<el_t>::type,       typename boost::remove_reference<el_t>::type,       typename deduce_non_ref_argument_types_<typename Args::tail_type, SigArgs>::type    > type;};template<class SigArgs>class deduce_non_ref_argument_types_<null_type, SigArgs> {public:  typedef null_type type; };  // -------------// take stored Args and Open Args, and return a const list with // deduced elements (real return types)template<class Args, class SigArgs>class deduce_argument_types {  typedef typename deduce_argument_types_<Args, SigArgs>::type t1;public:  typedef typename detail::IF<    has_null_type<t1>::value, null_type, t1  >::RET type; };// take stored Args and Open Args, and return a const list with // deduced elements (references are stripped from the element types)template<class Args, class SigArgs>class deduce_non_ref_argument_types {  typedef typename deduce_non_ref_argument_types_<Args, SigArgs>::type t1;public:  typedef typename detail::IF<    has_null_type<t1>::value, null_type, t1  >::RET type; };template <int N, class Args, class SigArgs>struct nth_return_type_sig {  typedef typename           as_lambda_functor<            typename boost::tuples::element<N, Args>::type   //            typename tuple_element_as_reference<N, Args>::type         >::type lf_type;  typedef typename lf_type::inherited::template sig<SigArgs>::type type;  };template<int N, class Tuple> struct element_or_null {  typedef typename boost::tuples::element<N, Tuple>::type type;};template<int N> struct element_or_null<N, null_type> {  typedef null_type type;};      } // end detail    // -- lambda_functor base ---------------------// the explicit_return_type_action case -----------------------------------template<class RET, class Args>class lambda_functor_base<explicit_return_type_action<RET>, Args> {public:  Args args;  explicit lambda_functor_base(const Args& a) : args(a) {}  template <class SigArgs> struct sig { typedef RET type; };  template<class RET_, CALL_TEMPLATE_ARGS>  RET call(CALL_FORMAL_ARGS) const   {    return detail::constify_rvals<RET>::go(     detail::r_select<RET>::go(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS));  }};// the protect_action case -----------------------------------template<class Args>class lambda_functor_base<protect_action, Args>{public:  Args args;public:  explicit lambda_functor_base(const Args& a) : args(a) {}  template<class RET, CALL_TEMPLATE_ARGS>  RET call(CALL_FORMAL_ARGS) const   {     CALL_USE_ARGS;     return boost::tuples::get<0>(args);  }  template<class SigArgs> struct sig {     //    typedef typename detail::tuple_element_as_reference<0, SigArgs>::type type;    typedef typename boost::tuples::element<0, Args>::type type;  };};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?