Blame view

3rdparty/boost_1_81_0/boost/hana/functional/compose.hpp 3.35 KB
63e88f80   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  /*!
  @file
  Defines `boost::hana::compose`.
  
  Copyright Louis Dionne 2013-2022
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
   */
  
  #ifndef BOOST_HANA_FUNCTIONAL_COMPOSE_HPP
  #define BOOST_HANA_FUNCTIONAL_COMPOSE_HPP
  
  #include <boost/hana/config.hpp>
  #include <boost/hana/detail/create.hpp>
  #include <boost/hana/detail/variadic/foldl1.hpp>
  
  #include <utility>
  
  
  namespace boost { namespace hana {
      //! @ingroup group-functional
      //! Return the composition of two functions or more.
      //!
      //! `compose` is defined inductively. When given more than two functions,
      //! `compose(f, g, h...)` is equivalent to `compose(f, compose(g, h...))`.
      //! When given two functions, `compose(f, g)` is a function such that
      //! @code
      //!     compose(f, g)(x, y...) == f(g(x), y...)
      //! @endcode
      //!
      //! If you need composition of the form `f(g(x, y...))`, use `demux` instead.
      //!
      //! @note
      //! `compose` is an associative operation; `compose(f, compose(g, h))`
      //! is equivalent to `compose(compose(f, g), h)`.
      //!
      //! @internal
      //! ### Proof of associativity
      //!
      //! @code
      //!     compose(f, compose(g, h))(x, xs...) == f(compose(g, h)(x), xs...)
      //!                                         == f(g(h(x)), xs...)
      //!
      //!     compose(compose(f, g), h)(x, xs...) == compose(f, g)(h(x), xs...)
      //!                                         == f(g(h(x)), xs...)
      //! @endcode
      //! @endinternal
      //!
      //! ### Example
      //! @include example/functional/compose.cpp
  #ifdef BOOST_HANA_DOXYGEN_INVOKED
      constexpr auto compose = [](auto&& f1, auto&& f2, ..., auto&& fn) {
          return [perfect-capture](auto&& x, auto&& ...xs) -> decltype(auto) {
              return forwarded(f1)(
                      forwarded(f2)(
                       ...
                        forwarded(fn)(forwarded(x))
                      ),
                      forwarded(xs)...
                  );
          }
      };
  #else
      template <typename F, typename G>
      struct _compose {
          F f; G g;
  
          template <typename X, typename ...Xs>
          constexpr decltype(auto) operator()(X&& x, Xs&& ...xs) const& {
              return f(
                  g(static_cast<X&&>(x)),
                  static_cast<Xs&&>(xs)...
              );
          }
  
          template <typename X, typename ...Xs>
          constexpr decltype(auto) operator()(X&& x, Xs&& ...xs) & {
              return f(
                  g(static_cast<X&&>(x)),
                  static_cast<Xs&&>(xs)...
              );
          }
  
          template <typename X, typename ...Xs>
          constexpr decltype(auto) operator()(X&& x, Xs&& ...xs) && {
              return std::move(f)(
                  std::move(g)(static_cast<X&&>(x)),
                  static_cast<Xs&&>(xs)...
              );
          }
      };
  
      struct _make_compose {
          template <typename F, typename G, typename ...H>
          constexpr decltype(auto) operator()(F&& f, G&& g, H&& ...h) const {
              return detail::variadic::foldl1(detail::create<_compose>{},
                  static_cast<F&&>(f),
                  static_cast<G&&>(g),
                  static_cast<H&&>(h)...
              );
          }
      };
  
      BOOST_HANA_INLINE_VARIABLE constexpr _make_compose compose{};
  #endif
  }} // end namespace boost::hana
  
  #endif // !BOOST_HANA_FUNCTIONAL_COMPOSE_HPP