123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #ifndef BOOST_HANA_FUNCTIONAL_CURRY_HPP
- #define BOOST_HANA_FUNCTIONAL_CURRY_HPP
- #include <boost/hana/config.hpp>
- #include <boost/hana/detail/decay.hpp>
- #include <boost/hana/functional/apply.hpp>
- #include <boost/hana/functional/partial.hpp>
- #include <cstddef>
- #include <type_traits>
- #include <utility>
- BOOST_HANA_NAMESPACE_BEGIN
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #ifdef BOOST_HANA_DOXYGEN_INVOKED
- template <std::size_t n>
- constexpr auto curry = [](auto&& f) {
- return [perfect-capture](auto&& x1) {
- return [perfect-capture](auto&& x2) {
- ...
- return [perfect-capture](auto&& xn) -> decltype(auto) {
- return forwarded(f)(
- forwarded(x1), forwarded(x2), ..., forwarded(xn)
- );
- };
- };
- };
- };
- #else
- template <std::size_t n, typename F>
- struct curry_t;
- template <std::size_t n>
- struct make_curry_t {
- template <typename F>
- constexpr curry_t<n, typename detail::decay<F>::type>
- operator()(F&& f) const { return {static_cast<F&&>(f)}; }
- };
- template <std::size_t n>
- constexpr make_curry_t<n> curry{};
- namespace curry_detail { namespace {
- template <std::size_t n>
- constexpr make_curry_t<n> curry_or_call{};
- template <>
- constexpr auto curry_or_call<0> = apply;
- }}
- template <std::size_t n, typename F>
- struct curry_t {
- F f;
- template <typename ...X>
- constexpr decltype(auto) operator()(X&& ...x) const& {
- static_assert(sizeof...(x) <= n,
- "too many arguments provided to boost::hana::curry");
- return curry_detail::curry_or_call<n - sizeof...(x)>(
- partial(f, static_cast<X&&>(x)...)
- );
- }
- template <typename ...X>
- constexpr decltype(auto) operator()(X&& ...x) & {
- static_assert(sizeof...(x) <= n,
- "too many arguments provided to boost::hana::curry");
- return curry_detail::curry_or_call<n - sizeof...(x)>(
- partial(f, static_cast<X&&>(x)...)
- );
- }
- template <typename ...X>
- constexpr decltype(auto) operator()(X&& ...x) && {
- static_assert(sizeof...(x) <= n,
- "too many arguments provided to boost::hana::curry");
- return curry_detail::curry_or_call<n - sizeof...(x)>(
- partial(std::move(f), static_cast<X&&>(x)...)
- );
- }
- };
- template <typename F>
- struct curry_t<0, F> {
- F f;
- constexpr decltype(auto) operator()() const&
- { return f(); }
- constexpr decltype(auto) operator()() &
- { return f(); }
- constexpr decltype(auto) operator()() &&
- { return std::move(f)(); }
- };
- #endif
- BOOST_HANA_NAMESPACE_END
- #endif
|