RPNX::DataStructures
Header-only C++ data structures and supporting utilities.
Loading...
Searching...
No Matches
set.hpp
1// Copyright (c) 2026 Ryan P. Nicholl <rnicholl@protonmail.com>
2
3#ifndef RPNXDATASTRUCTURES_SET_HPP
4#define RPNXDATASTRUCTURES_SET_HPP
5
6#include <compare>
7#include <initializer_list>
8#include <memory>
9#include <set>
10#include <type_traits>
11#include <utility>
12
13namespace rpnx
14{
28 template < typename Key, typename Compare = std::less< Key >, typename Allocator = std::allocator< Key > >
29 class set
30 {
31 public:
33 using underlying_type = std::set< Key, Compare, Allocator >;
35 using key_type = typename underlying_type::key_type;
37 using value_type = typename underlying_type::value_type;
39 using size_type = typename underlying_type::size_type;
41 using difference_type = typename underlying_type::difference_type;
43 using key_compare = typename underlying_type::key_compare;
45 using value_compare = typename underlying_type::value_compare;
47 using allocator_type = typename underlying_type::allocator_type;
49 using reference = typename underlying_type::reference;
51 using const_reference = typename underlying_type::const_reference;
53 using pointer = typename underlying_type::pointer;
55 using const_pointer = typename underlying_type::const_pointer;
57 using iterator = typename underlying_type::iterator;
59 using const_iterator = typename underlying_type::const_iterator;
61 using reverse_iterator = typename underlying_type::reverse_iterator;
63 using const_reverse_iterator = typename underlying_type::const_reverse_iterator;
65 using node_type = typename underlying_type::node_type;
67 using insert_return_type = typename underlying_type::insert_return_type;
68
69 private:
70 underlying_type m_set;
71
72 public:
76 set() = default;
77
83 explicit set(Compare const& comp, Allocator const& alloc = Allocator()) : m_set(comp, alloc)
84 {
85 }
86
91 explicit set(Allocator const& alloc) : m_set(alloc)
92 {
93 }
94
103 template < typename InputIt >
104 set(InputIt first, InputIt last, Compare const& comp = Compare(), Allocator const& alloc = Allocator()) : m_set(first, last, comp, alloc)
105 {
106 }
107
115 template < typename InputIt >
116 set(InputIt first, InputIt last, Allocator const& alloc) : m_set(first, last, alloc)
117 {
118 }
119
126 set(std::initializer_list< value_type > init, Compare const& comp = Compare(), Allocator const& alloc = Allocator()) : m_set(init, comp, alloc)
127 {
128 }
129
135 set(std::initializer_list< value_type > init, Allocator const& alloc) : m_set(init, alloc)
136 {
137 }
138
142 set(set const&) = default;
143
147 set(set&&) noexcept(std::is_nothrow_move_constructible_v< underlying_type >) = default;
148
154 set(set const& other, Allocator const& alloc) : m_set(other.m_set, alloc)
155 {
156 }
157
163 set(set&& other, Allocator const& alloc) : m_set(std::move(other.m_set), alloc)
164 {
165 }
166
171 set& operator=(set const&) = default;
172
177 set& operator=(set&&) noexcept(std::is_nothrow_move_assignable_v< underlying_type >) = default;
178
184 set& operator=(std::initializer_list< value_type > init)
185 {
186 m_set = init;
187 return *this;
188 }
189
195 {
196 return m_set.get_allocator();
197 }
198
200 iterator begin() noexcept
201 {
202 return m_set.begin();
203 }
204
206 const_iterator begin() const noexcept
207 {
208 return m_set.begin();
209 }
210
212 const_iterator cbegin() const noexcept
213 {
214 return m_set.cbegin();
215 }
216
218 iterator end() noexcept
219 {
220 return m_set.end();
221 }
222
224 const_iterator end() const noexcept
225 {
226 return m_set.end();
227 }
228
230 const_iterator cend() const noexcept
231 {
232 return m_set.cend();
233 }
234
237 {
238 return m_set.rbegin();
239 }
240
243 {
244 return m_set.rbegin();
245 }
246
249 {
250 return m_set.crbegin();
251 }
252
255 {
256 return m_set.rend();
257 }
258
261 {
262 return m_set.rend();
263 }
264
267 {
268 return m_set.crend();
269 }
270
272 bool empty() const noexcept
273 {
274 return m_set.empty();
275 }
276
278 size_type size() const noexcept
279 {
280 return m_set.size();
281 }
282
284 size_type max_size() const noexcept
285 {
286 return m_set.max_size();
287 }
288
290 void clear() noexcept
291 {
292 m_set.clear();
293 }
294
296 std::pair< iterator, bool > insert(value_type const& value)
297 {
298 return m_set.insert(value);
299 }
300
302 std::pair< iterator, bool > insert(value_type&& value)
303 {
304 return m_set.insert(std::move(value));
305 }
306
309 {
310 return m_set.insert(hint, value);
311 }
312
315 {
316 return m_set.insert(hint, std::move(value));
317 }
318
320 template < typename InputIt >
321 void insert(InputIt first, InputIt last)
322 {
323 m_set.insert(first, last);
324 }
325
327 void insert(std::initializer_list< value_type > init)
328 {
329 m_set.insert(init);
330 }
331
334 {
335 return m_set.insert(std::move(node));
336 }
337
340 {
341 return m_set.insert(hint, std::move(node));
342 }
343
345 template < typename... Args >
346 std::pair< iterator, bool > emplace(Args&&... args)
347 {
348 return m_set.emplace(std::forward< Args >(args)...);
349 }
350
352 template < typename... Args >
354 {
355 return m_set.emplace_hint(hint, std::forward< Args >(args)...);
356 }
357
360 {
361 return m_set.erase(pos);
362 }
363
366 {
367 return m_set.erase(first, last);
368 }
369
372 {
373 return m_set.erase(key);
374 }
375
377 void swap(set& other) noexcept(noexcept(m_set.swap(other.m_set)))
378 {
379 m_set.swap(other.m_set);
380 }
381
384 {
385 return m_set.extract(pos);
386 }
387
390 {
391 return m_set.extract(key);
392 }
393
395 template < typename C2 >
396 void merge(set< Key, C2, Allocator >& source)
397 {
398 m_set.merge(source.m_set);
399 }
400
402 template < typename C2 >
403 void merge(set< Key, C2, Allocator >&& source)
404 {
405 m_set.merge(source.m_set);
406 }
407
409 template < typename C2 >
410 void merge(std::set< Key, C2, Allocator >& source)
411 {
412 m_set.merge(source);
413 }
414
416 template < typename C2 >
417 void merge(std::set< Key, C2, Allocator >&& source)
418 {
419 m_set.merge(source);
420 }
421
423 size_type count(key_type const& key) const
424 {
425 return m_set.count(key);
426 }
427
430 {
431 return m_set.find(key);
432 }
433
435 const_iterator find(key_type const& key) const
436 {
437 return m_set.find(key);
438 }
439
441 bool contains(key_type const& key) const
442 {
443 return m_set.contains(key);
444 }
445
447 std::pair< iterator, iterator > equal_range(key_type const& key)
448 {
449 return m_set.equal_range(key);
450 }
451
453 std::pair< const_iterator, const_iterator > equal_range(key_type const& key) const
454 {
455 return m_set.equal_range(key);
456 }
457
460 {
461 return m_set.lower_bound(key);
462 }
463
466 {
467 return m_set.lower_bound(key);
468 }
469
472 {
473 return m_set.upper_bound(key);
474 }
475
478 {
479 return m_set.upper_bound(key);
480 }
481
484 {
485 return m_set.key_comp();
486 }
487
490 {
491 return m_set.value_comp();
492 }
493
494 template < typename K, typename C, typename A >
495 friend class set;
496
498 template < typename K, typename C, typename A >
499 friend bool operator==(set< K, C, A > const& lhs, set< K, C, A > const& rhs);
500
502 template < typename K, typename C, typename A >
503 friend bool operator<(set< K, C, A > const& lhs, set< K, C, A > const& rhs);
504
506 template < typename K, typename C, typename A >
507 friend auto operator<=>(set< K, C, A > const& lhs, set< K, C, A > const& rhs) -> decltype(std::declval< typename set< K, C, A >::underlying_type const& >() <=> std::declval< typename set< K, C, A >::underlying_type const& >());
508 };
509
515 template < typename Key, typename Compare, typename Allocator >
516 void swap(set< Key, Compare, Allocator >& lhs, set< Key, Compare, Allocator >& rhs) noexcept(noexcept(lhs.swap(rhs)))
517 {
518 lhs.swap(rhs);
519 }
520
527 template < typename Key, typename Compare, typename Allocator >
529 {
530 return lhs.m_set == rhs.m_set;
531 }
532
539 template < typename Key, typename Compare, typename Allocator >
541 {
542 return !(lhs == rhs);
543 }
544
551 template < typename Key, typename Compare, typename Allocator >
553 {
554 if (lhs.size() != rhs.size())
555 {
556 return lhs.size() < rhs.size();
557 }
558
559 return lhs.m_set < rhs.m_set;
560 }
561
568 template < typename Key, typename Compare, typename Allocator >
570 {
571 return rhs < lhs;
572 }
573
580 template < typename Key, typename Compare, typename Allocator >
582 {
583 return !(rhs < lhs);
584 }
585
592 template < typename Key, typename Compare, typename Allocator >
594 {
595 return !(lhs < rhs);
596 }
597
604 template < typename Key, typename Compare, typename Allocator >
605 auto operator<=>(set< Key, Compare, Allocator > const& lhs, set< Key, Compare, Allocator > const& rhs) -> decltype(std::declval< typename set< Key, Compare, Allocator >::underlying_type const& >() <=> std::declval< typename set< Key, Compare, Allocator >::underlying_type const& >())
606 {
607 using ordering_type = decltype(lhs.m_set <=> rhs.m_set);
608
609 if (lhs.size() < rhs.size())
610 {
611 return ordering_type::less;
612 }
613
614 if (rhs.size() < lhs.size())
615 {
616 return ordering_type::greater;
617 }
618
619 return lhs.m_set <=> rhs.m_set;
620 }
621} // namespace rpnx
622
623#endif // RPNXDATASTRUCTURES_SET_HPP
Ordered unique-key container with size-first ordering.
Definition set.hpp:30
std::pair< iterator, bool > emplace(Args &&... args)
Constructs a value in place if absent.
Definition set.hpp:346
void merge(std::set< Key, C2, Allocator > &source)
Transfers non-duplicate nodes from a standard set.
Definition set.hpp:410
const_iterator lower_bound(key_type const &key) const
Finds the first element not ordered before a key.
Definition set.hpp:465
set(InputIt first, InputIt last, Allocator const &alloc)
Constructs a set from an iterator range and allocator.
Definition set.hpp:116
const_iterator upper_bound(key_type const &key) const
Finds the first element ordered after a key.
Definition set.hpp:477
iterator lower_bound(key_type const &key)
Finds the first element not ordered before a key.
Definition set.hpp:459
std::pair< iterator, bool > insert(value_type &&value)
Inserts a moved value if absent.
Definition set.hpp:302
void merge(std::set< Key, C2, Allocator > &&source)
Transfers non-duplicate nodes from a standard set.
Definition set.hpp:417
std::pair< const_iterator, const_iterator > equal_range(key_type const &key) const
Finds the range matching a key.
Definition set.hpp:453
typename underlying_type::const_reference const_reference
Immutable stored-value reference type.
Definition set.hpp:51
reverse_iterator rend() noexcept
Returns a reverse iterator preceding the first element.
Definition set.hpp:254
void merge(set< Key, C2, Allocator > &&source)
Transfers non-duplicate nodes from another RPNX set.
Definition set.hpp:403
const_reverse_iterator rbegin() const noexcept
Returns an immutable reverse iterator to the final element.
Definition set.hpp:242
iterator find(key_type const &key)
Finds an element by key.
Definition set.hpp:429
void clear() noexcept
Removes all elements.
Definition set.hpp:290
set(Allocator const &alloc)
Constructs an empty set with an allocator.
Definition set.hpp:91
allocator_type get_allocator() const noexcept
Returns the allocator used by this set.
Definition set.hpp:194
typename underlying_type::value_compare value_compare
Function object used to order stored values.
Definition set.hpp:45
const_iterator cend() const noexcept
Returns an immutable iterator one past the final element.
Definition set.hpp:230
set(InputIt first, InputIt last, Compare const &comp=Compare(), Allocator const &alloc=Allocator())
Constructs a set from an iterator range.
Definition set.hpp:104
iterator erase(const_iterator first, const_iterator last)
Erases a range.
Definition set.hpp:365
friend bool operator<(set< K, C, A > const &lhs, set< K, C, A > const &rhs)
Grants less-than comparison access to the underlying set.
typename underlying_type::pointer pointer
Stored-value pointer type.
Definition set.hpp:53
void swap(set &other) noexcept(noexcept(m_set.swap(other.m_set)))
Exchanges contents with another set.
Definition set.hpp:377
void insert(std::initializer_list< value_type > init)
Inserts values from an initializer list.
Definition set.hpp:327
typename underlying_type::insert_return_type insert_return_type
Result returned when inserting a node handle without a hint.
Definition set.hpp:67
const_reverse_iterator crend() const noexcept
Returns an immutable reverse iterator preceding the first element.
Definition set.hpp:266
value_compare value_comp() const
Returns the stored-value ordering predicate.
Definition set.hpp:489
set & operator=(set &&) noexcept(std::is_nothrow_move_assignable_v< underlying_type >)=default
Move-assigns another set.
std::set< Key, Compare, Allocator > underlying_type
Underlying ordered unique-key container type.
Definition set.hpp:33
friend bool operator==(set< K, C, A > const &lhs, set< K, C, A > const &rhs)
Grants equality comparison access to the underlying set.
iterator end() noexcept
Returns an iterator one past the final element.
Definition set.hpp:218
typename underlying_type::const_pointer const_pointer
Immutable stored-value pointer type.
Definition set.hpp:55
bool contains(key_type const &key) const
Tests whether a key is present.
Definition set.hpp:441
set(set const &)=default
Copy-constructs a set.
iterator insert(const_iterator hint, value_type const &value)
Inserts a copied value using an ordering hint.
Definition set.hpp:308
typename underlying_type::value_type value_type
Stored value type, identical to key_type.
Definition set.hpp:37
set()=default
Constructs an empty set.
typename underlying_type::const_iterator const_iterator
Immutable bidirectional iterator type.
Definition set.hpp:59
friend auto operator<=>(set< K, C, A > const &lhs, set< K, C, A > const &rhs) -> decltype(std::declval< typename set< K, C, A >::underlying_type const & >()<=> std::declval< typename set< K, C, A >::underlying_type const & >())
Grants three-way comparison access to the underlying set.
typename underlying_type::key_compare key_compare
Function object used to order keys.
Definition set.hpp:43
void insert(InputIt first, InputIt last)
Inserts an iterator range.
Definition set.hpp:321
size_type erase(key_type const &key)
Erases an element by key.
Definition set.hpp:371
iterator upper_bound(key_type const &key)
Finds the first element ordered after a key.
Definition set.hpp:471
size_type count(key_type const &key) const
Counts elements matching a key.
Definition set.hpp:423
const_reverse_iterator crbegin() const noexcept
Returns an immutable reverse iterator to the final element.
Definition set.hpp:248
typename underlying_type::size_type size_type
Unsigned type used for element counts.
Definition set.hpp:39
iterator insert(const_iterator hint, node_type &&node)
Inserts an extracted node using an ordering hint.
Definition set.hpp:339
const_iterator cbegin() const noexcept
Returns an immutable iterator to the first element.
Definition set.hpp:212
typename underlying_type::reference reference
Stored-value reference type.
Definition set.hpp:49
set(set &&) noexcept(std::is_nothrow_move_constructible_v< underlying_type >)=default
Move-constructs a set.
set(set &&other, Allocator const &alloc)
Move-constructs a set using the specified allocator.
Definition set.hpp:163
std::pair< iterator, bool > insert(value_type const &value)
Inserts a copied value if absent.
Definition set.hpp:296
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the final element.
Definition set.hpp:236
const_reverse_iterator rend() const noexcept
Returns an immutable reverse iterator preceding the first element.
Definition set.hpp:260
const_iterator begin() const noexcept
Returns an immutable iterator to the first element.
Definition set.hpp:206
const_iterator find(key_type const &key) const
Finds an element by key.
Definition set.hpp:435
bool empty() const noexcept
Returns whether the set has no elements.
Definition set.hpp:272
iterator erase(const_iterator pos)
Erases one element.
Definition set.hpp:359
set(Compare const &comp, Allocator const &alloc=Allocator())
Constructs an empty set with a comparator and allocator.
Definition set.hpp:83
set(std::initializer_list< value_type > init, Allocator const &alloc)
Constructs a set from an initializer list and allocator.
Definition set.hpp:135
typename underlying_type::const_reverse_iterator const_reverse_iterator
Immutable reverse-iterator type.
Definition set.hpp:63
const_iterator end() const noexcept
Returns an immutable iterator one past the final element.
Definition set.hpp:224
set(std::initializer_list< value_type > init, Compare const &comp=Compare(), Allocator const &alloc=Allocator())
Constructs a set from an initializer list.
Definition set.hpp:126
typename underlying_type::allocator_type allocator_type
Allocator type used to manage nodes.
Definition set.hpp:47
typename underlying_type::iterator iterator
Bidirectional iterator type.
Definition set.hpp:57
size_type max_size() const noexcept
Returns the maximum number of elements supported by the implementation.
Definition set.hpp:284
typename underlying_type::key_type key_type
Key type used to order and identify elements.
Definition set.hpp:35
insert_return_type insert(node_type &&node)
Inserts an extracted node if absent.
Definition set.hpp:333
typename underlying_type::difference_type difference_type
Signed type used for iterator distances.
Definition set.hpp:41
iterator insert(const_iterator hint, value_type &&value)
Inserts a moved value using an ordering hint.
Definition set.hpp:314
key_compare key_comp() const
Returns the key-ordering predicate.
Definition set.hpp:483
set & operator=(set const &)=default
Copy-assigns another set.
node_type extract(key_type const &key)
Removes an element by key without destroying it.
Definition set.hpp:389
node_type extract(const_iterator pos)
Removes an element without destroying it.
Definition set.hpp:383
typename underlying_type::reverse_iterator reverse_iterator
Reverse-iterator type.
Definition set.hpp:61
iterator emplace_hint(const_iterator hint, Args &&... args)
Constructs a value in place using an ordering hint.
Definition set.hpp:353
std::pair< iterator, iterator > equal_range(key_type const &key)
Finds the range matching a key.
Definition set.hpp:447
typename underlying_type::node_type node_type
Owning handle for an extracted node.
Definition set.hpp:65
iterator begin() noexcept
Returns an iterator to the first element.
Definition set.hpp:200
void merge(set< Key, C2, Allocator > &source)
Transfers non-duplicate nodes from another RPNX set.
Definition set.hpp:396
size_type size() const noexcept
Returns the number of stored elements.
Definition set.hpp:278
Containers, iterator adapters, callable wrappers, and value utilities.
Definition annex.hpp:14
void swap(annex< T, Alloc > &lhs, annex< T, Alloc > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Swaps two annex objects.
Definition annex.hpp:577
bool operator<=(annex< T, Alloc > const &lhs, annex< T, Alloc > const &rhs)
Orders two annex objects.
Definition annex.hpp:651
bool operator>=(annex< T, Alloc > const &lhs, annex< T, Alloc > const &rhs)
Orders two annex objects.
Definition annex.hpp:663
bool operator<(annex< T, Alloc > const &lhs, annex< T, Alloc > const &rhs)
Orders two annex objects.
Definition annex.hpp:627
bool operator!=(annex< T, Alloc > const &lhs, annex< T, Alloc > const &rhs)
Compares two annex objects for inequality.
Definition annex.hpp:615
bool operator>(annex< T, Alloc > const &lhs, annex< T, Alloc > const &rhs)
Orders two annex objects.
Definition annex.hpp:639
auto operator<=>(annex< T, Alloc > const &lhs, annex< T, Alloc > const &rhs) -> decltype(*lhs<=> *rhs)
Three-way compares two annex objects when T supports <=>.
Definition annex.hpp:676
bool operator==(annex< T, Alloc > const &lhs, annex< T, Alloc > const &rhs)
Compares two annex objects for equality.
Definition annex.hpp:598