File indexing completed on 2025-01-18 09:38:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_AP_HPP
0011 #define BOOST_HANA_AP_HPP
0012
0013 #include <boost/hana/fwd/ap.hpp>
0014
0015 #include <boost/hana/chain.hpp>
0016 #include <boost/hana/concept/applicative.hpp>
0017 #include <boost/hana/concept/sequence.hpp>
0018 #include <boost/hana/config.hpp>
0019 #include <boost/hana/core/dispatch.hpp>
0020 #include <boost/hana/detail/variadic/foldl1.hpp>
0021 #include <boost/hana/functional/curry.hpp>
0022 #include <boost/hana/functional/partial.hpp>
0023 #include <boost/hana/transform.hpp>
0024
0025
0026 namespace boost { namespace hana {
0027 template <typename A, bool condition>
0028 struct ap_impl<A, when<condition>> : default_ {
0029 template <typename ...Args>
0030 static constexpr auto apply(Args&& ...args) = delete;
0031 };
0032
0033
0034 template <typename F, typename X>
0035 constexpr decltype(auto) ap_t::operator()(F&& f, X&& x) const {
0036 using Function = typename hana::tag_of<F>::type;
0037 using Value = typename hana::tag_of<X>::type;
0038 using Ap = BOOST_HANA_DISPATCH_IF(ap_impl<Function>,
0039 hana::Applicative<Function>::value && hana::Applicative<Value>::value
0040 );
0041
0042 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0043 static_assert(hana::Applicative<Function>::value,
0044 "hana::ap(f, x) requires 'f' to be an Applicative");
0045
0046 static_assert(hana::Applicative<Value>::value,
0047 "hana::ap(f, x) requires 'x' to be an Applicative");
0048 #endif
0049
0050 return Ap::apply(static_cast<F&&>(f), static_cast<X&&>(x));
0051 }
0052
0053 template <typename F, typename ...Xs>
0054 constexpr decltype(auto) ap_t::operator()(F&& f, Xs&& ...xs) const {
0055 static_assert(sizeof...(xs) >= 1,
0056 "hana::ap must be called with at least two arguments");
0057
0058 return detail::variadic::foldl1(
0059 *this,
0060 hana::transform(static_cast<F&&>(f), hana::curry<sizeof...(xs)>),
0061 static_cast<Xs&&>(xs)...
0062 );
0063 }
0064
0065
0066 template <typename S>
0067 struct ap_impl<S, when<Sequence<S>::value>> {
0068 template <typename F, typename X>
0069 static constexpr decltype(auto) apply(F&& f, X&& x) {
0070 return hana::chain(
0071 static_cast<F&&>(f),
0072 hana::partial(hana::transform, static_cast<X&&>(x))
0073 );
0074 }
0075 };
0076 }}
0077
0078 #endif