tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
flat_set.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2
3#ifndef TETL_FLAT_SET_FLAT_SET_HPP
4#define TETL_FLAT_SET_FLAT_SET_HPP
5
6#include <etl/_config/all.hpp>
7
24#include <etl/_iterator/end.hpp>
31#include <etl/_utility/move.hpp>
32#include <etl/_utility/pair.hpp>
33
34namespace etl {
35
57template <typename Key, typename Container, typename Compare = etl::less<Key>>
58struct flat_set {
59 using key_type = Key;
60 using key_compare = Compare;
61 using value_type = Key;
62 using value_compare = Compare;
65 using size_type = typename Container::size_type;
66 using difference_type = typename Container::difference_type;
67 using iterator = typename Container::iterator;
68 using const_iterator = typename Container::const_iterator;
71 using container_type = Container;
72
73 constexpr flat_set()
74 : flat_set{Compare{}}
75 {
76 }
77
84 explicit constexpr flat_set(container_type const& container)
85 requires(detail::RandomAccessRange<container_type>)
86 : flat_set{etl::begin(container), etl::end(container), Compare()}
87 {
88 }
89
91 : _container{etl::move(cont)}
92 , _compare{Compare()}
93 {
94 }
95
96 explicit constexpr flat_set(Compare const& comp)
97 : _container{}
98 , _compare(comp)
99 {
100 }
101
102 template <typename InputIt>
103 constexpr flat_set(InputIt first, InputIt last, Compare const& comp = Compare())
104 : _container{}
105 , _compare(comp)
106 {
107 insert(first, last);
108 }
109
110 template <typename InputIt>
111 constexpr flat_set(etl::sorted_unique_t /*tag*/, InputIt first, InputIt last, Compare const& comp = Compare())
112 : _container(first, last)
113 , _compare(comp)
114 {
115 }
116
117 [[nodiscard]] constexpr auto begin() noexcept -> iterator { return _container.begin(); }
118 [[nodiscard]] constexpr auto begin() const noexcept -> const_iterator { return _container.begin(); }
119 [[nodiscard]] constexpr auto cbegin() const noexcept -> const_iterator { return _container.begin(); }
120
121 [[nodiscard]] constexpr auto end() noexcept -> iterator { return _container.end(); }
122 [[nodiscard]] constexpr auto end() const noexcept -> const_iterator { return _container.end(); }
123 [[nodiscard]] constexpr auto cend() const noexcept -> const_iterator { return _container.end(); }
124
125 [[nodiscard]] constexpr auto rbegin() noexcept -> reverse_iterator { return _container.rbegin(); }
126 [[nodiscard]] constexpr auto rbegin() const noexcept -> const_reverse_iterator { return _container.rbegin(); }
127 [[nodiscard]] constexpr auto crbegin() const noexcept -> const_reverse_iterator { return _container.crbegin(); }
128
129 [[nodiscard]] constexpr auto rend() noexcept -> reverse_iterator { return _container.rend(); }
130 [[nodiscard]] constexpr auto rend() const noexcept -> const_reverse_iterator { return _container.rend(); }
131 [[nodiscard]] constexpr auto crend() const noexcept -> const_reverse_iterator { return _container.crend(); }
132
134 [[nodiscard]] constexpr auto empty() const noexcept -> bool { return _container.empty(); }
135
137 [[nodiscard]] constexpr auto size() const noexcept -> size_type { return _container.size(); }
138
140 [[nodiscard]] constexpr auto max_size() const noexcept -> size_type { return _container.max_size(); }
141
142 // 21.6.5.3, modifiers
143 template <typename... Args>
144 constexpr auto emplace(Args&&... args) -> etl::pair<iterator, bool>
145 {
146 auto key = Key{etl::forward<Args>(args)...};
147 iterator it = lower_bound(key);
148
149 if (it == end() or _compare(key, *it)) {
150 it = _container.emplace(it, etl::move(key));
151 return etl::make_pair(it, true);
152 }
153
154 return etl::make_pair(it, false);
155 }
156
157 template <typename... Args>
158 constexpr auto emplace_hint(const_iterator /*position*/, Args&&... args) -> iterator
159 {
160 return emplace(etl::forward<Args>(args)...).first;
161 }
162
163 constexpr auto insert(value_type const& x) -> etl::pair<iterator, bool> { return emplace(x); }
164
165 constexpr auto insert(value_type&& x) -> etl::pair<iterator, bool> { return emplace(etl::move(x)); }
166
167 constexpr auto insert(const_iterator position, value_type const& x) -> iterator
168 {
169 return emplace_hint(position, x);
170 }
171
172 constexpr auto insert(const_iterator position, value_type&& x) -> iterator
173 {
174 return emplace_hint(position, etl::move(x));
175 }
176
177 template <typename InputIt>
178 constexpr auto insert(InputIt first, InputIt last) -> void
179 {
180 while (first != last) {
181 insert(*first);
182 ++first;
183 }
184 }
185
186 template <typename InputIt>
187 constexpr auto insert(etl::sorted_unique_t /*tag*/, InputIt first, InputIt last) -> void;
188
189 constexpr auto extract() && -> container_type
190 {
191 auto&& container = etl::move(_container);
192 clear();
193 return container;
194 }
195
196 constexpr auto replace(container_type&& container) -> void { _container = etl::move(container); }
197
198 constexpr auto erase(iterator position) -> iterator { return _container.erase(position); }
199
200 constexpr auto erase(const_iterator position) -> iterator { return _container.erase(position); }
201
202 constexpr auto erase(key_type const& key) -> size_type
203 {
204 auto const it = etl::remove(begin(), end(), key);
205 auto const r = static_cast<size_type>(etl::distance(it, end()));
206 erase(it, end());
207 return r;
208 }
209
210 constexpr auto erase(const_iterator first, const_iterator last) -> iterator
211 {
212 return _container.erase(first, last);
213 }
214
215 constexpr auto swap(flat_set& other)
217 {
218 using etl::swap;
219 swap(_compare, other._compare);
220 swap(_container, other._container);
221 }
222
223 constexpr auto clear() noexcept -> void { _container.clear(); }
224
225 // observers
226 [[nodiscard]] constexpr auto key_comp() const -> key_compare { return _compare; }
227
228 [[nodiscard]] constexpr auto value_comp() const -> value_compare { return _compare; }
229
230 // set operations
231 [[nodiscard]] constexpr auto find(key_type const& key) -> iterator
232 {
233 auto const it = lower_bound(key);
234 if (it == end() or _compare(key, *it)) {
235 return end();
236 }
237 return it;
238 }
239
240 [[nodiscard]] constexpr auto find(key_type const& key) const -> const_iterator
241 {
242 auto const it = lower_bound(key);
243 if (it == end() or _compare(key, *it)) {
244 return end();
245 }
246 return it;
247 }
248
249 template <typename K>
250 requires etl::detail::is_transparent_v<Compare>
251 [[nodiscard]] constexpr auto find(K const& key) -> iterator
252 {
253 auto const it = lower_bound(key);
254 if (it == end() or _compare(key, *it)) {
255 return end();
256 }
257 return it;
258 }
259
260 template <typename K>
261 requires etl::detail::is_transparent_v<Compare>
262 [[nodiscard]] constexpr auto find(K const& key) const -> const_iterator
263 {
264 auto const it = lower_bound(key);
265 if (it == end() or _compare(key, *it)) {
266 return end();
267 }
268 return it;
269 }
270
271 [[nodiscard]] constexpr auto count(key_type const& key) const -> size_type { return find(key) == end() ? 0 : 1; }
272
273 template <typename K>
274 requires etl::detail::is_transparent_v<Compare>
275 [[nodiscard]] constexpr auto count(K const& key) const -> size_type
276 {
277 return find(key) == end() ? 0 : 1;
278 }
279
280 [[nodiscard]] constexpr auto contains(key_type const& key) const -> bool { return count(key) == 1; }
281
282 template <typename K>
283 requires etl::detail::is_transparent_v<Compare>
284 [[nodiscard]] constexpr auto contains(K const& key) const -> bool
285 {
286 return count(key) == 1;
287 }
288
289 [[nodiscard]] constexpr auto lower_bound(key_type const& key) -> iterator
290 {
291 return etl::lower_bound(begin(), end(), key, etl::ref(_compare));
292 }
293
294 [[nodiscard]] constexpr auto lower_bound(key_type const& key) const -> const_iterator
295 {
296 return etl::lower_bound(begin(), end(), key, etl::ref(_compare));
297 }
298
299 template <typename K>
300 requires etl::detail::is_transparent_v<Compare>
301 [[nodiscard]] constexpr auto lower_bound(K const& key) -> iterator
302 {
303 return etl::lower_bound(begin(), end(), key, etl::ref(_compare));
304 }
305
306 template <typename K>
307 requires etl::detail::is_transparent_v<Compare>
308 [[nodiscard]] constexpr auto lower_bound(K const& key) const -> const_iterator
309 {
310 return etl::lower_bound(begin(), end(), key, etl::ref(_compare));
311 }
312
313 [[nodiscard]] constexpr auto upper_bound(key_type const& key) -> iterator
314 {
315 return etl::upper_bound(begin(), end(), key, etl::ref(_compare));
316 }
317
318 [[nodiscard]] constexpr auto upper_bound(key_type const& key) const -> const_iterator
319 {
320 return etl::upper_bound(begin(), end(), key, etl::ref(_compare));
321 }
322
323 template <typename K>
324 requires etl::detail::is_transparent_v<Compare>
325 [[nodiscard]] constexpr auto upper_bound(K const& key) -> iterator
326 {
327 return etl::upper_bound(begin(), end(), key, etl::ref(_compare));
328 }
329
330 template <typename K>
331 requires etl::detail::is_transparent_v<Compare>
332 [[nodiscard]] constexpr auto upper_bound(K const& key) const -> const_iterator
333 {
334 return etl::upper_bound(begin(), end(), key, etl::ref(_compare));
335 }
336
337 [[nodiscard]] constexpr auto equal_range(key_type const& key) -> etl::pair<iterator, iterator>
338 {
339 return etl::equal_range(begin(), end(), key, etl::ref(_compare));
340 }
341
342 [[nodiscard]] constexpr auto equal_range(key_type const& key) const -> etl::pair<const_iterator, const_iterator>
343 {
344 return etl::equal_range(begin(), end(), key, etl::ref(_compare));
345 }
346
347 template <typename K>
348 requires etl::detail::is_transparent_v<Compare>
349 [[nodiscard]] constexpr auto equal_range(K const& key) -> etl::pair<iterator, iterator>
350 {
351 return etl::equal_range(begin(), end(), key, etl::ref(_compare));
352 }
353
354 template <typename K>
355 requires etl::detail::is_transparent_v<Compare>
356 [[nodiscard]] constexpr auto equal_range(K const& key) const -> etl::pair<const_iterator, const_iterator>
357 {
358 return etl::equal_range(begin(), end(), key, etl::ref(_compare));
359 }
360
361 friend constexpr auto operator==(flat_set const& lhs, flat_set const& rhs) -> bool
362 {
363 return etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
364 }
365
366 friend constexpr auto operator<(flat_set const& lhs, flat_set const& rhs) -> bool
367 {
368 return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
369 }
370
371 friend constexpr auto operator>(flat_set const& x, flat_set const& y) -> bool { return y < x; }
372
373 friend constexpr auto operator<=(flat_set const& x, flat_set const& y) -> bool { return !(y < x); }
374
375 friend constexpr auto operator>=(flat_set const& x, flat_set const& y) -> bool { return !(x < y); }
376
377 friend constexpr auto swap(flat_set& x, flat_set& y) noexcept(noexcept(x.swap(y))) -> void { return x.swap(y); }
378
379private:
382};
383
384template <typename Key, typename Container, typename Compare, typename Pred>
385constexpr auto erase_if(etl::flat_set<Key, Container, Compare>& c, Pred pred) ->
387{
388 auto const it = etl::remove_if(c.begin(), c.end(), pred);
389 auto const r = etl::distance(it, c.end());
390 c.erase(it, c.end());
391 return static_cast<typename etl::flat_set<Key, Container, Compare>::size_type>(r);
392}
393
394} // namespace etl
395
396#endif // TETL_FLAT_SET_FLAT_SET_HPP
#define TETL_NO_UNIQUE_ADDRESS
Definition attributes.hpp:41
constexpr auto equal_range(ForwardIt first, ForwardIt last, T const &value, Compare comp) -> pair< ForwardIt, ForwardIt >
Returns a range containing all elements equivalent to value in the range [first, last).
Definition equal_range.hpp:20
constexpr auto remove(ForwardIt first, ForwardIt last, T const &value) -> ForwardIt
Removes all elements satisfying specific criteria from the range [first, last) and returns a past-the...
Definition remove.hpp:15
constexpr auto remove_if(ForwardIt first, ForwardIt last, Predicate pred) -> ForwardIt
Removes all elements satisfying specific criteria from the range [first, last) and returns a past-the...
Definition remove_if.hpp:16
constexpr auto lower_bound(ForwardIt first, ForwardIt last, T const &value, Compare comp) noexcept -> ForwardIt
Returns an iterator pointing to the first element in the range [first, last) that is not less than (i...
Definition lower_bound.hpp:21
constexpr auto move(InputIt first, InputIt last, OutputIt destination) -> OutputIt
Moves the elements in the range [first, last), to another range beginning at destination,...
Definition move.hpp:26
constexpr auto lexicographical_compare(InputIt1 f1, InputIt1 l1, InputIt2 f2, InputIt2 l2, Compare comp) -> bool
Checks if the first range [f1, l1) is lexicographically less than the second range [f2,...
Definition lexicographical_compare.hpp:17
constexpr auto equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, Predicate p) -> bool
Returns true if the range [first1, last1) is equal to the range [first2, first2 + (last1 - first1)),...
Definition equal.hpp:18
constexpr auto upper_bound(ForwardIt first, ForwardIt last, T const &value, Compare comp) -> ForwardIt
Returns an iterator pointing to the first element in the range [first, last) that is greater than val...
Definition upper_bound.hpp:24
constexpr auto distance(It first, It last) -> typename iterator_traits< It >::difference_type
Returns the number of hops from first to last.
Definition distance.hpp:16
Definition adjacent_find.hpp:8
constexpr auto ref(T &t) noexcept -> reference_wrapper< T >
Function templates ref and cref are helper functions that generate an object of type reference_wrappe...
Definition reference_wrapper.hpp:103
constexpr auto make_pair(T1 &&t, T2 &&u) -> pair< decay_t< T1 >, decay_t< T2 > >
Creates a etl::pair object, deducing the target type from the types of arguments.
Definition pair.hpp:164
auto swap(inplace_function< R(Args...), Capacity, Alignment > &lhs, inplace_function< R(Args...), Capacity, Alignment > &rhs) noexcept -> void
Overloads the etl::swap algorithm for etl::inplace_function. Exchanges the state of lhs with that of ...
Definition inplace_function.hpp:249
constexpr auto erase_if(etl::flat_set< Key, Container, Compare > &c, Pred pred) -> typename etl::flat_set< Key, Container, Compare >::size_type
Definition flat_set.hpp:385
constexpr auto forward(remove_reference_t< T > &param) noexcept -> T &&
Forwards lvalues as either lvalues or as rvalues, depending on T. When t is a forwarding reference (a...
Definition forward.hpp:18
constexpr bool is_nothrow_swappable_v
Definition is_nothrow_swappable.hpp:19
A flat_set is a container adaptor that provides an associative container interface that supports uniq...
Definition flat_set.hpp:58
typename Container::iterator iterator
Definition flat_set.hpp:67
constexpr auto erase(key_type const &key) -> size_type
Definition flat_set.hpp:202
Compare value_compare
Definition flat_set.hpp:62
constexpr auto lower_bound(K const &key) const -> const_iterator
Definition flat_set.hpp:308
constexpr auto upper_bound(K const &key) const -> const_iterator
Definition flat_set.hpp:332
typename Container::const_iterator const_iterator
Definition flat_set.hpp:68
constexpr auto erase(const_iterator first, const_iterator last) -> iterator
Definition flat_set.hpp:210
friend constexpr auto operator==(flat_set const &lhs, flat_set const &rhs) -> bool
Definition flat_set.hpp:361
constexpr auto erase(iterator position) -> iterator
Definition flat_set.hpp:198
constexpr auto insert(value_type &&x) -> etl::pair< iterator, bool >
Definition flat_set.hpp:165
Compare key_compare
Definition flat_set.hpp:60
constexpr auto find(key_type const &key) const -> const_iterator
Definition flat_set.hpp:240
constexpr auto crbegin() const noexcept -> const_reverse_iterator
Definition flat_set.hpp:127
etl::reverse_iterator< const_iterator > const_reverse_iterator
Definition flat_set.hpp:70
constexpr auto insert(InputIt first, InputIt last) -> void
Definition flat_set.hpp:178
value_type const & const_reference
Definition flat_set.hpp:64
constexpr auto upper_bound(K const &key) -> iterator
Definition flat_set.hpp:325
constexpr auto upper_bound(key_type const &key) -> iterator
Definition flat_set.hpp:313
constexpr auto contains(key_type const &key) const -> bool
Definition flat_set.hpp:280
constexpr auto rbegin() const noexcept -> const_reverse_iterator
Definition flat_set.hpp:126
constexpr auto contains(K const &key) const -> bool
Definition flat_set.hpp:284
friend constexpr auto operator<=(flat_set const &x, flat_set const &y) -> bool
Definition flat_set.hpp:373
Key value_type
Definition flat_set.hpp:61
typename Container::size_type size_type
Definition flat_set.hpp:65
constexpr auto lower_bound(key_type const &key) -> iterator
Definition flat_set.hpp:289
friend constexpr auto operator>(flat_set const &x, flat_set const &y) -> bool
Definition flat_set.hpp:371
constexpr auto equal_range(key_type const &key) -> etl::pair< iterator, iterator >
Definition flat_set.hpp:337
constexpr auto insert(value_type const &x) -> etl::pair< iterator, bool >
Definition flat_set.hpp:163
constexpr auto lower_bound(key_type const &key) const -> const_iterator
Definition flat_set.hpp:294
constexpr auto rend() noexcept -> reverse_iterator
Definition flat_set.hpp:129
value_type & reference
Definition flat_set.hpp:63
constexpr auto begin() noexcept -> iterator
Definition flat_set.hpp:117
constexpr flat_set(etl::sorted_unique_t, container_type cont)
Definition flat_set.hpp:90
constexpr auto end() noexcept -> iterator
Definition flat_set.hpp:121
constexpr auto begin() const noexcept -> const_iterator
Definition flat_set.hpp:118
constexpr auto replace(container_type &&container) -> void
Definition flat_set.hpp:196
constexpr auto cbegin() const noexcept -> const_iterator
Definition flat_set.hpp:119
constexpr auto count(K const &key) const -> size_type
Definition flat_set.hpp:275
constexpr auto find(key_type const &key) -> iterator
Definition flat_set.hpp:231
friend constexpr auto operator<(flat_set const &lhs, flat_set const &rhs) -> bool
Definition flat_set.hpp:366
constexpr flat_set(InputIt first, InputIt last, Compare const &comp=Compare())
Definition flat_set.hpp:103
constexpr auto empty() const noexcept -> bool
Returns true if the underlying container is empty.
Definition flat_set.hpp:134
constexpr auto clear() noexcept -> void
Definition flat_set.hpp:223
constexpr auto lower_bound(K const &key) -> iterator
Definition flat_set.hpp:301
constexpr auto value_comp() const -> value_compare
Definition flat_set.hpp:228
constexpr flat_set(etl::sorted_unique_t, InputIt first, InputIt last, Compare const &comp=Compare())
Definition flat_set.hpp:111
Container container_type
Definition flat_set.hpp:71
etl::reverse_iterator< iterator > reverse_iterator
Definition flat_set.hpp:69
constexpr auto swap(flat_set &other) noexcept(etl::is_nothrow_swappable_v< Container > &&etl::is_nothrow_swappable_v< Compare >) -> void
Definition flat_set.hpp:215
constexpr auto equal_range(key_type const &key) const -> etl::pair< const_iterator, const_iterator >
Definition flat_set.hpp:342
constexpr flat_set(Compare const &comp)
Definition flat_set.hpp:96
constexpr auto max_size() const noexcept -> size_type
Returns the max_size of the underlying container.
Definition flat_set.hpp:140
constexpr auto key_comp() const -> key_compare
Definition flat_set.hpp:226
friend constexpr auto swap(flat_set &x, flat_set &y) noexcept(noexcept(x.swap(y))) -> void
Definition flat_set.hpp:377
constexpr auto find(K const &key) const -> const_iterator
Definition flat_set.hpp:262
constexpr auto end() const noexcept -> const_iterator
Definition flat_set.hpp:122
constexpr auto emplace(Args &&... args) -> etl::pair< iterator, bool >
Definition flat_set.hpp:144
constexpr auto count(key_type const &key) const -> size_type
Definition flat_set.hpp:271
Key key_type
Definition flat_set.hpp:59
constexpr auto crend() const noexcept -> const_reverse_iterator
Definition flat_set.hpp:131
constexpr auto equal_range(K const &key) -> etl::pair< iterator, iterator >
Definition flat_set.hpp:349
typename Container::difference_type difference_type
Definition flat_set.hpp:66
constexpr auto insert(const_iterator position, value_type const &x) -> iterator
Definition flat_set.hpp:167
constexpr auto extract() &&-> container_type
Definition flat_set.hpp:189
constexpr auto upper_bound(key_type const &key) const -> const_iterator
Definition flat_set.hpp:318
constexpr auto rend() const noexcept -> const_reverse_iterator
Definition flat_set.hpp:130
constexpr auto equal_range(K const &key) const -> etl::pair< const_iterator, const_iterator >
Definition flat_set.hpp:356
friend constexpr auto operator>=(flat_set const &x, flat_set const &y) -> bool
Definition flat_set.hpp:375
constexpr auto erase(const_iterator position) -> iterator
Definition flat_set.hpp:200
constexpr auto size() const noexcept -> size_type
Returns the size of the underlying container.
Definition flat_set.hpp:137
constexpr auto cend() const noexcept -> const_iterator
Definition flat_set.hpp:123
constexpr auto find(K const &key) -> iterator
Definition flat_set.hpp:251
constexpr auto insert(const_iterator position, value_type &&x) -> iterator
Definition flat_set.hpp:172
constexpr auto emplace_hint(const_iterator, Args &&... args) -> iterator
Definition flat_set.hpp:158
constexpr auto rbegin() noexcept -> reverse_iterator
Definition flat_set.hpp:125
constexpr flat_set(container_type const &container)
Initializes c with etl::move(cont), value-initializes compare, sorts the range [begin(),...
Definition flat_set.hpp:84
constexpr auto insert(etl::sorted_unique_t, InputIt first, InputIt last) -> void
constexpr flat_set()
Definition flat_set.hpp:73
etl::pair is a class template that provides a way to store two heterogeneous objects as a single unit...
Definition pair.hpp:36
reverse_iterator is an iterator adaptor that reverses the direction of a given iterator....
Definition reverse_iterator.hpp:22
Definition sorted_unique.hpp:8