6#ifndef MIMICPP_POLICIES_ARGUMENT_LIST_HPP
7#define MIMICPP_POLICIES_ARGUMENT_LIST_HPP
14#ifndef MIMICPP_DETAIL_IS_MODULE
19 #include <type_traits>
23namespace mimicpp::detail
25 template <
typename ArgSelector,
typename ApplyStrategy>
30 explicit constexpr apply_args_fn(ArgSelector argSelector, ApplyStrategy applyStrategy)
32 std::is_nothrow_move_constructible_v<ArgSelector>
33 && std::is_nothrow_move_constructible_v<ApplyStrategy>)
34 : m_ArgSelector{std::move(argSelector)},
35 m_ApplyStrategy{std::move(applyStrategy)}
39 template <
typename Action,
typename Return,
typename... Args>
40 requires std::invocable<
const ArgSelector&,
const call::Info<Return, Args...>&>
44 std::invoke_result_t<
const ArgSelector&,
const call::Info<Return, Args...>&>>
45 constexpr decltype(
auto) operator()(Action&& action,
const call::Info<Return, Args...>& info)
const
47 std::is_nothrow_invocable_v<
const ArgSelector&,
const call::Info<Return, Args...>&>
48 && std::is_nothrow_invocable_v<
51 std::invoke_result_t<
const ArgSelector&,
const call::Info<Return, Args...>&>>)
55 std::forward<Action>(action),
56 std::invoke(m_ArgSelector, info));
60 ArgSelector m_ArgSelector;
61 ApplyStrategy m_ApplyStrategy;
64 template <
template <
typename>
typename TypeProjection,
typename IndexSequence>
65 struct args_selector_fn;
67 template <
template <
typename>
typename TypeProjection, std::size_t... indices>
68 struct args_selector_fn<TypeProjection, std::index_sequence<indices...>>
72 std::is_reference_v<TypeProjection<int&>>,
73 "Only use reference-projections.");
75 template <std::
size_t index,
typename Signature>
76 using projected_t = TypeProjection<signature_param_type_t<index, Signature>>;
78 template <
typename Return,
typename... Args>
79 constexpr auto operator()(
const call::Info<Return, Args...>& callInfo)
const noexcept
81 using signature_t = Return(Args...);
83 return std::forward_as_tuple(
84 static_cast<projected_t<indices, signature_t>
>(
86 std::get<indices>(callInfo.args).get())...);
90 template <
template <
typename>
typename TypeProjection>
91 struct all_args_selector_fn
94 template <
typename Return,
typename... Args>
95 constexpr auto operator()(
const call::Info<Return, Args...>& callInfo)
const noexcept
98 args_selector_fn<TypeProjection, std::index_sequence_for<Args...>>{},
103 struct arg_list_forward_apply_fn
106 template <
typename Fun,
typename... Args>
107 requires std::invocable<Fun, Args...>
108 constexpr decltype(
auto)
operator()(Fun&& fun, std::tuple<Args...>&& argList)
const
109 noexcept(std::is_nothrow_invocable_v<Fun, Args...>)
112 std::forward<Fun>(fun),
117 template <
typename... Projections>
118 struct arg_list_indirect_apply_fn
122 explicit constexpr arg_list_indirect_apply_fn(std::tuple<Projections...> projections = {})
123 noexcept(std::is_nothrow_move_constructible_v<std::tuple<Projections...>>)
124 : m_Projections{std::move(projections)}
128 template <
typename Fun,
typename... Args>
129 requires(... && std::invocable<const Projections&, Args>)
130 && std::invocable<Fun, std::invoke_result_t<const Projections&, Args>...>
131 constexpr decltype(
auto) operator()(Fun&& fun, std::tuple<Args...>&& argList)
const
133 (... && std::is_nothrow_invocable_v<const Projections&, Args>)
134 && std::is_nothrow_invocable_v<Fun, std::invoke_result_t<const Projections&, Args>...>)
137 std::forward<Fun>(fun),
139 std::index_sequence_for<Projections...>{});
143 std::tuple<Projections...> m_Projections;
145 template <
typename Fun,
typename... Args, std::size_t... indices>
146 constexpr decltype(
auto) invoke_impl(
148 std::tuple<Args...>&& argList,
149 [[maybe_unused]]
const std::index_sequence<indices...>)
const
152 std::forward<Fun>(fun),
154 std::get<indices>(m_Projections),
155 std::forward<Args>(std::get<indices>(argList)))...);