Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:58

0001 /*!
0002 @file
0003 Defines `boost::hana::partial`.
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_FUNCTIONAL_PARTIAL_HPP
0011 #define BOOST_HANA_FUNCTIONAL_PARTIAL_HPP
0012 
0013 #include <boost/hana/basic_tuple.hpp>
0014 #include <boost/hana/config.hpp>
0015 #include <boost/hana/detail/decay.hpp>
0016 
0017 #include <cstddef>
0018 #include <utility>
0019 
0020 
0021 namespace boost { namespace hana {
0022     //! @ingroup group-functional
0023     //! Partially apply a function to some arguments.
0024     //!
0025     //! Given a function `f` and some arguments, `partial` returns a new
0026     //! function corresponding to the partially applied function `f`. This
0027     //! allows providing some arguments to a function and letting the rest
0028     //! of the arguments be provided later. Specifically, `partial(f, x...)`
0029     //! is a function such that
0030     //! @code
0031     //!     partial(f, x...)(y...) == f(x..., y...)
0032     //! @endcode
0033     //!
0034     //! @note
0035     //! The arity of `f` must match the total number of arguments passed to
0036     //! it, i.e. `sizeof...(x) + sizeof...(y)`.
0037     //!
0038     //!
0039     //! Example
0040     //! -------
0041     //! @include example/functional/partial.cpp
0042 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0043     constexpr auto partial = [](auto&& f, auto&& ...x) {
0044         return [perfect-capture](auto&& ...y) -> decltype(auto) {
0045             return forwarded(f)(forwarded(x)..., forwarded(y)...);
0046         };
0047     };
0048 #else
0049     template <typename Indices, typename F, typename ...X>
0050     struct partial_t;
0051 
0052     struct make_partial_t {
0053         struct secret { };
0054         template <typename F, typename ...X>
0055         constexpr partial_t<
0056             std::make_index_sequence<sizeof...(X)>,
0057             typename detail::decay<F>::type,
0058             typename detail::decay<X>::type...
0059         >
0060         operator()(F&& f, X&& ...x) const {
0061             return {secret{}, static_cast<F&&>(f), static_cast<X&&>(x)...};
0062         }
0063     };
0064 
0065     template <std::size_t ...n, typename F, typename ...X>
0066     struct partial_t<std::index_sequence<n...>, F, X...> {
0067         partial_t() = default;
0068 
0069         template <typename ...T>
0070         constexpr partial_t(make_partial_t::secret, T&& ...t)
0071             : storage_{static_cast<T&&>(t)...}
0072         { }
0073 
0074         basic_tuple<F, X...> storage_;
0075 
0076         template <typename ...Y>
0077         constexpr decltype(auto) operator()(Y&& ...y) const& {
0078             return hana::at_c<0>(storage_)(
0079                 hana::at_c<n+1>(storage_)...,
0080                 static_cast<Y&&>(y)...
0081             );
0082         }
0083 
0084         template <typename ...Y>
0085         constexpr decltype(auto) operator()(Y&& ...y) & {
0086             return hana::at_c<0>(storage_)(
0087                 hana::at_c<n+1>(storage_)...,
0088                 static_cast<Y&&>(y)...
0089             );
0090         }
0091 
0092         template <typename ...Y>
0093         constexpr decltype(auto) operator()(Y&& ...y) && {
0094             return static_cast<F&&>(hana::at_c<0>(storage_))(
0095                 static_cast<X&&>(hana::at_c<n+1>(storage_))...,
0096                 static_cast<Y&&>(y)...
0097             );
0098         }
0099     };
0100 
0101     BOOST_HANA_INLINE_VARIABLE constexpr make_partial_t partial{};
0102 #endif
0103 }} // end namespace boost::hana
0104 
0105 #endif // !BOOST_HANA_FUNCTIONAL_PARTIAL_HPP