GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/algorithm/map.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 13 13 100.0%
Functions: 69 69 100.0%
Branches: 10 10 100.0%

Line Branch Exec Source
1 //======================================================================================================================
2 /*
3 KUMI - Compact Tuple Tools
4 Copyright : KUMI Project Contributors
5 SPDX-License-Identifier: BSL-1.0
6 */
7 //======================================================================================================================
8 #pragma once
9
10 namespace kumi
11 {
12 namespace _
13 {
14 template<kumi::_::case_ Case, typename F, typename T, typename... Ts>
15 118 KUMI_HIDDEN_ABI constexpr decltype(auto) map_switch(auto N, F f, T&& t, Ts&&... ts)
16 {
17 if constexpr (Case == kumi::_::case_::normal)
18 {
19 if constexpr (kumi::concepts::record_type<T>)
20 {
21 constexpr auto field = kumi::identifier_of<kumi::element_t<N, T>>();
22 80 return kumi::capture_field<field>(kumi::invoke(f, get<field>(KUMI_FWD(t)), get<field>(KUMI_FWD(ts))...));
23 }
24 120 else return kumi::invoke(f, get<N>(KUMI_FWD(t)), get<N>(KUMI_FWD(ts))...);
25 }
26 else if constexpr (Case == kumi::_::case_::indexed)
27 {
28 58 return kumi::invoke(f, N, get<N>(KUMI_FWD(t)), get<N>(KUMI_FWD(ts))...);
29 }
30 else if constexpr (Case == kumi::_::case_::field)
31 {
32 constexpr auto field = kumi::identifier_of<kumi::element_t<N, T>>();
33 return kumi::capture_field<field>(
34
1/1
✓ Branch 1 taken 2 times.
94 kumi::invoke(f, kumi::_::make_str(field), get<field>(KUMI_FWD(t)), get<field>(KUMI_FWD(ts))...));
35 }
36 }
37
38 template<kumi::_::case_ Case, typename F, std::size_t... I, typename T, typename... Ts>
39 26 KUMI_HIDDEN_ABI constexpr decltype(auto) map_(
40 kumi::_::adl_tag_t, F&& f, std::index_sequence<I...>, T&& t, Ts&&... ts)
41 {
42 if constexpr (sizeof...(I) == 0) return kumi::builder<T>::make();
43 else
44
2/2
✓ Branch 4 taken 2 times.
✓ Branch 7 taken 2 times.
52 return kumi::builder<T>::make(map_switch<Case>(kumi::index<I>, KUMI_FWD(f), KUMI_FWD(t), KUMI_FWD(ts)...)...);
45 }
46 }
47
48 struct map_t
49 {
50 template<typename Function,
51 kumi::concepts::product_type T,
52 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
53 [[nodiscard]] KUMI_ABI constexpr auto operator()(Function f, T&& t, Ts&&... ts) const
54 requires(kumi::concepts::compatible_product_types<T, Ts...>) && (kumi::_::supports_call<Function, T&&, Ts&&...>)
55 {
56
3/3
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 2 times.
✓ Branch 7 taken 1 times.
9 return map_<kumi::_::case_::normal>(kumi::_::adl_tag, f, kumi::function::indexes_for<T>{}, KUMI_FWD(t),
57 9 KUMI_FWD(ts)...);
58 }
59 };
60
61 struct map_index_t
62 {
63 template<typename Function,
64 kumi::concepts::product_type T,
65 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
66 [[nodiscard]] KUMI_ABI constexpr auto operator()(Function f, T&& t, Ts&&... ts) const
67 requires(!kumi::concepts::record_type<T> && (!kumi::concepts::record_type<Ts> && ...))
68 {
69
2/2
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 1 times.
3 return map_<kumi::_::case_::indexed>(kumi::_::adl_tag, f, kumi::function::indexes_for<T>{}, KUMI_FWD(t),
70 3 KUMI_FWD(ts)...);
71 }
72 };
73
74 struct map_field_t
75 {
76 template<typename Function,
77 kumi::concepts::record_type R,
78 kumi::concepts::sized_product_type<kumi::size_v<R>>... Rs>
79 [[nodiscard]] KUMI_ABI constexpr auto operator()(Function f, R&& r, Rs&&... rs) const
80 requires(kumi::concepts::compatible_product_types<R, Rs...>)
81 {
82
2/2
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 1 times.
3 return map_<kumi::_::case_::field>(kumi::_::adl_tag, f, kumi::function::indexes_for<R>{}, KUMI_FWD(r),
83 3 KUMI_FWD(rs)...);
84 }
85 };
86
87 //====================================================================================================================
88 /**
89 @ingroup kumi_transforms
90
91 @var map
92 @brief Callable object applying the Callable object `f` on each product types' elements
93
94 Applies the given function to all the product types passed as arguments and stores the result in another product
95 type, keeping the original elements order. On records, the order is determined via the order of definition of
96 the fields.
97
98 @note Does not participate in overload resolution if product types' size are not equal or if
99 `f` can't be called on each product type's elements. All product type must either be
100 record types or product types, mixing is not supported.
101
102 @qualifier nodiscard
103 @qualifier inline
104 @qualifier constexpr
105
106 @groupheader{Header file}
107 @code
108 #include <kumi/algorithm/map.hpp>
109 @endcode
110
111 @groupheader{Call Signature}
112
113 @code
114 template<typename Function, product_type T, product_type... Ts>
115 constexpr auto map(Function && f, T && t, Ts &&... ts);
116 @endcode
117
118 @subgroupheader{Parameters}
119
120 - `f`: Callable object to apply
121 - `t`: Product Type to operate on
122 - `ts`: Other Product Types to operate on
123
124 @subgroupheader{Return value}
125
126 - The product type matching the common_product_type of the input containing `f` calls results.
127
128 @groupheader{Helper type}
129
130 @snippet include/kumi/algorithm/map.hpp map_t
131
132 Computes the return type of a call to kumi::map
133
134 @see kumi::map_index
135 @see kumi::map_field
136
137 @groupheader{Examples}
138
139 @tab_begin
140
141 @tab{Tuple}
142 @godbolt{doc/tuple/algo/map.cpp}
143
144 @tab{Record}
145 @godbolt{doc/record/algo/map.cpp}
146
147 @tab_end
148 **/
149 //====================================================================================================================
150 KUMI_VARIABLE_ABI constexpr map_t map{};
151
152 //====================================================================================================================
153 /**
154 @ingroup kumi_tuple_transforms
155
156 @var map_index
157 @brief Callable object applying the Callable object `f` on each product types elements and their indexes
158
159 Applies the given function to all the product types passed as arguments along with their indexes and stores the
160 result in another product type, keeping the original elements order.
161
162 @note Does not participate in overload resolution if tuples' size are not equal or if `f`
163 can't be called on each tuple's elements and their indexes.
164
165 @qualifier nodiscard
166 @qualifier inline
167 @qualifier constexpr
168
169 @groupheader{Header file}
170 @code
171 #include <kumi/algorithm/map.hpp>
172 @endcode
173
174 @groupheader{Call Signature}
175
176 @code
177 template<typename Function, product_type T, product_type... Ts>
178 constexpr auto map_index(Function && f, T && t, Ts &&... ts);
179 @endcode
180
181 @subgroupheader{Parameters}
182
183 - `f`: Callable object to apply
184 - `t`: Product Type to operate on
185 - `ts`: Other Product Types to operate on
186
187 @subgroupheader{Return value}
188
189 - The product type matching the common_product_type of the input containing `f` calls results.
190
191 @groupheader{Helper type}
192
193 @snippet include/kumi/algorithm/map.hpp map_index_t
194
195 Computes the return type of a call to kumi::map_index
196
197 @see kumi::map
198 @see kumi::map_field
199
200 @groupheader{Example}
201
202 @godbolt{doc/tuple/algo/map_index.cpp}
203 **/
204 //====================================================================================================================
205 KUMI_VARIABLE_ABI constexpr map_index_t map_index{};
206
207 //====================================================================================================================
208 /**
209 @ingroup kumi_record_transforms
210
211 @var map_field
212 @brief Callable object applying the Callable object `f` on each product types elements and their associated labels.
213
214 Applies the given function to all the records passed as arguments along with their names and
215 stores the result in another records, keeping the original elements order.
216
217 @note Does not participate in overload resolution if records' size are not equal or if `f`
218 can't be called on each record's fields and their names.
219
220 @qualifier nodiscard
221 @qualifier inline
222 @qualifier constexpr
223
224 @groupheader{Header file}
225 @code
226 #include <kumi/algorithm/map.hpp>
227 @endcode
228
229 @groupheader{Call Signature}
230
231 @code
232 template<typename Function, product_type T, product_type... Ts>
233 constexpr auto map_field(Function && f, T && t, Ts &&... ts);
234 @endcode
235
236 @subgroupheader{Parameters}
237
238 - `f`: Callable object to apply
239 - `t`: Product Type to operate on
240 - `ts`: Other Product Types to operate on
241
242 @subgroupheader{Return value}
243
244 - The product type matching the common_product_type of the input containing `f` calls results.
245
246 @groupheader{Helper type}
247
248 @snippet include/kumi/algorithm/map.hpp map_field_t
249
250 Computes the return type of a call to kumi::map_field
251
252 @see kumi::map
253 @see kumi::map_index
254
255 @groupheader{Example}
256
257 @godbolt{doc/record/algo/map_field.cpp}
258 **/
259 //====================================================================================================================
260 KUMI_VARIABLE_ABI constexpr map_field_t map_field{};
261
262 namespace result
263 {
264 //! [map_t]
265 template<typename Function,
266 kumi::concepts::product_type T,
267 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
268 using map_t = decltype(kumi::map(std::declval<Function>(), std::declval<T>(), std::declval<Ts>()...));
269
270 template<typename Function,
271 kumi::concepts::product_type T,
272 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
273 struct map
274 {
275 using type = kumi::result::map_t<Function, T, Ts...>;
276 };
277
278 //! [map_t]
279
280 //! [map_index_t]
281 template<typename Function,
282 kumi::concepts::product_type T,
283 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
284 using map_index_t = decltype(kumi::map_index(std::declval<Function>(), std::declval<T>(), std::declval<Ts>()...));
285
286 template<typename Function,
287 kumi::concepts::product_type T,
288 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
289 struct map_index
290 {
291 using type = kumi::result::map_index_t<Function, T, Ts...>;
292 };
293
294 //! [map_index_t]
295
296 //! [map_field_t]
297 template<typename Function,
298 kumi::concepts::record_type T,
299 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
300 using map_field_t = decltype(kumi::map_field(std::declval<Function>(), std::declval<T>(), std::declval<Ts>()...));
301
302 template<typename Function,
303 kumi::concepts::record_type T,
304 kumi::concepts::sized_product_type<kumi::size_v<T>>... Ts>
305 struct map_field
306 {
307 using type = kumi::result::map_field_t<Function, T, Ts...>;
308 };
309
310 //! [map_field_t]
311 }
312 }
313