7#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_FUNCTIONAL_PERFECT_FORWARD_CALL_WRAPPER_HPP_
8#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_FUNCTIONAL_PERFECT_FORWARD_CALL_WRAPPER_HPP_
14#include "arene/base/constraints/constraints.hpp"
15#include "arene/base/stdlib_choice/enable_if.hpp"
16#include "arene/base/stdlib_choice/forward.hpp"
17#include "arene/base/stdlib_choice/is_constructible.hpp"
18#include "arene/base/stdlib_choice/move.hpp"
19#include "arene/base/stdlib_choice/tuple.hpp"
20#include "arene/base/type_manipulation/ebo_holder.hpp"
21#include "arene/base/type_traits/decays_to.hpp"
22#include "arene/base/type_traits/give_cvref_to.hpp"
23#include "arene/base/type_traits/is_invocable.hpp"
31namespace functional_detail {
39struct bound_args_tag {};
70template <
typename Policy,
typename Func,
typename... BoundArgs>
71class perfect_forward_call_wrapper
72 : ebo_holder<invoke_tag<perfect_forward_call_wrapper<Policy, Func, BoundArgs...>>, Func>
73 , ebo_holder<bound_args_tag<perfect_forward_call_wrapper<Policy, Func, BoundArgs...>>, std::tuple<BoundArgs...>> {
75 using bound_arg_tuple = std::tuple<BoundArgs...>;
78 using invocable_wrapper = ebo_holder<invoke_tag<perfect_forward_call_wrapper>, Func>;
81 using bound_args_wrapper = ebo_holder<bound_args_tag<perfect_forward_call_wrapper>, bound_arg_tuple>;
92 static constexpr auto invocable(Self&& self)
noexcept -> give_cvref_to_t<Self&&, Func> {
93 return static_cast<give_cvref_to_t<Self&&, invocable_wrapper>>(self).get_value(
94 invoke_tag<perfect_forward_call_wrapper>{}
102 template <
class Self>
103 static constexpr auto bound_args(Self&& self)
noexcept -> give_cvref_to_t<Self&&, std::tuple<BoundArgs...>> {
104 return static_cast<give_cvref_to_t<Self&&, bound_args_wrapper>>(self).get_value(
105 bound_args_tag<perfect_forward_call_wrapper>{}
115 constexpr perfect_forward_call_wrapper(perfect_forward_call_wrapper
const& copy) =
default;
117 constexpr perfect_forward_call_wrapper(perfect_forward_call_wrapper&& move) =
default;
119 constexpr auto operator=(perfect_forward_call_wrapper
const& copy) -> perfect_forward_call_wrapper& =
default;
121 constexpr auto operator=(perfect_forward_call_wrapper&& move) -> perfect_forward_call_wrapper& =
default;
132 typename... ArgsToBind,
134 std::enable_if_t<!decays_to_v<BoundFunc, perfect_forward_call_wrapper>>,
135 std::enable_if_t<std::is_constructible<Func, BoundFunc&&>::value>,
136 std::enable_if_t<std::is_constructible<std::tuple<BoundArgs...>, ArgsToBind&&...>::value>> =
nullptr>
137 constexpr explicit perfect_forward_call_wrapper(BoundFunc&& func_to_bind, ArgsToBind&&... args_to_bind)
noexcept(
138 std::is_nothrow_constructible<Func, BoundFunc&&>::value &&
139 std::is_nothrow_constructible<std::tuple<BoundArgs...>, ArgsToBind&&...>::value
141 : invocable_wrapper{std::forward<BoundFunc>(func_to_bind)},
142 bound_args_wrapper{std::forward<ArgsToBind>(args_to_bind)...} {
143 static_assert(
sizeof...(ArgsToBind) ==
sizeof...(BoundArgs),
"Must store all bound arguments");
147 ~perfect_forward_call_wrapper() =
default;
155 typename... CallArgsT,
156 constraints<std::enable_if_t<is_invocable_v<Policy, Func&, bound_arg_tuple&, CallArgsT&&...>>> =
nullptr>
157 constexpr auto operator()(CallArgsT&&... call_args) &
noexcept(
158 is_nothrow_invocable_v<Policy, Func&, bound_arg_tuple&, CallArgsT&&...>
159 ) -> invoke_result_t<Policy, Func&, bound_arg_tuple&, CallArgsT&&...> {
164 std::forward<CallArgsT>(call_args)...
175 typename... CallArgsT,
176 constraints<std::enable_if_t<!is_invocable_v<Policy, Func&, bound_arg_tuple&, CallArgsT&&...>>> =
nullptr>
177 constexpr auto operator()(CallArgsT&&... call_args) & =
delete;
186 typename... CallArgsT,
187 constraints<std::enable_if_t<is_invocable_v<Policy, Func
const&, bound_arg_tuple
const&, CallArgsT&&...>>> =
189 constexpr auto operator()(CallArgsT&&... call_args)
const&
noexcept(
190 is_nothrow_invocable_v<Policy, Func
const&, bound_arg_tuple
const&, CallArgsT&&...>
191 ) -> invoke_result_t<Policy, Func
const&, bound_arg_tuple
const&, CallArgsT&&...> {
196 std::forward<CallArgsT>(call_args)...
207 typename... CallArgsT,
208 constraints<std::enable_if_t<!is_invocable_v<Policy, Func
const&, bound_arg_tuple
const&, CallArgsT&&...>>> =
210 constexpr auto operator()(CallArgsT&&... call_args)
const& =
delete;
219 typename... CallArgsT,
220 constraints<std::enable_if_t<is_invocable_v<Policy, Func&&, bound_arg_tuple&&, CallArgsT&&...>>> =
nullptr>
221 constexpr auto operator()(CallArgsT&&... call_args) &&
noexcept(
222 is_nothrow_invocable_v<Policy, Func&&, bound_arg_tuple&&, CallArgsT&&...>
223 ) -> invoke_result_t<Policy, Func&&, bound_arg_tuple&&, CallArgsT&&...> {
226 invocable(std::move(*
this)),
227 bound_args(std::move(*
this)),
228 std::forward<CallArgsT>(call_args)...
239 typename... CallArgsT,
240 constraints<std::enable_if_t<!is_invocable_v<Policy, Func&&, bound_arg_tuple&&, CallArgsT&&...>>> =
nullptr>
241 constexpr auto operator()(CallArgsT&&... call_args) && =
delete;
250 typename... CallArgsT,
251 constraints<std::enable_if_t<is_invocable_v<Policy, Func
const&&, bound_arg_tuple
const&&, CallArgsT&&...>>> =
253 constexpr auto operator()(CallArgsT&&... call_args)
const&&
noexcept(
254 is_nothrow_invocable_v<Policy, Func
const&&, bound_arg_tuple
const&&, CallArgsT&&...>
255 ) -> invoke_result_t<Policy, Func
const&&, bound_arg_tuple
const&&, CallArgsT&&...> {
259 invocable(std::move(*
this)),
260 bound_args(std::move(*
this)),
261 std::forward<CallArgsT>(call_args)...
273 typename... CallArgsT,
274 constraints<std::enable_if_t<!is_invocable_v<Policy, Func
const&&, bound_arg_tuple
const&&, CallArgsT&&...>>> =
276 constexpr auto operator()(CallArgsT&&... call_args)
const&& =
delete;
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10