File indexing completed on 2025-01-18 09:37:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_FUNCTIONAL_CURRY_HPP
0011 #define BOOST_HANA_FUNCTIONAL_CURRY_HPP
0012
0013 #include <boost/hana/config.hpp>
0014 #include <boost/hana/detail/decay.hpp>
0015 #include <boost/hana/functional/apply.hpp>
0016 #include <boost/hana/functional/partial.hpp>
0017
0018 #include <cstddef>
0019 #include <type_traits>
0020 #include <utility>
0021
0022
0023 namespace boost { namespace hana {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0087 template <std::size_t n>
0088 constexpr auto curry = [](auto&& f) {
0089 return [perfect-capture](auto&& x1) {
0090 return [perfect-capture](auto&& x2) {
0091 ...
0092 return [perfect-capture](auto&& xn) -> decltype(auto) {
0093 return forwarded(f)(
0094 forwarded(x1), forwarded(x2), ..., forwarded(xn)
0095 );
0096 };
0097 };
0098 };
0099 };
0100 #else
0101 template <std::size_t n, typename F>
0102 struct curry_t;
0103
0104 template <std::size_t n>
0105 struct make_curry_t {
0106 template <typename F>
0107 constexpr curry_t<n, typename detail::decay<F>::type>
0108 operator()(F&& f) const { return {static_cast<F&&>(f)}; }
0109 };
0110
0111 template <std::size_t n>
0112 BOOST_HANA_INLINE_VARIABLE constexpr make_curry_t<n> curry{};
0113
0114 namespace curry_detail { namespace {
0115 template <std::size_t n>
0116 constexpr make_curry_t<n> curry_or_call{};
0117
0118 template <>
0119 constexpr auto curry_or_call<0> = apply;
0120 }}
0121
0122 template <std::size_t n, typename F>
0123 struct curry_t {
0124 F f;
0125
0126 template <typename ...X>
0127 constexpr decltype(auto) operator()(X&& ...x) const& {
0128 static_assert(sizeof...(x) <= n,
0129 "too many arguments provided to boost::hana::curry");
0130 return curry_detail::curry_or_call<n - sizeof...(x)>(
0131 partial(f, static_cast<X&&>(x)...)
0132 );
0133 }
0134
0135 template <typename ...X>
0136 constexpr decltype(auto) operator()(X&& ...x) & {
0137 static_assert(sizeof...(x) <= n,
0138 "too many arguments provided to boost::hana::curry");
0139 return curry_detail::curry_or_call<n - sizeof...(x)>(
0140 partial(f, static_cast<X&&>(x)...)
0141 );
0142 }
0143
0144 template <typename ...X>
0145 constexpr decltype(auto) operator()(X&& ...x) && {
0146 static_assert(sizeof...(x) <= n,
0147 "too many arguments provided to boost::hana::curry");
0148 return curry_detail::curry_or_call<n - sizeof...(x)>(
0149 partial(std::move(f), static_cast<X&&>(x)...)
0150 );
0151 }
0152 };
0153
0154 template <typename F>
0155 struct curry_t<0, F> {
0156 F f;
0157
0158 constexpr decltype(auto) operator()() const&
0159 { return f(); }
0160
0161 constexpr decltype(auto) operator()() &
0162 { return f(); }
0163
0164 constexpr decltype(auto) operator()() &&
0165 { return std::move(f)(); }
0166 };
0167 #endif
0168 }}
0169
0170 #endif