6#ifndef MIMICPP_ARGUMENT_LIST_HPP
7#define MIMICPP_ARGUMENT_LIST_HPP
20namespace mimicpp::detail
22 template <
typename ArgSelector,
typename ApplyStrategy>
27 explicit constexpr apply_args_fn(ArgSelector argSelector, ApplyStrategy applyStrategy)
29 std::is_nothrow_move_constructible_v<ArgSelector>
30 && std::is_nothrow_move_constructible_v<ApplyStrategy>)
31 : m_ArgSelector{std::move(argSelector)},
32 m_ApplyStrategy{std::move(applyStrategy)}
36 template <
typename Action,
typename Return,
typename... Args>
37 requires std::invocable<
const ArgSelector&,
const call::Info<Return, Args...>&>
41 std::invoke_result_t<
const ArgSelector&,
const call::Info<Return, Args...>&>>
42 constexpr decltype(
auto) operator()(Action&& action,
const call::Info<Return, Args...>& info)
const
44 std::is_nothrow_invocable_v<
const ArgSelector&,
const call::Info<Return, Args...>&>
45 && std::is_nothrow_invocable_v<
48 std::invoke_result_t<
const ArgSelector&,
const call::Info<Return, Args...>&>>)
52 std::forward<Action>(action),
53 std::invoke(m_ArgSelector, info));
57 ArgSelector m_ArgSelector;
58 ApplyStrategy m_ApplyStrategy;
61 template <
template <
typename>
typename TypeProjection,
typename IndexSequence>
62 struct args_selector_fn;
64 template <
template <
typename>
typename TypeProjection, std::size_t... indices>
65 struct args_selector_fn<TypeProjection, std::index_sequence<indices...>>
69 std::is_reference_v<TypeProjection<int&>>,
70 "Only use reference-projections.");
72 template <std::
size_t index,
typename Signature>
73 using projected_t = TypeProjection<signature_param_type_t<index, Signature>>;
75 template <
typename Return,
typename... Args>
76 constexpr auto operator()(
const call::Info<Return, Args...>& callInfo)
const noexcept
78 using signature_t = Return(Args...);
80 return std::forward_as_tuple(
81 static_cast<projected_t<indices, signature_t>
>(
83 std::get<indices>(callInfo.args).get())...);
87 template <
template <
typename>
typename TypeProjection>
88 struct all_args_selector_fn
91 template <
typename Return,
typename... Args>
92 constexpr auto operator()(
const call::Info<Return, Args...>& callInfo)
const noexcept
95 args_selector_fn<TypeProjection, std::index_sequence_for<Args...>>{},
100 struct arg_list_forward_apply_fn
103 template <
typename Fun,
typename... Args>
104 requires std::invocable<Fun, Args...>
105 constexpr decltype(
auto)
operator()(Fun&& fun, std::tuple<Args...>&& argList)
const
106 noexcept(std::is_nothrow_invocable_v<Fun, Args...>)
109 std::forward<Fun>(fun),
114 template <
typename... Projections>
115 struct arg_list_indirect_apply_fn
119 explicit constexpr arg_list_indirect_apply_fn(std::tuple<Projections...> projections = {})
120 noexcept(std::is_nothrow_move_constructible_v<std::tuple<Projections...>>)
121 : m_Projections{std::move(projections)}
125 template <
typename Fun,
typename... Args>
126 requires(... && std::invocable<const Projections&, Args>)
127 && std::invocable<Fun, std::invoke_result_t<const Projections&, Args>...>
128 constexpr decltype(
auto) operator()(Fun&& fun, std::tuple<Args...>&& argList)
const
130 (... && std::is_nothrow_invocable_v<const Projections&, Args>)
131 && std::is_nothrow_invocable_v<Fun, std::invoke_result_t<const Projections&, Args>...>)
134 std::forward<Fun>(fun),
136 std::index_sequence_for<Projections...>{});
140 std::tuple<Projections...> m_Projections;
142 template <
typename Fun,
typename... Args, std::size_t... indices>
143 constexpr decltype(
auto) invoke_impl(
145 std::tuple<Args...>&& argList,
146 [[maybe_unused]]
const std::index_sequence<indices...>)
const
149 std::forward<Fun>(fun),
151 std::get<indices>(m_Projections),
152 std::forward<Args>(std::get<indices>(argList)))...);