6#ifndef SL_UTILITY_FUNCTIONAL_BIND_BACK_HPP
7#define SL_UTILITY_FUNCTIONAL_BIND_BACK_HPP
19namespace sl::functional::detail
21 template <
class Fn,
class BoundArgsTuple,
class... CallArgs>
22 constexpr decltype(
auto) call_bind_back(Fn&& func, BoundArgsTuple&& boundArgsTuple, CallArgs&&... callArgs)
25 [&]<
class... TArgs>(TArgs&&... boundArgs) ->
decltype(
auto)
28 std::forward<Fn>(func),
29 std::forward<CallArgs>(callArgs)...,
30 std::forward<TArgs>(boundArgs)...);
32 std::forward<BoundArgsTuple>(boundArgsTuple));
35 template <
class Fn,
class... BoundArgs>
39 template <
class FnCTorArg,
class... CTorArgs>
40 requires (
sizeof...(CTorArgs) != 0 && !std::derived_from<std::remove_cvref_t<FnCTorArg>, BindBack>)
41 explicit constexpr BindBack(FnCTorArg&& fn, CTorArgs&&... ctorArgs)
42 : m_Fn{std::forward<FnCTorArg>(fn)},
43 m_BoundArgs{std::forward<CTorArgs>(ctorArgs)...}
47 template <
class... CallArgs>
48 requires std::invocable<
const Fn&, CallArgs...,
const BoundArgs&...>
49 constexpr decltype(
auto)
operator()(
50 CallArgs&&... callArgs
51 )
const &
noexcept(std::is_nothrow_invocable_v<const Fn&, CallArgs..., const BoundArgs&...>)
53 return call_bind_back(m_Fn, m_BoundArgs, std::forward<CallArgs>(callArgs)...);
56 template <
class... CallArgs>
57 requires std::invocable<Fn&, CallArgs..., BoundArgs&...>
58 constexpr decltype(
auto)
operator()(
59 CallArgs&&... callArgs
60 ) &
noexcept(std::is_nothrow_invocable_v<Fn&, CallArgs..., BoundArgs&...>)
62 return call_bind_back(m_Fn, m_BoundArgs, std::forward<CallArgs>(callArgs)...);
65 template <
class... CallArgs>
66 requires std::invocable<
const Fn&&, CallArgs...,
const BoundArgs&&...>
67 constexpr decltype(
auto)
operator()(
68 CallArgs&&... callArgs
69 )
const &&
noexcept(std::is_nothrow_invocable_v<const Fn&&, CallArgs..., const BoundArgs&&...>)
71 return call_bind_back(std::move(m_Fn), std::move(m_BoundArgs), std::forward<CallArgs>(callArgs)...);
74 template <
class... CallArgs>
75 requires std::invocable<Fn&&, CallArgs..., BoundArgs&&...>
76 constexpr decltype(
auto)
operator()(
77 CallArgs&&... callArgs
78 ) &&
noexcept(std::is_nothrow_invocable_v<Fn&&, CallArgs..., BoundArgs&&...>)
80 return call_bind_back(std::move(m_Fn), std::move(m_BoundArgs), std::forward<CallArgs>(callArgs)...);
86 std::tuple<BoundArgs...> m_BoundArgs{};
89 template <
class TFunc,
class... TBoundArgs>
90 BindBack(TFunc, TBoundArgs...) -> BindBack<TFunc, std::unwrap_ref_decay_t<TBoundArgs>...>;
100 inline constexpr auto bind_back = []<
class Fn, class... BoundArgs>(
102 BoundArgs&&... boundArgs
103 )
noexcept(std::is_nothrow_constructible_v<std::remove_cvref_t<Fn>, Fn>
104 && (... && std::is_nothrow_constructible_v<std::unwrap_ref_decay_t<BoundArgs>, BoundArgs>))
106 return detail::BindBack{std::forward<Fn>(func), std::forward<BoundArgs>(boundArgs)...};
#define SL_UTILITY_NO_UNIQUE_ADDRESS
Definition: Config.hpp:21
constexpr auto bind_back
Helper function, which generates a forwarding call wrapper for the given function and curries the par...
Definition: bind_back.hpp:100
Definition: Arithmetic.hpp:13