epoc32/include/stdapis/boost/lambda/detail/ret.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  ret.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 www.boost.org
    10 
    11 
    12 #ifndef BOOST_LAMBDA_RET_HPP
    13 #define BOOST_LAMBDA_RET_HPP
    14 
    15 namespace boost { 
    16 namespace lambda {
    17 
    18   // TODO:
    19 
    20 //  Add specializations for function references for ret, protect and unlambda
    21 //  e.g void foo(); unlambda(foo); fails, as it would add a const qualifier
    22   // for a function type. 
    23   // on the other hand unlambda(*foo) does work
    24 
    25 
    26 // -- ret -------------------------
    27 // the explicit return type template 
    28 
    29   // TODO: It'd be nice to make ret a nop for other than lambda functors
    30   // but causes an ambiguiyty with gcc (not with KCC), check what is the
    31   // right interpretation.
    32 
    33   //  // ret for others than lambda functors has no effect
    34   // template <class U, class T>
    35   // inline const T& ret(const T& t) { return t; }
    36 
    37 
    38 template<class RET, class Arg>
    39 inline const 
    40 lambda_functor<
    41   lambda_functor_base<
    42     explicit_return_type_action<RET>, 
    43     tuple<lambda_functor<Arg> >
    44   > 
    45 >
    46 ret(const lambda_functor<Arg>& a1)
    47 {
    48   return  
    49     lambda_functor_base<
    50       explicit_return_type_action<RET>, 
    51       tuple<lambda_functor<Arg> >
    52     > 
    53     (tuple<lambda_functor<Arg> >(a1));
    54 }
    55 
    56 // protect ------------------
    57 
    58   // protecting others than lambda functors has no effect
    59 template <class T>
    60 inline const T& protect(const T& t) { return t; }
    61 
    62 template<class Arg>
    63 inline const 
    64 lambda_functor<
    65   lambda_functor_base<
    66     protect_action, 
    67     tuple<lambda_functor<Arg> >
    68   > 
    69 >
    70 protect(const lambda_functor<Arg>& a1)
    71 {
    72   return 
    73       lambda_functor_base<
    74         protect_action, 
    75         tuple<lambda_functor<Arg> >
    76       > 
    77     (tuple<lambda_functor<Arg> >(a1));
    78 }
    79    
    80 // -------------------------------------------------------------------
    81 
    82 // Hides the lambda functorness of a lambda functor. 
    83 // After this, the functor is immune to argument substitution, etc.
    84 // This can be used, e.g. to make it safe to pass lambda functors as 
    85 // arguments to functions, which might use them as target functions
    86 
    87 // note, unlambda and protect are different things. Protect hides the lambda
    88 // functor for one application, unlambda for good.
    89 
    90 template <class LambdaFunctor>
    91 class non_lambda_functor
    92 {
    93   LambdaFunctor lf;
    94 public:
    95   
    96   // This functor defines the result_type typedef.
    97   // The result type must be deducible without knowing the arguments
    98 
    99   template <class SigArgs> struct sig {
   100     typedef typename 
   101       LambdaFunctor::inherited:: 
   102         template sig<typename SigArgs::tail_type>::type type;
   103   };
   104 
   105   explicit non_lambda_functor(const LambdaFunctor& a) : lf(a) {}
   106 
   107   typename LambdaFunctor::nullary_return_type  
   108   operator()() const {
   109     return lf.template 
   110       call<typename LambdaFunctor::nullary_return_type>
   111         (cnull_type(), cnull_type(), cnull_type(), cnull_type()); 
   112   }
   113 
   114   template<class A>
   115   typename sig<tuple<const non_lambda_functor, A&> >::type 
   116   operator()(A& a) const {
   117     return lf.template call<typename sig<tuple<const non_lambda_functor, A&> >::type >(a, cnull_type(), cnull_type(), cnull_type()); 
   118   }
   119 
   120   template<class A, class B>
   121   typename sig<tuple<const non_lambda_functor, A&, B&> >::type 
   122   operator()(A& a, B& b) const {
   123     return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&> >::type >(a, b, cnull_type(), cnull_type()); 
   124   }
   125 
   126   template<class A, class B, class C>
   127   typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type 
   128   operator()(A& a, B& b, C& c) const {
   129     return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type>(a, b, c, cnull_type()); 
   130   }
   131 };
   132 
   133 template <class Arg>
   134 inline const Arg& unlambda(const Arg& a) { return a; }
   135 
   136 template <class Arg>
   137 inline const non_lambda_functor<lambda_functor<Arg> > 
   138 unlambda(const lambda_functor<Arg>& a)
   139 {
   140   return non_lambda_functor<lambda_functor<Arg> >(a);
   141 }
   142 
   143   // Due to a language restriction, lambda functors cannot be made to
   144   // accept non-const rvalue arguments. Usually iterators do not return 
   145   // temporaries, but sometimes they do. That's why a workaround is provided.
   146   // Note, that this potentially breaks const correctness, so be careful!
   147 
   148 // any lambda functor can be turned into a const_incorrect_lambda_functor
   149 // The operator() takes arguments as consts and then casts constness
   150 // away. So this breaks const correctness!!! but is a necessary workaround
   151 // in some cases due to language limitations.
   152 // Note, that this is not a lambda_functor anymore, so it can not be used
   153 // as a sub lambda expression.
   154 
   155 template <class LambdaFunctor>
   156 struct const_incorrect_lambda_functor {
   157   LambdaFunctor lf;
   158 public:
   159 
   160   explicit const_incorrect_lambda_functor(const LambdaFunctor& a) : lf(a) {}
   161 
   162   template <class SigArgs> struct sig {
   163     typedef typename
   164       LambdaFunctor::inherited::template 
   165         sig<typename SigArgs::tail_type>::type type;
   166   };
   167 
   168   // The nullary case is not needed (no arguments, no parameter type problems)
   169 
   170   template<class A>
   171   typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type
   172   operator()(const A& a) const {
   173     return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type >(const_cast<A&>(a), cnull_type(), cnull_type(), cnull_type());
   174   }
   175 
   176   template<class A, class B>
   177   typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type
   178   operator()(const A& a, const B& b) const {
   179     return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type >(const_cast<A&>(a), const_cast<B&>(b), cnull_type(), cnull_type());
   180   }
   181 
   182   template<class A, class B, class C>
   183   typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type
   184   operator()(const A& a, const B& b, const C& c) const {
   185     return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type>(const_cast<A&>(a), const_cast<B&>(b), const_cast<C&>(c), cnull_type());
   186   }
   187 };
   188 
   189 // ------------------------------------------------------------------------
   190 // any lambda functor can be turned into a const_parameter_lambda_functor
   191 // The operator() takes arguments as const.
   192 // This is useful if lambda functors are called with non-const rvalues.
   193 // Note, that this is not a lambda_functor anymore, so it can not be used
   194 // as a sub lambda expression.
   195 
   196 template <class LambdaFunctor>
   197 struct const_parameter_lambda_functor {
   198   LambdaFunctor lf;
   199 public:
   200 
   201   explicit const_parameter_lambda_functor(const LambdaFunctor& a) : lf(a) {}
   202 
   203   template <class SigArgs> struct sig {
   204     typedef typename
   205       LambdaFunctor::inherited::template 
   206         sig<typename SigArgs::tail_type>::type type;
   207   };
   208 
   209   // The nullary case is not needed: no arguments, no constness problems.
   210 
   211   template<class A>
   212   typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type
   213   operator()(const A& a) const {
   214     return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type >(a, cnull_type(), cnull_type(), cnull_type());
   215   }
   216 
   217   template<class A, class B>
   218   typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type
   219   operator()(const A& a, const B& b) const {
   220     return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type >(a, b, cnull_type(), cnull_type());
   221   }
   222 
   223   template<class A, class B, class C>
   224   typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&>
   225 >::type
   226   operator()(const A& a, const B& b, const C& c) const {
   227     return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&> >::type>(a, b, c, cnull_type());
   228   }
   229 };
   230 
   231 template <class Arg>
   232 inline const const_incorrect_lambda_functor<lambda_functor<Arg> >
   233 break_const(const lambda_functor<Arg>& lf)
   234 {
   235   return const_incorrect_lambda_functor<lambda_functor<Arg> >(lf);
   236 }
   237 
   238 
   239 template <class Arg>
   240 inline const const_parameter_lambda_functor<lambda_functor<Arg> >
   241 const_parameters(const lambda_functor<Arg>& lf)
   242 {
   243   return const_parameter_lambda_functor<lambda_functor<Arg> >(lf);
   244 }
   245 
   246 // make void ------------------------------------------------
   247 // make_void( x ) turns a lambda functor x with some return type y into
   248 // another lambda functor, which has a void return type
   249 // when called, the original return type is discarded
   250 
   251 // we use this action. The action class will be called, which means that
   252 // the wrapped lambda functor is evaluated, but we just don't do anything
   253 // with the result.
   254 struct voidifier_action {
   255   template<class Ret, class A> static void apply(A&) {}
   256 };
   257 
   258 template<class Args> struct return_type_N<voidifier_action, Args> {
   259   typedef void type;
   260 };
   261 
   262 template<class Arg1>
   263 inline const 
   264 lambda_functor<
   265   lambda_functor_base<
   266     action<1, voidifier_action>,
   267     tuple<lambda_functor<Arg1> >
   268   > 
   269 > 
   270 make_void(const lambda_functor<Arg1>& a1) { 
   271 return 
   272     lambda_functor_base<
   273       action<1, voidifier_action>,
   274       tuple<lambda_functor<Arg1> >
   275     > 
   276   (tuple<lambda_functor<Arg1> > (a1));
   277 }
   278 
   279 // for non-lambda functors, make_void does nothing 
   280 // (the argument gets evaluated immediately)
   281 
   282 template<class Arg1>
   283 inline const 
   284 lambda_functor<
   285   lambda_functor_base<do_nothing_action, null_type> 
   286 > 
   287 make_void(const Arg1& a1) { 
   288 return 
   289     lambda_functor_base<do_nothing_action, null_type>();
   290 }
   291 
   292 // std_functor -----------------------------------------------------
   293 
   294 //  The STL uses the result_type typedef as the convention to let binders know
   295 //  the return type of a function object. 
   296 //  LL uses the sig template.
   297 //  To let LL know that the function object has the result_type typedef 
   298 //  defined, it can be wrapped with the std_functor function.
   299 
   300 
   301 // Just inherit form the template parameter (the standard functor), 
   302 // and provide a sig template. So we have a class which is still the
   303 // same functor + the sig template.
   304 
   305 template<class T>
   306 struct result_type_to_sig : public T {
   307   template<class Args> struct sig { typedef typename T::result_type type; };
   308   result_type_to_sig(const T& t) : T(t) {}
   309 };
   310 
   311 template<class F>
   312 inline result_type_to_sig<F> std_functor(const F& f) { return f; }
   313 
   314 
   315 } // namespace lambda 
   316 } // namespace boost
   317 
   318 #endif
   319 
   320 
   321 
   322 
   323 
   324 
   325