16 #include "Utilities/TaggedTuple.hpp"
19 namespace elliptic::util {
22 template <
bool PassThrough,
typename... MapKeys>
25 template <
typename... MapKeys>
26 struct unmap_arg<true, MapKeys...> {
28 static constexpr
const T&
apply(
41 template <
typename FirstMapKey,
typename... MapKeys>
42 struct unmap_arg<false, FirstMapKey, MapKeys...> {
44 static constexpr decltype(
auto) apply(
46 const std::tuple<FirstMapKey, MapKeys...>& map_keys) noexcept {
47 return unmap_arg<
sizeof...(MapKeys) == 0, MapKeys...>::
apply(
48 arg.at(std::get<0>(map_keys)),
53 static constexpr decltype(
auto) apply(
54 const
gsl::not_null<T*> arg,
55 const std::tuple<FirstMapKey, MapKeys...>& map_keys) noexcept {
56 return unmap_arg<
sizeof...(MapKeys) == 0, MapKeys...>::
apply(
62 template <
typename...
ArgumentTags,
typename PassthroughArgumentTags,
63 typename F,
typename TaggedContainer,
typename... MapKeys,
66 F&& f, const TaggedContainer& box, const std::tuple<MapKeys...>& map_keys,
68 Args&&... args) noexcept {
70 using ::tuples::apply;
72 [&f, &map_keys, &args...](
const auto&... args_items) noexcept {
74 return std::forward<F>(f)(
76 tmpl::list_contains_v<PassthroughArgumentTags, ArgumentTags>,
77 MapKeys...>::apply(args_items, map_keys)...,
78 std::forward<Args>(args)...);
105 template <
typename ArgumentTags,
typename PassthroughArgumentTags,
106 typename... MapKeys,
typename F,
typename TaggedContainer,
109 F&& f, const TaggedContainer& box, const std::tuple<MapKeys...>& map_keys,
110 Args&&... args) noexcept {
111 return detail::apply_at(std::forward<F>(f), box, map_keys,
ArgumentTags{},
112 PassthroughArgumentTags{},
113 std::forward<Args>(args)...);
116 template <
typename ArgumentTags,
typename PassthroughArgumentTags,
117 typename MapKey,
typename F,
typename TaggedContainer,
120 const MapKey& map_key,
121 Args&&... args) noexcept {
122 return detail::apply_at(
123 std::forward<F>(f), box, std::forward_as_tuple(map_key),
ArgumentTags{},
124 PassthroughArgumentTags{}, std::forward<Args>(args)...);
130 template <
typename... ReturnTags,
typename...
ArgumentTags,
131 typename PassthroughTags,
typename F,
typename TaggedContainer,
132 typename... MapKeys,
typename... Args>
136 tmpl::list<ArgumentTags...> , PassthroughTags ,
137 Args&&... args) noexcept {
139 using ::db::mutate_apply;
140 using ::tuples::apply;
142 [](
const auto&... expanded_args_items) noexcept {
143 return std::forward_as_tuple(expanded_args_items...);
146 mutate_apply<tmpl::list<ReturnTags...>, tmpl::list<>>(
147 [&f, &map_keys, &args_items,
148 &args...](
const auto... mutated_items) noexcept {
152 unmap_arg<tmpl::list_contains_v<PassthroughTags, ReturnTags>,
153 MapKeys...>::apply(mutated_items, map_keys)...,
154 unmap_arg<tmpl::list_contains_v<PassthroughTags, ArgumentTags>,
156 apply(
std::get<tmpl::index_of<tmpl::list<ArgumentTags...>,
159 std::forward<Args>(args)...);
187 typename F,
typename TaggedContainer,
typename... MapKeys,
192 detail::mutate_apply_at(std::forward<F>(f), box, map_keys,
MutateTags{},
194 std::forward<Args>(args)...);
198 typename F,
typename TaggedContainer,
typename MapKey,
202 Args&&... args) noexcept {
203 detail::mutate_apply_at(
204 std::forward<F>(f), box, std::forward_as_tuple(map_key),
MutateTags{},
205 ArgumentTags{}, PassthroughTags{}, std::forward<Args>(args)...);