]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/hana/functional/reverse_partial.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / hana / functional / reverse_partial.hpp
1 /*!
2 @file
3 Defines `boost::hana::reverse_partial`.
4
5 @copyright Louis Dionne 2013-2017
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10 #ifndef BOOST_HANA_FUNCTIONAL_REVERSE_PARTIAL_HPP
11 #define BOOST_HANA_FUNCTIONAL_REVERSE_PARTIAL_HPP
12
13 #include <boost/hana/basic_tuple.hpp>
14 #include <boost/hana/config.hpp>
15 #include <boost/hana/detail/decay.hpp>
16
17 #include <cstddef>
18 #include <utility>
19
20
21 BOOST_HANA_NAMESPACE_BEGIN
22 //! @ingroup group-functional
23 //! Partially apply a function to some arguments.
24 //!
25 //! Given a function `f` and some arguments, `reverse_partial` returns a
26 //! new function corresponding to `f` whose last arguments are partially
27 //! applied. Specifically, `reverse_partial(f, x...)` is a function such
28 //! that
29 //! @code
30 //! reverse_partial(f, x...)(y...) == f(y..., x...)
31 //! @endcode
32 //!
33 //! @note
34 //! The arity of `f` must match the total number of arguments passed to
35 //! it, i.e. `sizeof...(x) + sizeof...(y)`.
36 //!
37 //!
38 //! Example
39 //! -------
40 //! @include example/functional/reverse_partial.cpp
41 #ifdef BOOST_HANA_DOXYGEN_INVOKED
42 constexpr auto reverse_partial = [](auto&& f, auto&& ...x) {
43 return [perfect-capture](auto&& ...y) -> decltype(auto) {
44 return forwarded(f)(forwarded(y)..., forwarded(x)...);
45 };
46 };
47 #else
48 template <typename Indices, typename F, typename ...X>
49 struct reverse_partial_t;
50
51 struct make_reverse_partial_t {
52 struct secret { };
53 template <typename F, typename ...X>
54 constexpr reverse_partial_t<
55 std::make_index_sequence<sizeof...(X)>,
56 typename detail::decay<F>::type,
57 typename detail::decay<X>::type...
58 > operator()(F&& f, X&& ...x) const {
59 return {secret{}, static_cast<F&&>(f), static_cast<X&&>(x)...};
60 }
61 };
62
63 template <std::size_t ...n, typename F, typename ...X>
64 struct reverse_partial_t<std::index_sequence<n...>, F, X...> {
65 reverse_partial_t() = default;
66
67 template <typename ...T>
68 constexpr reverse_partial_t(make_reverse_partial_t::secret, T&& ...t)
69 : storage_{static_cast<T&&>(t)...}
70 { }
71
72 basic_tuple<F, X...> storage_;
73
74 template <typename ...Y>
75 constexpr decltype(auto) operator()(Y&& ...y) const& {
76 return hana::at_c<0>(storage_)(
77 static_cast<Y&&>(y)...,
78 hana::at_c<n+1>(storage_)...
79 );
80 }
81
82 template <typename ...Y>
83 constexpr decltype(auto) operator()(Y&& ...y) & {
84 return hana::at_c<0>(storage_)(
85 static_cast<Y&&>(y)...,
86 hana::at_c<n+1>(storage_)...
87 );
88 }
89
90 template <typename ...Y>
91 constexpr decltype(auto) operator()(Y&& ...y) && {
92 return static_cast<F&&>(hana::at_c<0>(storage_))(
93 static_cast<Y&&>(y)...,
94 static_cast<X&&>(hana::at_c<n+1>(storage_))...
95 );
96 }
97 };
98
99 constexpr make_reverse_partial_t reverse_partial{};
100 #endif
101 BOOST_HANA_NAMESPACE_END
102
103 #endif // !BOOST_HANA_FUNCTIONAL_REVERSE_PARTIAL_HPP