]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/include/boost/hana/functional/on.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / functional / on.hpp
1 /*!
2 @file
3 Defines `boost::hana::on`.
4
5 @copyright Louis Dionne 2013-2016
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_ON_HPP
11 #define BOOST_HANA_FUNCTIONAL_ON_HPP
12
13 #include <boost/hana/config.hpp>
14 #include <boost/hana/detail/create.hpp>
15 #include <boost/hana/functional/infix.hpp>
16
17 #include <utility>
18
19
20 BOOST_HANA_NAMESPACE_BEGIN
21 //! @ingroup group-functional
22 //! Invoke a function with the result of invoking another function on
23 //! each argument.
24 //!
25 //! Specifically, `on(f, g)` is a function such that
26 //! @code
27 //! on(f, g)(x...) == f(g(x)...)
28 //! @endcode
29 //!
30 //! For convenience, `on` also supports infix application as provided
31 //! by `infix`.
32 //!
33 //!
34 //! @note
35 //! `on` is associative, i.e. `on(f, on(g, h))` is equivalent to
36 //! `on(on(f, g), h)`.
37 //!
38 //! @internal
39 //! ### Proof of associativity
40 //!
41 //! @code
42 //! on(f, on(g, h))(xs...) == f(on(g, h)(xs)...)
43 //! == f(g(h(xs))...)
44 //!
45 //! on(on(f, g), h)(xs...) == on(f, g)(h(xs)...)
46 //! == f(g(h(xs))...)
47 //! @endcode
48 //! @endinternal
49 //!
50 //!
51 //! ### Example
52 //! @include example/functional/on.cpp
53 #ifdef BOOST_HANA_DOXYGEN_INVOKED
54 constexpr auto on = infix([](auto&& f, auto&& g) {
55 return [perfect-capture](auto&& ...x) -> decltype(auto) {
56 return forwarded(f)(g(forwarded(x))...);
57 };
58 });
59 #else
60 template <typename F, typename G>
61 struct on_t {
62 F f; G g;
63 template <typename ...X>
64 constexpr decltype(auto) operator()(X&& ...x) const& {
65 return f(g(static_cast<X&&>(x))...);
66 }
67
68 template <typename ...X>
69 constexpr decltype(auto) operator()(X&& ...x) & {
70 return f(g(static_cast<X&&>(x))...);
71 }
72
73 template <typename ...X>
74 constexpr decltype(auto) operator()(X&& ...x) && {
75 return std::move(f)(g(static_cast<X&&>(x))...);
76 }
77 };
78
79 constexpr auto on = infix(detail::create<on_t>{});
80 #endif
81 BOOST_HANA_NAMESPACE_END
82
83 #endif // !BOOST_HANA_FUNCTIONAL_ON_HPP