tinympl  0.2
mini MPL library for C++11
lambda.hpp
1 // Copyright (C) 2013, Ennio Barbaro.
2 //
3 // Use, modification, and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://sbabbi.github.io/tinympl for documentation.
8 //
9 // You are welcome to contact the author at:
10 // enniobarbaro@gmail.com
11 //
12 
13 #ifndef TINYMPL_LAMBDA_HPP
14 #define TINYMPL_LAMBDA_HPP
15 
16 #include <tinympl/bind.hpp>
17 #include <type_traits>
18 
19 namespace tinympl {
20 
27 template<class T> struct protect {typedef T type;};
28 
29 template<class Expr>
30 struct lambda
31 {
32  template<class ... Ts>
33  struct eval
34  {
35  template<class T,class Enable = void> struct pick {typedef T type;};
36  template<class T> struct pick<T, typename std::enable_if< (is_placeholder<T>::type::value > 0)>::type> {typedef variadic::at_t<is_placeholder<T>::value-1, Ts ... > type;};
37  template<class T> struct pick<T, typename std::enable_if< is_bind_expression<T>::type::value>::type> {typedef typename T::template eval<Ts...>::type type;};
38 
39  typedef typename pick<Expr>::type type;
40  };
41 
42  template<class ... Ts> using eval_t = typename eval<Ts...>::type;
43 };
44 
45 template< template<class ...> class F, class ... Args> struct lambda<F<Args...> >
46 {
47  template<class ... Ts>
48  struct eval
49  {
50  template<class T> using forward_t = typename T::template eval<Ts...>::type;
51 
52  typedef typename F< forward_t<lambda<Args> > ... >::type type;
53  };
54 
55  template<class ... Ts> using eval_t = typename eval<Ts...>::type;
56 };
57 
58 template< template<class ...> class F,class ... Args> struct lambda< protect<F<Args...> > >
59 {
60  template<class ... Ts>
61  struct eval
62  {
63  template<class T> using forward_t = typename T::template eval<Ts...>::type;
64 
65  typedef F< forward_t< lambda<protect<Args> > > ... > type;
66  };
67 
68  template<class ... Ts> using eval_t = typename eval<Ts...>::type;
69 };
70 
71 template<class Expr> struct is_bind_expression<lambda<Expr> > : std::true_type {};
72 
75 }
76 
77 #endif // TINYMPL_LAMBDA_HPP