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