Iros
 
Loading...
Searching...
No Matches
chain.h
Go to the documentation of this file.
1#pragma once
2
5#include "di/function/piped.h"
7#include "di/meta/util.h"
8#include "di/util/forward.h"
9#include "di/util/move.h"
10
11namespace di::function {
12namespace detail {
13 template<typename F, typename G>
15 public:
16 template<typename Fn, typename Gn>
17 constexpr explicit ChainFunction(Fn&& f, Gn&& g) : m_f(util::forward<Fn>(f)), m_g(util::forward<Gn>(g)) {}
18
19 constexpr ChainFunction(ChainFunction const&) = default;
20 constexpr ChainFunction(ChainFunction&&) = default;
21
22 constexpr auto operator=(ChainFunction const&) -> ChainFunction& = delete;
23 constexpr auto operator=(ChainFunction&&) -> ChainFunction& = delete;
24
25 template<typename... Args>
26 requires(concepts::Invocable<F&, Args...> && concepts::Invocable<G&, meta::InvokeResult<F&, Args...>>)
27 constexpr auto operator()(Args&&... args) & -> decltype(auto) {
28 return function::invoke(m_g, function::invoke(m_f, util::forward<Args>(args)...));
29 }
30
31 template<typename... Args>
32 requires(concepts::Invocable<F const&, Args...> &&
33 concepts::Invocable<G const&, meta::InvokeResult<F const&, Args...>>)
34 constexpr auto operator()(Args&&... args) const& -> decltype(auto) {
35 return function::invoke(m_g, function::invoke(m_f, util::forward<Args>(args)...));
36 }
37
38 template<typename... Args>
39 requires(concepts::Invocable<F &&, Args...> && concepts::Invocable<G &&, meta::InvokeResult<F &&, Args...>>)
40 constexpr auto operator()(Args&&... args) && -> decltype(auto) {
41 return function::invoke(util::move(m_g), function::invoke(util::move(m_f), util::forward<Args>(args)...));
42 }
43
44 template<typename... Args>
45 requires(concepts::Invocable<F const &&, Args...> &&
46 concepts::Invocable<G const &&, meta::InvokeResult<F const &&, Args...>>)
47 constexpr auto operator()(Args&&... args) const&& -> decltype(auto) {
48 return function::invoke(util::move(m_g), function::invoke(util::move(m_f), util::forward<Args>(args)...));
49 }
50
51 private:
52 F m_f;
53 G m_g;
54 };
55}
56
57template<typename F>
59constexpr auto chain(F&& f) {
60 return function::piped(util::forward<F>(f));
61}
62
63template<typename F, typename G, typename... Fs>
66constexpr auto chain(F&& f, G&& g, Fs&&... rest) {
67 return function::chain(
68 detail::ChainFunction<meta::Decay<F>, meta::Decay<G>>(util::forward<F>(f), util::forward<G>(g)),
69 util::forward<Fs>(rest)...);
70}
71}
72
73namespace di {
74using function::chain;
75}
constexpr ChainFunction(ChainFunction &&)=default
constexpr auto operator=(ChainFunction &&) -> ChainFunction &=delete
constexpr ChainFunction(Fn &&f, Gn &&g)
Definition chain.h:17
constexpr ChainFunction(ChainFunction const &)=default
constexpr auto operator=(ChainFunction const &) -> ChainFunction &=delete
Definition operations.h:11
Definition invoke.h:58
Definition bind_back.h:16
Definition as_bool.h:8
constexpr auto invoke
Definition invoke.h:100
constexpr auto piped(F &&function)
Definition piped.h:56
constexpr auto chain(F &&f)
Definition chain.h:59
Conditional< concepts::LanguageArray< RemoveReference< T > >, RemoveExtent< RemoveReference< T > > *, Conditional< concepts::LanguageFunction< RemoveReference< T > >, AddPointer< RemoveReference< T > >, RemoveCVRef< T > > > Decay
Definition language.h:574
decltype(function::detail::invoke_impl(util::declval< Ts >()...)) InvokeResult
Definition invoke.h:64
Definition vocab.h:96
Definition zstring_parser.h:9