GCC Code Coverage Report


Directory: include/kumi/
File: include/kumi/algorithm/unique.hpp
Date: 2026-10-14 16:33:56
Exec Total Coverage
Lines: 5 5 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, std::size_t... I>
15 KUMI_HIDDEN_ABI consteval auto all_unique_(kumi::_::adl_tag_t, std::index_sequence<I...>) noexcept
16 {
17 using set = kumi::_::make_multiset_t<std::index_sequence<I...>, kumi::stored_element_t<I, T>...>;
18 return kumi::function::unique_index_sequence<(set{}(std::type_identity<kumi::stored_element_t<I, T>>{}) ==
19 I)...>{};
20 }
21
22 template<typename T, std::size_t... I>
23 KUMI_HIDDEN_ABI consteval auto unique_(kumi::_::adl_tag_t, std::index_sequence<I...>) noexcept
24 {
25 return kumi::function::adjacent_index_sequence<
26 !std::is_same_v<kumi::stored_element_t<I, T>, kumi::stored_element_t<I + 1, T>>...>{};
27 }
28 }
29
30 struct unique_t
31 {
32 template<kumi::concepts::product_type T> [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t) const
33 {
34 4 if constexpr (kumi::concepts::empty_product_type<T>) return KUMI_FWD(t);
35 4 else if constexpr (kumi::concepts::sized_product_type<T, 1>) return KUMI_FWD(t);
36 else
37 {
38 constexpr auto proj = unique_<T>(kumi::_::adl_tag, std::make_index_sequence<kumi::size_v<T> - 1>{});
39 20 return kumi::_::builder(KUMI_FWD(t), proj);
40 }
41 }
42 };
43
44 struct all_unique_t
45 {
46 template<kumi::concepts::product_type T> [[nodiscard]] KUMI_ABI constexpr auto operator()(T&& t) const
47 {
48 4 if constexpr (kumi::concepts::empty_product_type<T>) return t;
49 else
50 {
51 constexpr auto proj = all_unique_<T>(kumi::_::adl_tag, kumi::function::indexes_for<T>{});
52 28 return kumi::_::builder(KUMI_FWD(t), proj);
53 }
54 }
55 };
56
57 //====================================================================================================================
58 /**
59 @ingroup kumi_generators
60
61 @var unique
62 @brief Callable object returning a product type with consecutive duplicate types removed (pairwise uniqueness).
63
64 On record types, this function operates on the underlying values, not on the fields themselves.
65
66 @qualifier nodiscard
67 @qualifier inline
68 @qualifier constexpr
69
70 @groupheader{Header file}
71 @code
72 #include <kumi/algorithm/unique.hpp>
73 @endcode
74
75 @groupheader{Call Signature}
76
77 @code
78 template<product_type T>
79 constexpr auto unique(T && t);
80 @endcode
81
82 @subgroupheader{Parameters}
83
84 - `t`: Product Type to process
85
86 @subgroupheader{Return value}
87
88 - A product type containing elements of `t` with consecutive duplicates removed.
89
90 @groupheader{Helper type}
91
92 @snippet include/kumi/algorithm/unique.hpp unique_t
93
94 Computes the return type of a call to kumi::unique
95
96 @groupheader{Examples}
97
98 @tab_begin
99
100 @tab{Tuple}
101 @godbolt{doc/tuple/algo/unique.cpp}
102
103 @tab{Record}
104 @godbolt{doc/record/algo/unique.cpp}
105
106 @tab_end
107 **/
108 //====================================================================================================================
109 KUMI_VARIABLE_ABI constexpr unique_t unique{};
110
111 //====================================================================================================================
112 /**
113 @ingroup kumi_generators
114
115 @var all_unique
116 @brief Callable object returning a product type containing the values of the first occurrence of each type in `t`.
117
118 On record types, this function operates on the underlying values, not on the fields themselves.
119
120 @qualifier nodiscard
121 @qualifier inline
122 @qualifier constexpr
123
124 @groupheader{Header file}
125 @code
126 #include <kumi/algorithm/unique.hpp>
127 @endcode
128
129 @groupheader{Call Signature}
130
131 @code
132 template<product_type T>
133 constexpr auto all_unique(T && t);
134 @endcode
135
136 @subgroupheader{Parameters}
137
138 - `t`: Product Type to process
139
140 @subgroupheader{Return value}
141
142 - A product type built by keeping the first occurrence of every distinct element type in `t`.
143
144 @groupheader{Helper type}
145
146 @snippet include/kumi/algorithm/unique.hpp all_unique_t
147
148 Computes the return type of a call to kumi::all_unique
149
150 @groupheader{Examples}
151
152 @tab_begin
153
154 @tab{Tuple}
155 @godbolt{doc/tuple/algo/all_unique.cpp}
156
157 @tab{Record}
158 @godbolt{doc/record/algo/all_unique.cpp}
159
160 @tab_end
161 **/
162 //====================================================================================================================
163 KUMI_VARIABLE_ABI constexpr all_unique_t all_unique{};
164
165 namespace result
166 {
167 //! [unique_t]
168 template<kumi::concepts::product_type T> using unique_t = decltype(kumi::unique(std::declval<T>()));
169
170 template<kumi::concepts::product_type T> struct unique
171 {
172 using type = kumi::result::unique_t<T>;
173 };
174
175 //! [unique_t]
176
177 //! [all_unique_t]
178 template<kumi::concepts::product_type T> using all_unique_t = decltype(kumi::all_unique(std::declval<T>()));
179
180 template<kumi::concepts::product_type T> struct all_unique
181 {
182 using type = kumi::result::all_unique_t<T>;
183 };
184
185 //! [all_unique_t]
186 }
187 }
188