⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lambda_functor_base.hpp

📁 C++的一个好库。。。现在很流行
💻 HPP
📖 第 1 页 / 共 2 页
字号:
// 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_HPP

namespace boost { 
namespace lambda {


  // for return type deductions we wrap bound argument to this class,
  // which fulfils the base class contract for lambda_functors
template <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 types
template <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 functors
template <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
  // called
template <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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -