ossrv_pub/boost_apis/boost/lambda/detail/lambda_functors.hpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Boost Lambda Library -  lambda_functors.hpp -------------------------------
       
     2 
       
     3 // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
       
     4 //
       
     5 // Distributed under the Boost Software License, Version 1.0. (See
       
     6 // accompanying file LICENSE_1_0.txt or copy at
       
     7 // http://www.boost.org/LICENSE_1_0.txt)
       
     8 //
       
     9 // For more information, see http://www.boost.org
       
    10 
       
    11 // ------------------------------------------------
       
    12 
       
    13 #ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
       
    14 #define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
       
    15 
       
    16 namespace boost { 
       
    17 namespace lambda {
       
    18 
       
    19 // -- lambda_functor --------------------------------------------
       
    20 // --------------------------------------------------------------
       
    21 
       
    22 //inline const null_type const_null_type() { return null_type(); }
       
    23 
       
    24 namespace detail {
       
    25 namespace {
       
    26 
       
    27   static const null_type constant_null_type = null_type();
       
    28 
       
    29 } // unnamed
       
    30 } // detail
       
    31 
       
    32 class unused {};
       
    33 
       
    34 #define cnull_type() detail::constant_null_type
       
    35 
       
    36 // -- free variables types -------------------------------------------------- 
       
    37  
       
    38   // helper to work around the case where the nullary return type deduction 
       
    39   // is always performed, even though the functor is not nullary  
       
    40 namespace detail {
       
    41   template<int N, class Tuple> struct get_element_or_null_type {
       
    42     typedef typename 
       
    43       detail::tuple_element_as_reference<N, Tuple>::type type;
       
    44   };
       
    45   template<int N> struct get_element_or_null_type<N, null_type> {
       
    46     typedef null_type type;
       
    47   };
       
    48 }
       
    49 
       
    50 template <int I> struct placeholder;
       
    51 
       
    52 template<> struct placeholder<FIRST> {
       
    53 
       
    54   template<class SigArgs> struct sig {
       
    55     typedef typename detail::get_element_or_null_type<0, SigArgs>::type type;
       
    56   };
       
    57 
       
    58   template<class RET, CALL_TEMPLATE_ARGS> 
       
    59   RET call(CALL_FORMAL_ARGS) const { 
       
    60     BOOST_STATIC_ASSERT(boost::is_reference<RET>::value); 
       
    61     CALL_USE_ARGS; // does nothing, prevents warnings for unused args
       
    62     return a; 
       
    63   }
       
    64 };
       
    65 
       
    66 template<> struct placeholder<SECOND> {
       
    67 
       
    68   template<class SigArgs> struct sig {
       
    69     typedef typename detail::get_element_or_null_type<1, SigArgs>::type type;
       
    70   };
       
    71 
       
    72   template<class RET, CALL_TEMPLATE_ARGS> 
       
    73   RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return b; }
       
    74 };
       
    75 
       
    76 template<> struct placeholder<THIRD> {
       
    77 
       
    78   template<class SigArgs> struct sig {
       
    79     typedef typename detail::get_element_or_null_type<2, SigArgs>::type type;
       
    80   };
       
    81 
       
    82   template<class RET, CALL_TEMPLATE_ARGS> 
       
    83   RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return c; }
       
    84 };
       
    85 
       
    86 template<> struct placeholder<EXCEPTION> {
       
    87 
       
    88   template<class SigArgs> struct sig {
       
    89     typedef typename detail::get_element_or_null_type<3, SigArgs>::type type;
       
    90   };
       
    91 
       
    92   template<class RET, CALL_TEMPLATE_ARGS> 
       
    93   RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return env; }
       
    94 };
       
    95    
       
    96 typedef const lambda_functor<placeholder<FIRST> >  placeholder1_type;
       
    97 typedef const lambda_functor<placeholder<SECOND> > placeholder2_type;
       
    98 typedef const lambda_functor<placeholder<THIRD> >  placeholder3_type;
       
    99    
       
   100 
       
   101 ///////////////////////////////////////////////////////////////////////////////
       
   102 
       
   103 
       
   104 // free variables are lambda_functors. This is to allow uniform handling with 
       
   105 // other lambda_functors.
       
   106 // -------------------------------------------------------------------
       
   107 
       
   108 
       
   109 
       
   110 // -- lambda_functor NONE ------------------------------------------------
       
   111 template <class T>
       
   112 class lambda_functor : public T 
       
   113 {
       
   114 
       
   115 BOOST_STATIC_CONSTANT(int, arity_bits = get_arity<T>::value);
       
   116  
       
   117 public:
       
   118   typedef T inherited;
       
   119 
       
   120   lambda_functor() {}
       
   121   lambda_functor(const lambda_functor& l) : inherited(l) {}
       
   122 
       
   123   lambda_functor(const T& t) : inherited(t) {}
       
   124 
       
   125   template <class SigArgs> struct sig {
       
   126     typedef typename inherited::template 
       
   127       sig<typename SigArgs::tail_type>::type type;
       
   128   };
       
   129 
       
   130   // Note that this return type deduction template is instantiated, even 
       
   131   // if the nullary 
       
   132   // operator() is not called at all. One must make sure that it does not fail.
       
   133   typedef typename 
       
   134     inherited::template sig<null_type>::type
       
   135       nullary_return_type;
       
   136 
       
   137   nullary_return_type operator()() const { 
       
   138     return inherited::template 
       
   139       call<nullary_return_type>
       
   140         (cnull_type(), cnull_type(), cnull_type(), cnull_type()); 
       
   141   }
       
   142 
       
   143   template<class A>
       
   144   typename inherited::template sig<tuple<A&> >::type
       
   145   operator()(A& a) const { 
       
   146     return inherited::template call<
       
   147       typename inherited::template sig<tuple<A&> >::type
       
   148     >(a, cnull_type(), cnull_type(), cnull_type());
       
   149   }
       
   150 
       
   151   template<class A, class B>
       
   152   typename inherited::template sig<tuple<A&, B&> >::type
       
   153   operator()(A& a, B& b) const { 
       
   154     return inherited::template call<
       
   155       typename inherited::template sig<tuple<A&, B&> >::type
       
   156     >(a, b, cnull_type(), cnull_type()); 
       
   157   }
       
   158 
       
   159   template<class A, class B, class C>
       
   160   typename inherited::template sig<tuple<A&, B&, C&> >::type
       
   161   operator()(A& a, B& b, C& c) const
       
   162   { 
       
   163     return inherited::template call<
       
   164       typename inherited::template sig<tuple<A&, B&, C&> >::type
       
   165     >(a, b, c, cnull_type()); 
       
   166   }
       
   167 
       
   168   // for internal calls with env
       
   169   template<CALL_TEMPLATE_ARGS>
       
   170   typename inherited::template sig<tuple<CALL_REFERENCE_TYPES> >::type
       
   171   internal_call(CALL_FORMAL_ARGS) const { 
       
   172      return inherited::template 
       
   173        call<typename inherited::template 
       
   174          sig<tuple<CALL_REFERENCE_TYPES> >::type>(CALL_ACTUAL_ARGS); 
       
   175   }
       
   176 
       
   177   template<class A>
       
   178   const lambda_functor<lambda_functor_base<
       
   179                   other_action<assignment_action>,
       
   180                   boost::tuple<lambda_functor,
       
   181                   typename const_copy_argument <const A>::type> > >
       
   182   operator=(const A& a) const {
       
   183     return lambda_functor_base<
       
   184                   other_action<assignment_action>,
       
   185                   boost::tuple<lambda_functor,
       
   186                   typename const_copy_argument <const A>::type> >
       
   187      (  boost::tuple<lambda_functor,
       
   188              typename const_copy_argument <const A>::type>(*this, a) );
       
   189   }
       
   190 
       
   191   template<class A> 
       
   192   const lambda_functor<lambda_functor_base< 
       
   193                   other_action<subscript_action>, 
       
   194                   boost::tuple<lambda_functor, 
       
   195                         typename const_copy_argument <const A>::type> > > 
       
   196   operator[](const A& a) const { 
       
   197     return lambda_functor_base< 
       
   198                   other_action<subscript_action>, 
       
   199                   boost::tuple<lambda_functor, 
       
   200                         typename const_copy_argument <const A>::type> >
       
   201      ( boost::tuple<lambda_functor, 
       
   202              typename const_copy_argument <const A>::type>(*this, a ) ); 
       
   203   } 
       
   204 };
       
   205 
       
   206 
       
   207 } // namespace lambda
       
   208 } // namespace boost
       
   209 
       
   210 #endif
       
   211 
       
   212