GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/algorithm/contains.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 9 9 100.0%
Functions: 20 20 100.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, typename... Ts>
15 inline constexpr bool contains = ((kumi::concepts::field<T> && std::invocable<T, kumi::_::tag_of_t<Ts>>) || ...);
16
17 template<typename T, typename ID, std::size_t... I>
18 28 KUMI_HIDDEN_ABI constexpr auto contains_(kumi::_::adl_tag_t, T&&, ID const&, std::index_sequence<I...>)
19 {
20 return std::bool_constant<
21 28 kumi::concepts::contains_identifier<std::remove_cvref_t<ID>, kumi::element_t<I, T>...>>{};
22 }
23
24 template<typename T, std::size_t... I, typename... Is>
25 12 KUMI_HIDDEN_ABI constexpr auto contains_only_(kumi::_::adl_tag_t, T&&, std::index_sequence<I...>, Is const&...)
26 {
27 12 return std::bool_constant<(kumi::_::contains<kumi::element_t<I, T>, Is...> && ...)>{};
28 }
29 }
30
31 struct contains_t
32 {
33 template<kumi::concepts::product_type T, kumi::concepts::identifier ID>
34 [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t, ID const& id) const noexcept
35 {
36 if constexpr (kumi::concepts::empty_product_type<T>) return std::false_type{};
37 14 else return contains_(kumi::_::adl_tag, KUMI_FWD(t), id, kumi::function::indexes_for<T>{});
38 }
39 };
40
41 struct contains_any_t
42 {
43 template<kumi::concepts::product_type T, kumi::concepts::identifier... Is>
44 [[nodiscard]] KUMI_ABI constexpr auto operator()([[maybe_unused]] T&& t, Is const&... ids) const noexcept
45 {
46 if constexpr (kumi::concepts::empty_product_type<T>) return std::false_type{};
47 else if constexpr (sizeof...(Is) == 0) return std::false_type{};
48 else
49 return std::bool_constant<(
50 4 decltype(contains_(kumi::_::adl_tag, std::declval<T>(), ids, kumi::function::indexes_for<T>{})){} || ...)>{};
51 }
52 };
53
54 struct contains_only_t
55 {
56 template<kumi::concepts::product_type T, kumi::concepts::identifier... Is>
57 [[nodiscard]] KUMI_ABI constexpr auto operator()([[maybe_unused]] T&& t,
58 [[maybe_unused]] Is const&... ids) const noexcept
59 {
60 if constexpr (kumi::concepts::empty_product_type<T>) return std::false_type{};
61 else if constexpr (sizeof...(Is) == 0) return std::false_type{};
62 8 else if constexpr (sizeof...(Is) < kumi::size_v<T>) return std::false_type{};
63 6 else return contains_only_(kumi::_::adl_tag, KUMI_FWD(t), kumi::function::indexes_for<T>{}, ids...);
64 }
65 };
66
67 struct contains_none_t : private contains_any_t
68 {
69 template<kumi::concepts::product_type T, kumi::concepts::identifier... Is>
70 [[nodiscard]] KUMI_ABI constexpr auto operator()([[maybe_unused]] T&& t, Is const&... ids) const noexcept
71 {
72 using R = decltype(contains_any_t::operator()(std::declval<T>(), ids...));
73 4 return std::bool_constant<!R{}>{};
74 }
75 };
76
77 //====================================================================================================================
78 /**
79 @ingroup kumi_queries
80
81 @var contains
82 @brief Callable object checking if a product type contains a given identifier
83
84 @qualifier nodiscard
85 @qualifier inline
86 @qualifier constexpr
87 @qualifier noexcept
88
89 @groupheader{Header file}
90 @code
91 #include <kumi/algorithm/contains.hpp>
92 @endcode
93
94 @groupheader{Call Signature}
95
96 @code
97 template<product_type T, identifier ID>
98 constexpr auto contains(T && t, ID const& id) noexcept;
99 @endcode
100
101 @subgroupheader{Parameters}
102
103 - `t`: The product type to inspect
104 - `id`: The identifier to check for
105
106 @subgroupheader{Return value}
107
108 - `std::true_type` if `t` contains a field labeled with the `id` identifier, `std::false_type` otherwise.
109
110 @groupheader{Helper type}
111
112 @snippet include/kumi/algorithm/contains.hpp contains_t
113
114 Computes the return type of a call to kumi::contains
115
116 @groupheader{Examples}
117
118 @tab_begin
119
120 @tab{Tuple}
121 @godbolt{doc/tuple/algo/contains.cpp}
122
123 @tab{Record}
124 @godbolt{doc/record/algo/contains.cpp}
125
126 @tab_end
127 **/
128 //====================================================================================================================
129 KUMI_VARIABLE_ABI constexpr contains_t contains{};
130
131 //====================================================================================================================
132 /**
133 @ingroup kumi_queries
134
135 @var contains_any
136 @brief Callable object checking if a product type contains at least one of many identifier
137
138 @qualifier nodiscard
139 @qualifier inline
140 @qualifier constexpr
141 @qualifier noexcept
142
143 @groupheader{Header file}
144 @code
145 #include <kumi/algorithm/contains.hpp>
146 @endcode
147
148 @groupheader{Call Signature}
149
150 @code
151 template<product_type T, identifier... IDs>
152 constexpr auto contains_any(T && t, IDs const&... ids) noexcept;
153 @endcode
154
155 @subgroupheader{Parameters}
156
157 - `t`: The product type to inspect
158 - `ids`: The identifiers to check for
159
160 @subgroupheader{Return value}
161
162 - `std::true_type` if `t` contains a field labeled with one of the `ids`, `std::false_type` otherwise.
163
164 @groupheader{Helper type}
165
166 @snippet include/kumi/algorithm/contains.hpp contains_any_t
167
168 Computes the return type of a call to kumi::contains_any
169
170 @groupheader{Examples}
171
172 @tab_begin
173
174 @tab{Tuple}
175 @godbolt{doc/tuple/algo/contains_any.cpp}
176
177 @tab{Record}
178 @godbolt{doc/record/algo/contains_any.cpp}
179
180 @tab_end
181 **/
182 //====================================================================================================================
183 KUMI_VARIABLE_ABI constexpr contains_any_t contains_any{};
184
185 //====================================================================================================================
186 /**
187 @ingroup kumi_queries
188
189 @var contains_only
190 @brief Callable object checking if a product type contains fields based on a selected identifier
191
192 @qualifier nodiscard
193 @qualifier inline
194 @qualifier constexpr
195 @qualifier noexcept
196
197 @groupheader{Header file}
198 @code
199 #include <kumi/algorithm/contains.hpp>
200 @endcode
201
202 @groupheader{Call Signature}
203
204 @code
205 template<product_type T, identifier... IDs>
206 constexpr auto contains_only(T && t, IDs const&... ids) noexcept;
207 @endcode
208
209 @subgroupheader{Parameters}
210
211 - `t`: The product type to inspect
212 - `ids`: The identifiers to check for
213
214 @subgroupheader{Return value}
215
216 - `std::true_type` if `t` contains a field labeled with any of the `ids`, `std::false_type` otherwise.
217
218 @groupheader{Helper type}
219
220 @snippet include/kumi/algorithm/contains.hpp contains_only_t
221
222 Computes the return type of a call to kumi::contains_only
223
224 @groupheader{Examples}
225
226 @tab_begin
227
228 @tab{Tuple}
229 @godbolt{doc/tuple/algo/contains_only.cpp}
230
231 @tab{Record}
232 @godbolt{doc/record/algo/contains_only.cpp}
233
234 @tab_end
235 **/
236 //====================================================================================================================
237 KUMI_VARIABLE_ABI constexpr contains_only_t contains_only{};
238
239 //====================================================================================================================
240 /**
241 @ingroup kumi_queries
242
243 @var contains_none
244 @brief Callable object checking if a product type contains no fields based on any of the selected identifiers
245
246 @qualifier nodiscard
247 @qualifier inline
248 @qualifier constexpr
249 @qualifier noexcept
250
251 @groupheader{Header file}
252 @code
253 #include <kumi/algorithm/contains.hpp>
254 @endcode
255
256 @groupheader{Call Signature}
257
258 @code
259 template<product_type T, identifier... IDs>
260 constexpr auto contains_none(T && t, IDs const&... ids) noexcept;
261 @endcode
262
263 @subgroupheader{Parameters}
264
265 - `t`: The product type to inspect
266 - `ids`: The identifiers to check for
267
268 @subgroupheader{Return value}
269
270 - `std::true_type` if `t` contains no field labeled with any of the `ids`, `std::false_type` otherwise.
271
272 @groupheader{Helper type}
273
274 @snippet include/kumi/algorithm/contains.hpp contains_none_t
275
276 Computes the return type of a call to kumi::contains_none
277
278 @groupheader{Examples}
279
280 @tab_begin
281
282 @tab{Tuple}
283 @godbolt{doc/tuple/algo/contains_none.cpp}
284
285 @tab{Record}
286 @godbolt{doc/record/algo/contains_none.cpp}
287
288 @tab_end
289 **/
290 //====================================================================================================================
291 KUMI_VARIABLE_ABI constexpr contains_none_t contains_none{};
292
293 namespace result
294 {
295 //! [contains_t]
296 template<kumi::concepts::product_type T, kumi::concepts::identifier ID>
297 using contains_t = decltype(kumi::contains(std::declval<T>(), std::declval<ID>()));
298
299 template<kumi::concepts::product_type T, kumi::concepts::identifier ID> struct contains
300 {
301 using type = kumi::result::contains_t<T, ID>;
302 };
303
304 //! [contains_t]
305
306 //! [contains_any_t]
307 template<kumi::concepts::product_type T, kumi::concepts::identifier... IDs>
308 using contains_any_t = decltype(kumi::contains_any(std::declval<T>(), std::declval<IDs>()...));
309
310 template<kumi::concepts::product_type T, kumi::concepts::identifier... IDs> struct contains_any
311 {
312 using type = kumi::result::contains_any_t<T, IDs...>;
313 };
314
315 //! [contains_any_t]
316
317 //! [contains_only_t]
318 template<kumi::concepts::product_type T, kumi::concepts::identifier... IDs>
319 using contains_only_t = decltype(kumi::contains_only(std::declval<T>(), std::declval<IDs>()...));
320
321 template<kumi::concepts::product_type T, kumi::concepts::identifier... IDs> struct contains_only
322 {
323 using type = kumi::result::contains_only_t<T, IDs...>;
324 };
325
326 //! [contains_only_t]
327
328 //! [contains_none_t]
329 template<kumi::concepts::product_type T, kumi::concepts::identifier... IDs>
330 using contains_none_t = decltype(kumi::contains_none(std::declval<T>(), std::declval<IDs>()...));
331
332 template<kumi::concepts::product_type T, kumi::concepts::identifier... IDs> struct contains_none
333 {
334 using type = kumi::result::contains_none_t<T, IDs...>;
335 };
336
337 //! [contains_none_t]
338 }
339 }
340