Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:01

0001 /*!
0002 @file
0003 Defines `boost::hana::ap`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
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     //! @cond
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     //! @endcond
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 }} // end namespace boost::hana
0077 
0078 #endif // !BOOST_HANA_AP_HPP