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::reverse_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_REVERSE_PARTIAL_HPP
0011 #define BOOST_HANA_FUNCTIONAL_REVERSE_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, `reverse_partial` returns a
0026     //! new function corresponding to `f` whose last arguments are partially
0027     //! applied. Specifically, `reverse_partial(f, x...)` is a function such
0028     //! that
0029     //! @code
0030     //!     reverse_partial(f, x...)(y...) == f(y..., x...)
0031     //! @endcode
0032     //!
0033     //! @note
0034     //! The arity of `f` must match the total number of arguments passed to
0035     //! it, i.e. `sizeof...(x) + sizeof...(y)`.
0036     //!
0037     //!
0038     //! Example
0039     //! -------
0040     //! @include example/functional/reverse_partial.cpp
0041 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0042     constexpr auto reverse_partial = [](auto&& f, auto&& ...x) {
0043         return [perfect-capture](auto&& ...y) -> decltype(auto) {
0044             return forwarded(f)(forwarded(y)..., forwarded(x)...);
0045         };
0046     };
0047 #else
0048     template <typename Indices, typename F, typename ...X>
0049     struct reverse_partial_t;
0050 
0051     struct make_reverse_partial_t {
0052         struct secret { };
0053         template <typename F, typename ...X>
0054         constexpr reverse_partial_t<
0055             std::make_index_sequence<sizeof...(X)>,
0056             typename detail::decay<F>::type,
0057             typename detail::decay<X>::type...
0058         > operator()(F&& f, X&& ...x) const {
0059             return {secret{}, static_cast<F&&>(f), static_cast<X&&>(x)...};
0060         }
0061     };
0062 
0063     template <std::size_t ...n, typename F, typename ...X>
0064     struct reverse_partial_t<std::index_sequence<n...>, F, X...> {
0065         reverse_partial_t() = default;
0066 
0067         template <typename ...T>
0068         constexpr reverse_partial_t(make_reverse_partial_t::secret, T&& ...t)
0069             : storage_{static_cast<T&&>(t)...}
0070         { }
0071 
0072         basic_tuple<F, X...> storage_;
0073 
0074         template <typename ...Y>
0075         constexpr decltype(auto) operator()(Y&& ...y) const& {
0076             return hana::at_c<0>(storage_)(
0077                 static_cast<Y&&>(y)...,
0078                 hana::at_c<n+1>(storage_)...
0079             );
0080         }
0081 
0082         template <typename ...Y>
0083         constexpr decltype(auto) operator()(Y&& ...y) & {
0084             return hana::at_c<0>(storage_)(
0085                 static_cast<Y&&>(y)...,
0086                 hana::at_c<n+1>(storage_)...
0087             );
0088         }
0089 
0090         template <typename ...Y>
0091         constexpr decltype(auto) operator()(Y&& ...y) && {
0092             return static_cast<F&&>(hana::at_c<0>(storage_))(
0093                 static_cast<Y&&>(y)...,
0094                 static_cast<X&&>(hana::at_c<n+1>(storage_))...
0095             );
0096         }
0097     };
0098 
0099     BOOST_HANA_INLINE_VARIABLE constexpr make_reverse_partial_t reverse_partial{};
0100 #endif
0101 }} // end namespace boost::hana
0102 
0103 #endif // !BOOST_HANA_FUNCTIONAL_REVERSE_PARTIAL_HPP