epoc32/include/stdapis/boost/lambda/detail/lambda_functors.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     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