xtd 1.0.0
Loading...
Searching...
No Matches
hash_set.hpp
Go to the documentation of this file.
1
4#pragma once
6#include "helpers/equator.hpp"
7#include "helpers/hasher.hpp"
8#include "iset.hpp"
9#include <unordered_set>
10
12namespace xtd {
14 namespace collections {
16 namespace generic {
36 template<typename type_t, typename hasher_t = xtd::collections::generic::helpers::hasher<type_t>, typename equator_t = xtd::collections::generic::helpers::equator<type_t>, typename allocator_t = xtd::collections::generic::helpers::allocator<type_t >>
37 class hash_set : public xtd::object, public xtd::collections::generic::iset<type_t> {
38 public:
40
49 using base_type = std::unordered_set<key_type, hasher_t, equator_t, allocator_t>;
51
53
72 hash_set() noexcept = default;
77 hash_set(const xtd::collections::generic::iequality_comparer<key_type>& comparer) noexcept : data_(xtd::new_ptr<hash_set_data>(comparer)) {}
86 hash_set(const ienumerable<value_type>& collection) noexcept {
87 for (const auto& item : collection)
88 add(item);
89 }
90
96 hash_set(const ienumerable < value_type >& collection, const xtd::collections::generic::iequality_comparer<key_type>& comparer) noexcept : data_(xtd::new_ptr<hash_set_data>(comparer)) {
97 for (const auto& item : collection)
98 add(item);
100 }
101
103 template<xtd::iterable iterable_t>
104 hash_set(iterable_t&& items) {
105 for (const auto& item : items)
106 add(item);
108 }
109
115 hash_set(hash_set&& other) noexcept = default;
116 hash_set(const hash_set& other) noexcept : data_(xtd::new_ptr<hash_set_data>(*other.data_->comparer, other.data_->items, other.data_->version)) {}
117 hash_set(std::unordered_set<key_type>&& other) noexcept : data_(xtd::new_ptr<hash_set_data>(std::move(other))) {}
118 hash_set(const std::unordered_set<key_type>& other) noexcept {
119 for (auto iterator = other.begin(); iterator != other.end(); ++iterator)
120 add(*iterator);
121 }
122 hash_set(std::initializer_list <value_type> init) {
123 ensure_capacity(init.size());
124 for (const auto& value : init)
125 add(value);
126 }
127 hash_set(std::initializer_list <value_type> init, const xtd::collections::generic::iequality_comparer<key_type>& comparer) noexcept : data_(xtd::new_ptr<hash_set_data>(comparer)) {
128 ensure_capacity(init.size());
129 for (const auto& value : init)
130 add(value);
131 }
132 template<typename input_iterator_t>
133 explicit hash_set(input_iterator_t first, input_iterator_t last) {
134 for (auto iterator = first; iterator != last; ++iterator)
135 add(*iterator);
136 }
138
140
144 [[nodiscard]] auto capacity() const noexcept -> size_type {return items().bucket_count();}
145
149 [[nodiscard]] auto comparer() const noexcept -> const iequality_comparer<key_type>& {
150 if (!data_->comparer) return equality_comparer <key_type>::default_equality_comparer();
151 return *data_->comparer;
152 }
153
159 [[nodiscard]] auto count() const noexcept -> size_type override {return items().size();}
160
163 [[nodiscard]] virtual auto items() const noexcept -> const base_type& {return data_->items;}
166 [[nodiscard]] virtual auto items() noexcept -> base_type& {return data_->items;}
168
170
175 auto add(const key_type& item) noexcept -> bool override {
176 if (contains(item)) return false;
177 items().insert(item);
178 ++data_->version;
179 return true;
180 }
181
184 auto clear() noexcept -> void override {
185 items().clear();
186 ++data_->version;
187 }
188
192 [[nodiscard]] auto contains(const value_type & item) const noexcept -> bool override {
193 return items().find(item) != items().end();
194 }
195
199 auto copy_to(xtd::array<type_t>& array) const -> void {
200 copy_to(0, array, 0, count());
201 }
202
208 auto copy_to(xtd::array<type_t>& array, size_type index) const -> void override {
209 copy_to(0, array, index, count());
210 }
211
218 auto copy_to(size_type index, xtd::array<type_t>& array, size_type array_index, size_type count) const -> void {
220 auto increment = size_type {};
221 for (const auto& item : self_) {
222 if (increment >= index + count) return;
223 if (increment++ >= index) array[array_index++] = item;
224 }
225 }
226
231 data_->items.reserve(capacity);
232 return self_.capacity();
233 }
234
238 auto except_with(const xtd::collections::generic::ienumerable<type_t>& other) noexcept -> void override {
239 if (&other == this) {
240 clear();
241 return;
242 }
243 for (const type_t& item : other)
244 remove(item);
245 }
246
249 [[nodiscard]] enumerator<value_type> get_enumerator() const noexcept override {
250 struct hash_set_enumerator : public ienumerator < value_type > {
251 explicit hash_set_enumerator(const hash_set & items, size_type version) : items_(items), version_(version) {}
252
253 const value_type& current() const override {
255 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
256 value_ = value_type {*iterator_};
257 return value_;
258 }
259
260 bool move_next() override {
261 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
262 if (index_++ && iterator_ != items_.data_->items.cend()) ++iterator_;
263 else iterator_ = items_.items().cbegin();
264 return iterator_ != items_.data_->items.cend();
265 }
266
267 void reset() override {
268 index_ = 0;
269 version_ = items_.data_->version;
270 iterator_ = items_.items().cend();
271 }
272
273 private:
274 size_type index_ = 0;
275 const hash_set& items_;
276 typename hash_set::base_type::const_iterator iterator_ = items_.data_->items.cend();
277 mutable value_type value_;
278 size_type version_ = 0;
279 };
280 return {new_ptr < hash_set_enumerator > (self_, data_->version)};
281 }
282
287 auto to_keep = hash_set {other};
288 auto to_remove = hash_set {};
289 for (const type_t& item : self_)
290 if (!to_keep.contains(item))
291 to_remove.add(item);
292 except_with(to_remove);
293 }
294
298 [[nodiscard]] auto is_proper_subset_of(const xtd::collections::generic::ienumerable<type_t>& other) const noexcept -> bool override {
299 auto set = hash_set {other};
300 if (count() == 0) return set.count() > 0;
301 if (count() >= set.count()) return false;
302 return sub_set(set);
303 }
304
308 [[nodiscard]] auto is_proper_superset_of(const xtd::collections::generic::ienumerable<type_t>& other) const noexcept -> bool override {
309 auto set = hash_set {other};
310 if (set.count() == 0) return count() > 0;
311 if (set.count() >= count()) return false;
312 return super_set(set);
313 }
314
318 [[nodiscard]] auto is_subset_of(const xtd::collections::generic::ienumerable<type_t>& other) const noexcept -> bool override {
319 return sub_set(hash_set {other});
320 }
321
325 [[nodiscard]] auto is_superset_of(const xtd::collections::generic::ienumerable<type_t>& other) const noexcept -> bool override {
326 return super_set(hash_set {other});
327 }
328
332 [[nodiscard]] auto overlaps(const xtd::collections::generic::ienumerable<type_t>& other) const noexcept -> bool override {
333 if (count() == 0) return false;
334 for (const auto& item : other)
335 if (contains(item)) return true;
336 return false;
337 }
338
342 auto remove(const type_t& item) noexcept -> bool override {
343 auto result = items().erase(item) == 1;
344 ++data_->version;
345 return result;
346 }
347
351 template<typename predicate_t>
352 auto remove_where(predicate_t match) noexcept -> size_type {
353 auto to_remove = hash_set {};
354 for (const auto& item : self_)
355 if (match(item)) to_remove.add(item);
356 for (const auto& item : to_remove)
357 remove(item);
358 return to_remove.count();
359 }
360
364 [[nodiscard]] auto set_equals(const xtd::collections::generic::ienumerable<type_t>& other) const noexcept -> bool override {
365 auto set = hash_set {other};
366 if (count() != set.count()) return false;
367 for (const auto& item : other)
368 if (!contains(item)) return false;
369 return true;
370 }
371
376 for (const auto& item : other)
377 if (contains(item)) remove(item);
378 else add(item);
379 }
380
383 [[nodiscard]] auto to_string() const noexcept -> xtd::string override {return xtd::string::format("{{{}}}", xtd::string::join(", ", self_));}
384
388 auto union_with(const xtd::collections::generic::ienumerable<type_t>& other) noexcept -> void override {
389 for (const auto& item : other)
390 if (!contains(item)) add(item);
391 }
392
394
396
399
400 private:
401 auto is_read_only() const noexcept -> bool override {return false;}
402 auto is_synchronized() const noexcept -> bool override {return false;}
403 const xtd::object& sync_root() const noexcept override {return data_->sync_root;}
404 auto sub_set(const hash_set& set) const noexcept -> bool {
405 if (count() == 0) return true;
406 if (count() > set.count()) return false;
407 for (const auto& item : self_)
408 if (!set.contains(item)) return false;
409 return true;
410 }
411
412 auto super_set(const hash_set& set) const noexcept -> bool {
413 if (set.count() == 0) return true;
414 if (set.count() > count()) return false;
415 for (const auto& item : set)
416 if (!contains(item)) return false;
417 return true;
418 }
419
420 struct hash_set_data {
421 hash_set_data() = default;
422 hash_set_data(const xtd::collections::generic::iequality_comparer<key_type>& comparer) : comparer {&comparer}, items {size_type {}, hasher_t {comparer}, equator_t {comparer}, allocator_t {}} {}
423 hash_set_data(const xtd::collections::generic::iequality_comparer<key_type>& comparer, const base_type& items, size_type version) noexcept : comparer {&comparer}, items {size_type {}, hasher_t {comparer}, equator_t {comparer}, allocator_t {}}, version {version} {
424 for (const auto& item : items)
425 self_.items.insert(item);
426 }
427 hash_set_data(base_type&& items, size_type version) noexcept : version {version} {
428 for (auto&& item : items)
429 self_.items.insert(item);
430 }
431
432 const xtd::collections::generic::iequality_comparer<key_type>* comparer = null;
433 base_type items;
434 size_type version = 0;
435 xtd::object sync_root;
436 };
438 };
439
441 // Deduction guides for xtd::collections::generic::hash_set
442 // {
443 template<typename type_t>
445
446 template<typename type_t>
448
449 template<xtd::iterable iterable_t>
451
452 template<typename type_t>
453 hash_set(std::initializer_list<type_t>) -> hash_set<type_t>;
454
455 template<typename input_iterator_t >
456 hash_set(input_iterator_t, input_iterator_t) -> hash_set<std::iter_value_t<input_iterator_t>>;
457 // }
459 }
460 }
461}
Contains xtd::collections::generic::helpers::allocator alias.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition array.hpp:64
virtual auto length() const noexcept -> size_type
Gets a size that represents the total number of elements in all the dimensions of the array.
Definition basic_array.hpp:122
static auto join(const basic_string &separator, const collection_t &values) noexcept -> basic_string
Definition basic_string.hpp:1259
static auto default_equality_comparer() -> const equality_comparer &
Gets the default equality comparer for the type specified by the generic argument.
Definition equality_comparer.hpp:42
Represents a set of values.
Definition hash_set.hpp:37
auto contains(const value_type &item) const noexcept -> bool override
Determines whether an element is in the xtd::collections::generic::dictionary <key_t,...
Definition hash_set.hpp:192
typename xtd::collections::generic::iset< type_t >::value_type value_type
Represents the hash set value type.
Definition hash_set.hpp:45
auto intersect_with(const xtd::collections::generic::ienumerable< type_t > &other) noexcept -> void override
Modifies the current set so that it contains only elements that are also in a specified collection.
Definition hash_set.hpp:286
auto symetric_excep_with(const xtd::collections::generic::ienumerable< type_t > &other) noexcept -> void override
Modifies the current set so that it contains only elements that are present either in the current set...
Definition hash_set.hpp:375
hash_set(iterable_t &&items)
Initializes a new instance of the xtd::iterable that contains elements copied from the specified coll...
Definition hash_set.hpp:104
auto ensure_capacity(xtd::usize capacity) noexcept -> xtd::usize
Ensures that the dictionary can hold up to a specified number of entries without any further expansio...
Definition hash_set.hpp:230
auto capacity() const noexcept -> size_type
Gets the total numbers of elements the internal data structure can hold without resizing.
Definition hash_set.hpp:144
auto except_with(const xtd::collections::generic::ienumerable< type_t > &other) noexcept -> void override
Removes all elements in the specified collection from the current set.
Definition hash_set.hpp:238
auto overlaps(const xtd::collections::generic::ienumerable< type_t > &other) const noexcept -> bool override
Determines whether the current set overlaps with the specified collection.
Definition hash_set.hpp:332
auto set_equals(const xtd::collections::generic::ienumerable< type_t > &other) const noexcept -> bool override
Determines whether the current set and the specified collection contain the same elements.
Definition hash_set.hpp:364
auto copy_to(size_type index, xtd::array< type_t > &array, size_type array_index, size_type count) const -> void
Copies a specified number of elements from hash_set <type_t> to a compatible one-dimensional array,...
Definition hash_set.hpp:218
xtd::usize size_type
Represents the hash set size type.
Definition hash_set.hpp:47
auto is_proper_superset_of(const xtd::collections::generic::ienumerable< type_t > &other) const noexcept -> bool override
Determines whether the current set is a proper (strict) superset of a specified collection.
Definition hash_set.hpp:308
auto is_superset_of(const xtd::collections::generic::ienumerable< type_t > &other) const noexcept -> bool override
Determines whether a set is a superset of a specified collection.
Definition hash_set.hpp:325
hash_set(const ienumerable< value_type > &collection) noexcept
Initializes a new instance of the xtd::collections::generic::hash_set <type_t> class that uses the de...
Definition hash_set.hpp:86
auto is_subset_of(const xtd::collections::generic::ienumerable< type_t > &other) const noexcept -> bool override
Determines whether a set is a subset of a specified collection.
Definition hash_set.hpp:318
auto to_string() const noexcept -> xtd::string override
Gets a string that represents the current object.
Definition hash_set.hpp:383
virtual auto items() const noexcept -> const base_type &
Returns the underlying base type items.
Definition hash_set.hpp:163
hash_set() noexcept=default
Initializes a new instance of the xtd::collections::generic::hash_set <type_t> class that is empty an...
auto clear() noexcept -> void override
Removes all keys and values from the xtd::collections::generic::dictionary <key_t,...
Definition hash_set.hpp:184
auto copy_to(xtd::array< type_t > &array, size_type index) const -> void override
Copies the complete hash_set <type_t> to a compatible one-dimensional array, starting at the specifie...
Definition hash_set.hpp:208
auto copy_to(xtd::array< type_t > &array) const -> void
Copies the complete hash_set <type_t> to a compatible one-dimensional array, starting at the beginnin...
Definition hash_set.hpp:199
auto union_with(const xtd::collections::generic::ienumerable< type_t > &other) noexcept -> void override
Modifies the current set so that it contains all elements that are present in the current set,...
Definition hash_set.hpp:388
auto remove(const type_t &item) noexcept -> bool override
Removes a specified item from the hash_set <type_t>.
Definition hash_set.hpp:342
virtual auto items() noexcept -> base_type &
Returns the underlying base type items.
Definition hash_set.hpp:166
std::unordered_set< key_type, hasher_t, equator_t, allocator_t > base_type
Represents the hash set base type.
Definition hash_set.hpp:49
hash_set(size_type capacity) noexcept
Initializes a new instance of the xtd::collections::generic::hash_set <type_t> class that is empty,...
Definition hash_set.hpp:112
auto remove_where(predicate_t match) noexcept -> size_type
Removes all elements that match the conditions defined by the specified predicate from a hash_set <ty...
Definition hash_set.hpp:352
enumerator< value_type > get_enumerator() const noexcept override
Returns an enumerator that iterates through the xtd::collections::generic::hash_set <type_t>.
Definition hash_set.hpp:249
auto add(const key_type &item) noexcept -> bool override
Adds an item to the xtd::collections::generic::icollection <type_t>.
Definition hash_set.hpp:175
auto is_proper_subset_of(const xtd::collections::generic::ienumerable< type_t > &other) const noexcept -> bool override
Determines whether the current set is a proper (strict) superset of a specified collection.
Definition hash_set.hpp:298
auto comparer() const noexcept -> const iequality_comparer< key_type > &
Gets the xtd::collections::generic::iequality_comparer <type_t> that is used to determine equality of...
Definition hash_set.hpp:149
auto count() const noexcept -> size_type override
Gets the number of key/value pairs contained in the xtd::collections::generic::dictionary <key_t,...
Definition hash_set.hpp:159
hash_set(const ienumerable< value_type > &collection, const xtd::collections::generic::iequality_comparer< key_type > &comparer) noexcept
Initializes a new instance of the xtd::collections::generic::hash_set <type_t> class that uses the sp...
Definition hash_set.hpp:96
typename xtd::collections::generic::iset< type_t >::key_type key_type
Represents the hash set key type.
Definition hash_set.hpp:43
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
Definition ienumerable.hpp:40
typename xtd::collections::generic::extensions::enumerable_iterators< type_t, xtd::collections::generic::ienumerable< type_t > >::iterator iterator
Represents the iterator of xtd::collections::generic::ienumerable value type.
Definition ienumerable.hpp:48
Supports a simple iteration over a generic collection.
Definition ienumerator.hpp:58
Defines methods to support the comparison of objects for equality.
Definition iequality_comparer.hpp:34
Provides the base interface for the abstraction of sets.
Definition iset.hpp:33
virtual auto is_read_only() const noexcept -> bool=0
Gets a value indicating whether the xtd::collections::generic::icollection <type_t> is read-only.
virtual auto is_synchronized() const noexcept -> bool=0
Gets a value indicating whether access to the xtd::collections::generic::icollection <type_t> is sync...
type_t value_type
Represents the set value type.
Definition iset.hpp:41
virtual auto sync_root() const noexcept -> const xtd::object &=0
Gets an object that can be used to synchronize access to the the xtd::collections::generic::icollecti...
type_t key_type
Represents the set key type.
Definition iset.hpp:39
virtual auto clear() -> void=0
Removes all items from the xtd::collections::generic::iset <type_t>.
virtual auto count() const noexcept -> xtd::usize=0
Gets the number of elements contained in the xtd::collections::generic::icollection <type_t>.
static auto throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current()) -> void
Throws an exption with specified exception case.
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:40
Represents the version number of an assembly, operating system, or the xtd. This class cannot be inhe...
Definition version.hpp:115
Contains xtd::collections::generic::helpers::equator struct.
static auto format(const basic_string< char > &fmt, args_t &&... args) -> basic_string
@ argument
The argument is not valid.
Definition exception_case.hpp:31
@ invalid_operation
The operation is not valid.
Definition exception_case.hpp:65
#define self_
The self_ expression is a reference value expression whose value is the reference of the implicit obj...
Definition self.hpp:20
null_ptr null
Represents a null pointer value.
xtd::sptr< type_t > ptr
The xtd::ptr object is a shared pointer.
Definition ptr.hpp:27
std::size_t usize
Represents an unsigned size of any object in bytes.
Definition usize.hpp:22
auto new_ptr(args_t &&... args) -> xtd::ptr< type_t >
The xtd::new_ptr operator creates a xtd::ptr object.
Definition new_ptr.hpp:24
@ other
The operating system is other.
Definition platform_id.hpp:60
Contains xtd::collections::generic::helpers::hasher struct.
Contains xtd::collections::generic::iset <type_t> interface.
The xtd::collections::generic namespace contains interfaces and classes that define generic collectio...
Definition comparer.hpp:16
The xtd::collections namespace contains interfaces and classes that define various collections of obj...
Definition any_pair.hpp:10
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
const xtd::collections::generic::helpers::wrap_pointer_iterator< pointer > iterator
Represents the iterator of read_only_span value type.
Definition read_only_span.hpp:74
auto first() const -> read_only_span< type_t, count >
Obtains a subspan consisting of the first count elements of the sequence.
Definition read_only_span.hpp:262
auto last() const -> read_only_span< type_t, count >
Obtains a subspan consisting of the last N elements of the sequence.
Definition read_only_span.hpp:287
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:39