curry.hpp 2.4 KB

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