• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_METAPARSE_META_HS_CURRY_HPP
2 #define BOOST_METAPARSE_META_HS_CURRY_HPP
3 
4 // Copyright Abel Sinkovics (abel@sinkovics.hu)  2010.
5 // Distributed under the Boost Software License, Version 1.0.
6 //    (See accompanying file LICENSE_1_0.txt or copy at
7 //          http://www.boost.org/LICENSE_1_0.txt)
8 
9 #include <boost/mpl/eval_if.hpp>
10 #include <boost/mpl/equal_to.hpp>
11 #include <boost/mpl/int.hpp>
12 #include <boost/mpl/apply.hpp>
13 #include <boost/mpl/minus.hpp>
14 #include <boost/mpl/push_back.hpp>
15 #include <boost/mpl/unpack_args.hpp>
16 #include <boost/mpl/deque.hpp>
17 #include <boost/mpl/quote.hpp>
18 
19 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
20 #include <boost/preprocessor/repetition/enum_params.hpp>
21 #include <boost/preprocessor/repetition/enum.hpp>
22 #include <boost/preprocessor/cat.hpp>
23 #include <boost/preprocessor/tuple/eat.hpp>
24 
25 #ifndef CURRY_MAX_ARGUMENT
26 #  define CURRY_MAX_ARGUMENT 5
27 #endif
28 
29 namespace impl
30 {
31   template <
32     class UnpackedMetafunctionClass,
33     class ArgumentsLeft,
34     class ArgumentList
35   >
36   struct curry_impl;
37 
38 
39 
40   template <
41     class UnpackedMetafunctionClass,
42     class ArgumentsLeft,
43     class ArgumentList
44   >
45   struct next_currying_step
46   {
47     typedef next_currying_step type;
48 
49     template <class T>
50     struct apply :
51       curry_impl<
52         UnpackedMetafunctionClass,
53         typename boost::mpl::minus<
54           ArgumentsLeft,
55           boost::mpl::int_<1>
56         >::type,
57         typename boost::mpl::push_back<ArgumentList, T>::type
58       >
59     {};
60   };
61 
62 
63   template <
64     class UnpackedMetafunctionClass,
65     class ArgumentsLeft,
66     class ArgumentList
67   >
68   struct curry_impl :
69     boost::mpl::eval_if<
70       typename boost::mpl::equal_to<
71         ArgumentsLeft,
72         boost::mpl::int_<0>
73       >::type,
74       boost::mpl::apply<UnpackedMetafunctionClass, ArgumentList>,
75       next_currying_step<
76         UnpackedMetafunctionClass,
77         ArgumentsLeft,
78         ArgumentList
79       >
80     >
81   {};
82 }
83 
84 
85 template <class T>
86 struct curry0 : T {};
87 
88 #ifdef CURRY
89 #  error CURRY already defined
90 #endif
91 #define CURRY(z, n, unused) \
92   template <template <BOOST_PP_ENUM(n,class BOOST_PP_TUPLE_EAT(3),~)> class T> \
93   struct BOOST_PP_CAT(curry, n) : \
94     impl::curry_impl< \
95       boost::mpl::unpack_args<boost::mpl::BOOST_PP_CAT(quote, n) <T> >, \
96       boost::mpl::int_<n>, \
97       boost::mpl::deque<> \
98     >::type \
99   {};
100 
101 BOOST_PP_REPEAT_FROM_TO(1, CURRY_MAX_ARGUMENT, CURRY, ~)
102 
103 #undef CURRY
104 
105 #endif
106 
107