1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/lambda/detail/ret.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,325 @@
1.4 +// Boost Lambda Library ret.hpp -----------------------------------------
1.5 +
1.6 +// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
1.7 +//
1.8 +// Distributed under the Boost Software License, Version 1.0. (See
1.9 +// accompanying file LICENSE_1_0.txt or copy at
1.10 +// http://www.boost.org/LICENSE_1_0.txt)
1.11 +//
1.12 +// For more information, see www.boost.org
1.13 +
1.14 +
1.15 +#ifndef BOOST_LAMBDA_RET_HPP
1.16 +#define BOOST_LAMBDA_RET_HPP
1.17 +
1.18 +namespace boost {
1.19 +namespace lambda {
1.20 +
1.21 + // TODO:
1.22 +
1.23 +// Add specializations for function references for ret, protect and unlambda
1.24 +// e.g void foo(); unlambda(foo); fails, as it would add a const qualifier
1.25 + // for a function type.
1.26 + // on the other hand unlambda(*foo) does work
1.27 +
1.28 +
1.29 +// -- ret -------------------------
1.30 +// the explicit return type template
1.31 +
1.32 + // TODO: It'd be nice to make ret a nop for other than lambda functors
1.33 + // but causes an ambiguiyty with gcc (not with KCC), check what is the
1.34 + // right interpretation.
1.35 +
1.36 + // // ret for others than lambda functors has no effect
1.37 + // template <class U, class T>
1.38 + // inline const T& ret(const T& t) { return t; }
1.39 +
1.40 +
1.41 +template<class RET, class Arg>
1.42 +inline const
1.43 +lambda_functor<
1.44 + lambda_functor_base<
1.45 + explicit_return_type_action<RET>,
1.46 + tuple<lambda_functor<Arg> >
1.47 + >
1.48 +>
1.49 +ret(const lambda_functor<Arg>& a1)
1.50 +{
1.51 + return
1.52 + lambda_functor_base<
1.53 + explicit_return_type_action<RET>,
1.54 + tuple<lambda_functor<Arg> >
1.55 + >
1.56 + (tuple<lambda_functor<Arg> >(a1));
1.57 +}
1.58 +
1.59 +// protect ------------------
1.60 +
1.61 + // protecting others than lambda functors has no effect
1.62 +template <class T>
1.63 +inline const T& protect(const T& t) { return t; }
1.64 +
1.65 +template<class Arg>
1.66 +inline const
1.67 +lambda_functor<
1.68 + lambda_functor_base<
1.69 + protect_action,
1.70 + tuple<lambda_functor<Arg> >
1.71 + >
1.72 +>
1.73 +protect(const lambda_functor<Arg>& a1)
1.74 +{
1.75 + return
1.76 + lambda_functor_base<
1.77 + protect_action,
1.78 + tuple<lambda_functor<Arg> >
1.79 + >
1.80 + (tuple<lambda_functor<Arg> >(a1));
1.81 +}
1.82 +
1.83 +// -------------------------------------------------------------------
1.84 +
1.85 +// Hides the lambda functorness of a lambda functor.
1.86 +// After this, the functor is immune to argument substitution, etc.
1.87 +// This can be used, e.g. to make it safe to pass lambda functors as
1.88 +// arguments to functions, which might use them as target functions
1.89 +
1.90 +// note, unlambda and protect are different things. Protect hides the lambda
1.91 +// functor for one application, unlambda for good.
1.92 +
1.93 +template <class LambdaFunctor>
1.94 +class non_lambda_functor
1.95 +{
1.96 + LambdaFunctor lf;
1.97 +public:
1.98 +
1.99 + // This functor defines the result_type typedef.
1.100 + // The result type must be deducible without knowing the arguments
1.101 +
1.102 + template <class SigArgs> struct sig {
1.103 + typedef typename
1.104 + LambdaFunctor::inherited::
1.105 + template sig<typename SigArgs::tail_type>::type type;
1.106 + };
1.107 +
1.108 + explicit non_lambda_functor(const LambdaFunctor& a) : lf(a) {}
1.109 +
1.110 + typename LambdaFunctor::nullary_return_type
1.111 + operator()() const {
1.112 + return lf.template
1.113 + call<typename LambdaFunctor::nullary_return_type>
1.114 + (cnull_type(), cnull_type(), cnull_type(), cnull_type());
1.115 + }
1.116 +
1.117 + template<class A>
1.118 + typename sig<tuple<const non_lambda_functor, A&> >::type
1.119 + operator()(A& a) const {
1.120 + return lf.template call<typename sig<tuple<const non_lambda_functor, A&> >::type >(a, cnull_type(), cnull_type(), cnull_type());
1.121 + }
1.122 +
1.123 + template<class A, class B>
1.124 + typename sig<tuple<const non_lambda_functor, A&, B&> >::type
1.125 + operator()(A& a, B& b) const {
1.126 + return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&> >::type >(a, b, cnull_type(), cnull_type());
1.127 + }
1.128 +
1.129 + template<class A, class B, class C>
1.130 + typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type
1.131 + operator()(A& a, B& b, C& c) const {
1.132 + return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type>(a, b, c, cnull_type());
1.133 + }
1.134 +};
1.135 +
1.136 +template <class Arg>
1.137 +inline const Arg& unlambda(const Arg& a) { return a; }
1.138 +
1.139 +template <class Arg>
1.140 +inline const non_lambda_functor<lambda_functor<Arg> >
1.141 +unlambda(const lambda_functor<Arg>& a)
1.142 +{
1.143 + return non_lambda_functor<lambda_functor<Arg> >(a);
1.144 +}
1.145 +
1.146 + // Due to a language restriction, lambda functors cannot be made to
1.147 + // accept non-const rvalue arguments. Usually iterators do not return
1.148 + // temporaries, but sometimes they do. That's why a workaround is provided.
1.149 + // Note, that this potentially breaks const correctness, so be careful!
1.150 +
1.151 +// any lambda functor can be turned into a const_incorrect_lambda_functor
1.152 +// The operator() takes arguments as consts and then casts constness
1.153 +// away. So this breaks const correctness!!! but is a necessary workaround
1.154 +// in some cases due to language limitations.
1.155 +// Note, that this is not a lambda_functor anymore, so it can not be used
1.156 +// as a sub lambda expression.
1.157 +
1.158 +template <class LambdaFunctor>
1.159 +struct const_incorrect_lambda_functor {
1.160 + LambdaFunctor lf;
1.161 +public:
1.162 +
1.163 + explicit const_incorrect_lambda_functor(const LambdaFunctor& a) : lf(a) {}
1.164 +
1.165 + template <class SigArgs> struct sig {
1.166 + typedef typename
1.167 + LambdaFunctor::inherited::template
1.168 + sig<typename SigArgs::tail_type>::type type;
1.169 + };
1.170 +
1.171 + // The nullary case is not needed (no arguments, no parameter type problems)
1.172 +
1.173 + template<class A>
1.174 + typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type
1.175 + operator()(const A& a) const {
1.176 + return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type >(const_cast<A&>(a), cnull_type(), cnull_type(), cnull_type());
1.177 + }
1.178 +
1.179 + template<class A, class B>
1.180 + typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type
1.181 + operator()(const A& a, const B& b) const {
1.182 + 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());
1.183 + }
1.184 +
1.185 + template<class A, class B, class C>
1.186 + typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type
1.187 + operator()(const A& a, const B& b, const C& c) const {
1.188 + 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());
1.189 + }
1.190 +};
1.191 +
1.192 +// ------------------------------------------------------------------------
1.193 +// any lambda functor can be turned into a const_parameter_lambda_functor
1.194 +// The operator() takes arguments as const.
1.195 +// This is useful if lambda functors are called with non-const rvalues.
1.196 +// Note, that this is not a lambda_functor anymore, so it can not be used
1.197 +// as a sub lambda expression.
1.198 +
1.199 +template <class LambdaFunctor>
1.200 +struct const_parameter_lambda_functor {
1.201 + LambdaFunctor lf;
1.202 +public:
1.203 +
1.204 + explicit const_parameter_lambda_functor(const LambdaFunctor& a) : lf(a) {}
1.205 +
1.206 + template <class SigArgs> struct sig {
1.207 + typedef typename
1.208 + LambdaFunctor::inherited::template
1.209 + sig<typename SigArgs::tail_type>::type type;
1.210 + };
1.211 +
1.212 + // The nullary case is not needed: no arguments, no constness problems.
1.213 +
1.214 + template<class A>
1.215 + typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type
1.216 + operator()(const A& a) const {
1.217 + return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type >(a, cnull_type(), cnull_type(), cnull_type());
1.218 + }
1.219 +
1.220 + template<class A, class B>
1.221 + typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type
1.222 + operator()(const A& a, const B& b) const {
1.223 + return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type >(a, b, cnull_type(), cnull_type());
1.224 + }
1.225 +
1.226 + template<class A, class B, class C>
1.227 + typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&>
1.228 +>::type
1.229 + operator()(const A& a, const B& b, const C& c) const {
1.230 + return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&> >::type>(a, b, c, cnull_type());
1.231 + }
1.232 +};
1.233 +
1.234 +template <class Arg>
1.235 +inline const const_incorrect_lambda_functor<lambda_functor<Arg> >
1.236 +break_const(const lambda_functor<Arg>& lf)
1.237 +{
1.238 + return const_incorrect_lambda_functor<lambda_functor<Arg> >(lf);
1.239 +}
1.240 +
1.241 +
1.242 +template <class Arg>
1.243 +inline const const_parameter_lambda_functor<lambda_functor<Arg> >
1.244 +const_parameters(const lambda_functor<Arg>& lf)
1.245 +{
1.246 + return const_parameter_lambda_functor<lambda_functor<Arg> >(lf);
1.247 +}
1.248 +
1.249 +// make void ------------------------------------------------
1.250 +// make_void( x ) turns a lambda functor x with some return type y into
1.251 +// another lambda functor, which has a void return type
1.252 +// when called, the original return type is discarded
1.253 +
1.254 +// we use this action. The action class will be called, which means that
1.255 +// the wrapped lambda functor is evaluated, but we just don't do anything
1.256 +// with the result.
1.257 +struct voidifier_action {
1.258 + template<class Ret, class A> static void apply(A&) {}
1.259 +};
1.260 +
1.261 +template<class Args> struct return_type_N<voidifier_action, Args> {
1.262 + typedef void type;
1.263 +};
1.264 +
1.265 +template<class Arg1>
1.266 +inline const
1.267 +lambda_functor<
1.268 + lambda_functor_base<
1.269 + action<1, voidifier_action>,
1.270 + tuple<lambda_functor<Arg1> >
1.271 + >
1.272 +>
1.273 +make_void(const lambda_functor<Arg1>& a1) {
1.274 +return
1.275 + lambda_functor_base<
1.276 + action<1, voidifier_action>,
1.277 + tuple<lambda_functor<Arg1> >
1.278 + >
1.279 + (tuple<lambda_functor<Arg1> > (a1));
1.280 +}
1.281 +
1.282 +// for non-lambda functors, make_void does nothing
1.283 +// (the argument gets evaluated immediately)
1.284 +
1.285 +template<class Arg1>
1.286 +inline const
1.287 +lambda_functor<
1.288 + lambda_functor_base<do_nothing_action, null_type>
1.289 +>
1.290 +make_void(const Arg1& a1) {
1.291 +return
1.292 + lambda_functor_base<do_nothing_action, null_type>();
1.293 +}
1.294 +
1.295 +// std_functor -----------------------------------------------------
1.296 +
1.297 +// The STL uses the result_type typedef as the convention to let binders know
1.298 +// the return type of a function object.
1.299 +// LL uses the sig template.
1.300 +// To let LL know that the function object has the result_type typedef
1.301 +// defined, it can be wrapped with the std_functor function.
1.302 +
1.303 +
1.304 +// Just inherit form the template parameter (the standard functor),
1.305 +// and provide a sig template. So we have a class which is still the
1.306 +// same functor + the sig template.
1.307 +
1.308 +template<class T>
1.309 +struct result_type_to_sig : public T {
1.310 + template<class Args> struct sig { typedef typename T::result_type type; };
1.311 + result_type_to_sig(const T& t) : T(t) {}
1.312 +};
1.313 +
1.314 +template<class F>
1.315 +inline result_type_to_sig<F> std_functor(const F& f) { return f; }
1.316 +
1.317 +
1.318 +} // namespace lambda
1.319 +} // namespace boost
1.320 +
1.321 +#endif
1.322 +
1.323 +
1.324 +
1.325 +
1.326 +
1.327 +
1.328 +