GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/algorithm/partition.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 6 6 100.0%
Functions: 0 0 -%
Branches: 0 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, template<typename> typename Pred, std::size_t... I>
15 KUMI_HIDDEN_ABI consteval auto select_in_(kumi::_::adl_tag_t, std::index_sequence<I...>) noexcept
16 {
17 return kumi::function::select_index_sequence<(Pred<kumi::stored_element_t<I, T>>::value)...>{};
18 }
19
20 template<typename T, template<typename> typename Pred, std::size_t... I>
21 KUMI_HIDDEN_ABI consteval auto select_out_(kumi::_::adl_tag_t, std::index_sequence<I...>) noexcept
22 {
23 return kumi::function::select_index_sequence<(!Pred<kumi::stored_element_t<I, T>>::value)...>{};
24 }
25 }
26
27 template<template<typename> typename Pred> struct partition_t
28 {
29 template<kumi::concepts::product_type T> [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t) const noexcept
30 {
31 2 if constexpr (kumi::concepts::empty_product_type<T>) return kumi::tuple{builder<T>::make(), builder<T>::make()};
32 else
33 {
34 constexpr auto in = select_in_<T, Pred>(kumi::_::adl_tag, kumi::function::indexes_for<T>{});
35 constexpr auto out = select_out_<T, Pred>(kumi::_::adl_tag, kumi::function::indexes_for<T>{});
36 30 return kumi::tuple{kumi::_::builder(KUMI_FWD(t), in), kumi::_::builder(KUMI_FWD(t), out)};
37 }
38 }
39 };
40
41 template<template<typename> typename Pred> struct filter_t
42 {
43 template<kumi::concepts::product_type T> [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t) const noexcept
44 {
45 2 if constexpr (kumi::concepts::empty_product_type<T>) return builder<T>::make();
46 else
47 {
48 constexpr auto pos = select_in_<T, Pred>(kumi::_::adl_tag, kumi::function::indexes_for<T>{});
49 28 return kumi::_::builder(KUMI_FWD(t), pos);
50 }
51 }
52 };
53
54 template<template<typename> typename Pred> struct filter_not_t
55 {
56 template<kumi::concepts::product_type T> [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t) const noexcept
57 {
58 2 if constexpr (kumi::concepts::empty_product_type<T>) return builder<T>::make();
59 else
60 {
61 constexpr auto pos = select_out_<T, Pred>(kumi::_::adl_tag, kumi::function::indexes_for<T>{});
62 28 return kumi::_::builder(KUMI_FWD(t), pos);
63 }
64 }
65 };
66
67 //====================================================================================================================
68 /**
69 @ingroup kumi_generators
70
71 @var partition
72 @brief Callable object partitioning a product type over a predicate
73
74 On a record type, `Pred` is applied directly to the underlying elements of the fields.
75
76 @qualifier nodiscard
77 @qualifier inline
78 @qualifier constexpr
79 @qualifier noexcept
80
81 @groupheader{Header file}
82 @code
83 #include <kumi/algorithm/partition.hpp>
84 @endcode
85
86 @groupheader{Call Signature}
87
88 @code
89 template<product_type T>
90 constexpr auto partition<Pred>(T && t) noexcept;
91 @endcode
92
93 @subgroupheader{Template Parameters}
94
95 - `Pred`: Compile-time predicate
96
97 @subgroupheader{Parameters}
98
99 - `t`: Product Type to process
100
101 @subgroupheader{Return value}
102
103 - A tuple containing the product type of all values whose types satisfy `Pred` in `t`
104 and the product type of all values whose types do not satisfy `Pred`.
105
106 @groupheader{Helper type}
107
108 @snippet include/kumi/algorithm/partition.hpp partition_t
109
110 Computes the return type of a call to kumi::partition
111
112 @groupheader{Examples}
113
114 @tab_begin
115
116 @tab{Tuple}
117 @godbolt{doc/tuple/algo/partition.cpp}
118
119 @tab{Record}
120 @godbolt{doc/record/algo/partition.cpp}
121
122 @tab_end
123 **/
124 //====================================================================================================================
125 template<template<typename> typename Pred> inline constexpr partition_t<Pred> partition{};
126
127 //====================================================================================================================
128 /**
129 @ingroup kumi_generators
130
131 @var filter
132 @brief Callable object filtering a product type over a predicate
133
134 On a record type, `Pred` is applied directly to the underlying elements of the fields.
135
136 @qualifier nodiscard
137 @qualifier inline
138 @qualifier constexpr
139 @qualifier noexcept
140
141 @groupheader{Header file}
142 @code
143 #include <kumi/algorithm/partition.hpp>
144 @endcode
145
146 @groupheader{Call Signature}
147
148 @code
149 template<product_type T>
150 constexpr auto filter<Pred>(T && t) noexcept;
151 @endcode
152
153 @subgroupheader{Template Parameters}
154
155 - `Pred`: Compile-time predicate
156
157 @subgroupheader{Parameters}
158
159 - `t`: Product Type to process
160
161 @subgroupheader{Return value}
162
163 - A Product type containing all values of `t` whose types satisfy `Pred`.
164
165 @groupheader{Helper type}
166
167 @snippet include/kumi/algorithm/partition.hpp filter_t
168
169 Computes the return type of a call to kumi::filter
170
171 @groupheader{Examples}
172
173 @tab_begin
174
175 @tab{Tuple}
176 @godbolt{doc/tuple/algo/filter.cpp}
177
178 @tab{Record}
179 @godbolt{doc/record/algo/filter.cpp}
180
181 @tab_end
182 **/
183 //====================================================================================================================
184 template<template<typename> typename Pred> inline constexpr filter_t<Pred> filter{};
185
186 //====================================================================================================================
187 /**
188 @ingroup kumi_generators
189
190 @var filter_not
191 @brief Callable object filtering a product type over a predicate
192
193 On a record type, `Pred` is applied directly to the underlying elements of the fields.
194
195 @qualifier nodiscard
196 @qualifier inline
197 @qualifier constexpr
198 @qualifier noexcept
199
200 @groupheader{Header file}
201 @code
202 #include <kumi/algorithm/partition.hpp>
203 @endcode
204
205 @groupheader{Call Signature}
206
207 @code
208 template<product_type T>
209 constexpr auto filter_not<Pred>(T && t) noexcept;
210 @endcode
211
212 @subgroupheader{Template Parameters}
213
214 - `Pred`: Compile-time predicate
215
216 @subgroupheader{Parameters}
217
218 - `t`: Product Type to process
219
220 @subgroupheader{Return value}
221
222 - A Product type containing all values of `t` whose types do not satisfy `Pred`.
223
224 @groupheader{Helper type}
225
226 @snippet include/kumi/algorithm/partition.hpp filter_not_t
227
228 Computes the return type of a call to kumi::filter_not
229
230 @groupheader{Examples}
231
232 @tab_begin
233
234 @tab{Tuple}
235 @godbolt{doc/tuple/algo/filter_not.cpp}
236
237 @tab{Record}
238 @godbolt{doc/record/algo/filter_not.cpp}
239
240 @tab_end
241 **/
242 //====================================================================================================================
243 template<template<typename> typename Pred> inline constexpr filter_not_t<Pred> filter_not{};
244
245 namespace result
246 {
247 //! [partition_t]
248 template<template<typename> typename Pred, kumi::concepts::product_type T>
249 using partition_t = decltype(kumi::partition<Pred>(std::declval<T>()));
250
251 template<template<typename> typename Pred, kumi::concepts::product_type T> struct partition
252 {
253 using type = kumi::result::partition_t<Pred, T>;
254 };
255
256 //! [partition_t]
257
258 //! [filter_t]
259 template<template<typename> typename Pred, kumi::concepts::product_type T>
260 using filter_t = decltype(kumi::filter<Pred>(std::declval<T>()));
261
262 template<template<typename> typename Pred, kumi::concepts::product_type T> struct filter
263 {
264 using type = kumi::result::filter_t<Pred, T>;
265 };
266
267 //! [filter_t]
268
269 //! [filter_not_t]
270 template<template<typename> typename Pred, kumi::concepts::product_type T>
271 using filter_not_t = decltype(kumi::filter_not<Pred>(std::declval<T>()));
272
273 template<template<typename> typename Pred, kumi::concepts::product_type T> struct filter_not
274 {
275 using type = kumi::result::filter_not_t<Pred, T>;
276 };
277
278 //! [filter_not_t]
279 }
280 }
281