3 Defines `boost::hana::on`.
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)
10 #ifndef BOOST_HANA_FUNCTIONAL_ON_HPP
11 #define BOOST_HANA_FUNCTIONAL_ON_HPP
13 #include <boost/hana/config.hpp>
14 #include <boost/hana/detail/create.hpp>
15 #include <boost/hana/functional/infix.hpp>
20 BOOST_HANA_NAMESPACE_BEGIN
21 //! @ingroup group-functional
22 //! Invoke a function with the result of invoking another function on
25 //! Specifically, `on(f, g)` is a function such that
27 //! on(f, g)(x...) == f(g(x)...)
30 //! For convenience, `on` also supports infix application as provided
35 //! `on` is associative, i.e. `on(f, on(g, h))` is equivalent to
36 //! `on(on(f, g), h)`.
39 //! ### Proof of associativity
42 //! on(f, on(g, h))(xs...) == f(on(g, h)(xs)...)
45 //! on(on(f, g), h)(xs...) == on(f, g)(h(xs)...)
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))...);
60 template <typename F, typename G>
63 template <typename ...X>
64 constexpr decltype(auto) operator()(X&& ...x) const& {
65 return f(g(static_cast<X&&>(x))...);
68 template <typename ...X>
69 constexpr decltype(auto) operator()(X&& ...x) & {
70 return f(g(static_cast<X&&>(x))...);
73 template <typename ...X>
74 constexpr decltype(auto) operator()(X&& ...x) && {
75 return std::move(f)(g(static_cast<X&&>(x))...);
79 constexpr auto on = infix(detail::create<on_t>{});
81 BOOST_HANA_NAMESPACE_END
83 #endif // !BOOST_HANA_FUNCTIONAL_ON_HPP