GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/algorithm/zip.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 15 15 100.0%
Functions: 36 36 100.0%
Branches: 15 15 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<typename T, std::size_t... I, std::size_t... J>
15 26 KUMI_HIDDEN_ABI constexpr auto zip_(kumi::_::adl_tag_t,
16 T&& t,
17 std::index_sequence<I...>,
18 std::index_sequence<J...> is)
19 {
20 52 return kumi::make_tuple(kumi::_::builder(KUMI_FWD(t), std::integral_constant<std::size_t, I>{}, is)...);
21 }
22
23 template<typename T, std::size_t N, std::size_t... I>
24 36 KUMI_HIDDEN_ABI constexpr auto zip_intern_(T&& t, kumi::index_t<N>, std::index_sequence<I...>)
25 {
26 using U = kumi::common_product_type_t<std::remove_cvref_t<kumi::function::element_or_t<I, T, kumi::unit>>...>;
27 204 return kumi::builder<U>::make(kumi::function::get_or<N>(get<I>(KUMI_FWD(t)), kumi::none)...);
28 }
29
30 template<typename T, std::size_t... I, std::size_t... J>
31 5 KUMI_HIDDEN_ABI constexpr auto zip_max_(kumi::_::adl_tag_t,
32 T&& t,
33 std::index_sequence<I...>,
34 std::index_sequence<J...> is)
35 {
36
6/6
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 7 taken 3 times.
✓ Branch 10 taken 3 times.
✓ Branch 13 taken 3 times.
✓ Branch 16 taken 3 times.
10 return kumi::make_tuple(kumi::_::zip_intern_(KUMI_FWD(t), kumi::index<I>, is)...);
37 }
38 }
39
40 struct zip_t
41 {
42 template<kumi::concepts::product_type T0, kumi::concepts::sized_product_type<kumi::size_v<T0>>... Ts>
43 [[nodiscard]] KUMI_ABI constexpr auto operator()(T0&& t0, Ts&&... ts) const
44 requires(kumi::concepts::follows_same_semantic<T0, Ts...>)
45 {
46 3 if constexpr (kumi::concepts::sized_product_type<T0, 0>) return kumi::tuple{};
47 else
48 {
49 11 constexpr auto c = 1 + sizeof...(Ts);
50 constexpr auto outer = std::make_index_sequence<c>{};
51 constexpr auto inner = kumi::function::indexes_for<T0>{};
52
5/5
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 2 times.
✓ Branch 7 taken 2 times.
✓ Branch 10 taken 2 times.
✓ Branch 13 taken 1 times.
11 return zip_(kumi::_::adl_tag, kumi::forward_as_tuple(KUMI_FWD(t0), KUMI_FWD(ts)...), inner, outer);
53 }
54 }
55 };
56
57 struct zip_min_t
58 {
59 template<kumi::concepts::product_type T0, kumi::concepts::product_type... Ts>
60 [[nodiscard]] KUMI_ABI constexpr auto operator()(T0&& t0, Ts&&... ts) const
61 requires(kumi::concepts::follows_same_semantic<T0, Ts...>)
62 {
63 4 constexpr std::size_t m = kumi::_::min(kumi::size_v<T0>, kumi::size_v<Ts>...);
64 if constexpr (m == 0) return kumi::tuple{};
65 else
66 {
67 4 constexpr std::size_t c = 1 + sizeof...(Ts);
68 constexpr auto outer = std::make_index_sequence<c>{};
69 constexpr auto inner = std::make_index_sequence<m>{};
70
2/2
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 1 times.
4 return zip_(kumi::_::adl_tag, kumi::forward_as_tuple(KUMI_FWD(t0), KUMI_FWD(ts)...), inner, outer);
71 }
72 }
73 };
74
75 struct zip_max_t
76 {
77 template<kumi::concepts::product_type T0, kumi::concepts::product_type... Ts>
78 [[nodiscard]] KUMI_ABI constexpr auto operator()(T0&& t0, Ts&&... ts) const
79 requires(kumi::concepts::follows_same_semantic<T0, Ts...>)
80 {
81 3 constexpr std::size_t m = kumi::_::max(kumi::size_v<T0>, kumi::size_v<Ts>...);
82 if constexpr (m == 0) return kumi::tuple{};
83 else
84 {
85 3 constexpr std::size_t c = 1 + sizeof...(Ts);
86 constexpr auto outer = std::make_index_sequence<c>{};
87 constexpr auto inner = std::make_index_sequence<m>{};
88
2/2
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 1 times.
3 return zip_max_(kumi::_::adl_tag, kumi::forward_as_tuple(KUMI_FWD(t0), KUMI_FWD(ts)...), inner, outer);
89 }
90 }
91 };
92
93 //====================================================================================================================
94 /**
95 @ingroup kumi_generators
96
97 @var zip
98 @brief Callable object constructing a tuple where the ith element is the product type of all ith elements of
99 `t`,`ts`...
100
101 On record types, this function operates on elements as if they were ordered. The considered order is the order
102 of declaration.
103
104 @note This function does not take part in overload resolution if the product types do not follow the same
105 semantic. @see kumi::concepts::follows_same_semantic
106
107 @see zip_min
108 @see zip_max
109
110 @qualifier nodiscard
111 @qualifier inline
112 @qualifier constexpr
113
114 @groupheader{Header file}
115 @code
116 #include <kumi/algorithm/zip.hpp>
117 @endcode
118
119 @groupheader{Call Signature}
120
121 @code
122 template<product_type T, product_type... Ts>
123 constexpr auto zip(T && t, Ts &&... ts);
124 @endcode
125
126 @subgroupheader{Parameters}
127
128 - `t`: Product type to convert
129 - `ts`: Product types to convert
130
131 @subgroupheader{Return value}
132
133 - The tuple of all combinations of elements from `t`, `ts`...
134
135 @groupheader{Helper type}
136
137 @snippet include/kumi/algorithm/zip.hpp zip_t
138
139 Computes the return type of a call to kumi::zip
140
141 @groupheader{Examples}
142
143 @tab_begin
144
145 @tab{Tuple}
146 @godbolt{doc/tuple/algo/zip.cpp}
147
148 @tab{Record}
149 @godbolt{doc/record/algo/zip.cpp}
150
151 @tab_end
152 **/
153 //====================================================================================================================
154 KUMI_VARIABLE_ABI constexpr zip_t zip{};
155
156 //====================================================================================================================
157 /**
158 @ingroup kumi_generators
159
160 @var zip_min
161 @brief Callable object constructing a tuple where the ith element is the product type of all ith elements of
162 `t`,`ts`...
163
164 On record types, this function operates on elements as if they were ordered. The considered order is the order
165 of declaration.
166
167 @note This function does not take part in overload resolution if the product types do not follow the same
168 semantic. @see kumi::concepts::follows_same_semantic
169
170 @note `zip_min` truncates product types based on the smallest size.
171
172 @see zip
173 @see zip_max
174
175 @qualifier nodiscard
176 @qualifier inline
177 @qualifier constexpr
178
179 @groupheader{Header file}
180 @code
181 #include <kumi/algorithm/zip.hpp>
182 @endcode
183
184 @groupheader{Call Signature}
185
186 @code
187 template<product_type T, product_type... Ts>
188 constexpr auto zip_min(T && t, Ts &&... ts);
189 @endcode
190
191 @subgroupheader{Parameters}
192
193 - `t`: Product type to convert
194 - `ts`: Product types to convert
195
196 @subgroupheader{Return value}
197
198 - The tuple of all combinations of elements from `t`, `ts`...
199
200 @groupheader{Helper type}
201
202 @snippet include/kumi/algorithm/zip.hpp zip_min_t
203
204 Computes the return type of a call to kumi::zip_min
205
206 @groupheader{Examples}
207
208 @tab_begin
209
210 @tab{Tuple}
211 @godbolt{doc/tuple/algo/zip_min.cpp}
212
213 @tab{Record}
214 @godbolt{doc/record/algo/zip_min.cpp}
215
216 @tab_end
217 **/
218 //====================================================================================================================
219 KUMI_VARIABLE_ABI constexpr zip_min_t zip_min{};
220
221 //====================================================================================================================
222 /**
223 @ingroup kumi_generators
224
225 @var zip_max
226 @brief Callable object constructing a tuple where the ith element is the product type of all ith elements of
227 `t`,`ts`...
228
229 On record types, this function operates on elements as if they were ordered. The considered order is the order
230 of declaration.
231
232 @note This function does not take part in overload resolution if the product types do not follow the same
233 semantic. @see kumi::concepts::follows_same_semantic
234
235 @note `zip_max` fills missing elements to reach the biggest product type size.
236
237 @see zip
238 @see zip_min
239
240 @qualifier nodiscard
241 @qualifier inline
242 @qualifier constexpr
243
244 @groupheader{Header file}
245 @code
246 #include <kumi/algorithm/zip.hpp>
247 @endcode
248
249 @groupheader{Call Signature}
250
251 @code
252 template<product_type T, product_type... Ts>
253 constexpr auto zip_max(T && t, Ts &&... ts);
254 @endcode
255
256 @subgroupheader{Parameters}
257
258 - `t`: Product type to convert
259 - `ts`: Product types to convert
260
261 @subgroupheader{Return value}
262
263 - The tuple of all combinations of elements from `t`, `ts`...
264
265 @groupheader{Helper type}
266
267 @snippet include/kumi/algorithm/zip.hpp zip_max_t
268
269 Computes the return type of a call to kumi::zip_max
270
271 @groupheader{Example}
272
273 @subgroupheader{Tuple}
274 @godbolt{doc/tuple/algo/zip_max.cpp}
275 **/
276 //====================================================================================================================
277 KUMI_VARIABLE_ABI constexpr zip_max_t zip_max{};
278
279 namespace result
280 {
281 //! [zip_t]
282 //
283 template<kumi::concepts::product_type T0, kumi::concepts::product_type... Ts>
284 using zip_t = decltype(kumi::zip(std::declval<T0>(), std::declval<Ts>()...));
285
286 template<kumi::concepts::product_type T0, kumi::concepts::sized_product_type<kumi::size_v<T0>>... Ts> struct zip
287 {
288 using type = kumi::result::zip_t<T0, Ts...>;
289 };
290
291 //! [zip_t]
292
293 //! [zip_min_t]
294 //
295 template<kumi::concepts::product_type T0, kumi::concepts::product_type... Ts>
296 using zip_min_t = decltype(kumi::zip_min(std::declval<T0>(), std::declval<Ts>()...));
297
298 template<kumi::concepts::product_type T0, kumi::concepts::product_type... Ts> struct zip_min
299 {
300 using type = kumi::result::zip_min_t<T0, Ts...>;
301 };
302
303 //! [zip_min_t]
304
305 //! [zip_max_t]
306 template<kumi::concepts::product_type T0, kumi::concepts::product_type... Ts>
307 using zip_max_t = decltype(kumi::zip_max(std::declval<T0>(), std::declval<Ts>()...));
308
309 template<kumi::concepts::product_type T0, kumi::concepts::product_type... Ts> struct zip_max
310 {
311 using type = kumi::result::zip_max_t<T0, Ts...>;
312 };
313
314 //! [zip_max_t]
315 }
316 }
317