xtd 1.0.0
Loading...
Searching...
No Matches
dictionary.hpp
Go to the documentation of this file.
1
4#pragma once
5#define __XTD_CORE_INTERNAL__
7#undef __XTD_CORE_INTERNAL__
8#include "list.hpp"
9#include "../../new_ptr.hpp"
10#include "../../ptr.hpp"
11#include <cmath>
12
14namespace xtd {
16 namespace collections {
18 namespace generic {
62 template<typename key_t, typename value_t, typename hasher_t, typename equator_t, typename allocator_t>
63 class dictionary : public xtd::object, public xtd::collections::generic::idictionary<key_t, value_t> {
64 public:
66
77 using base_value_type = std::pair < const key_t, value_t >;
79 using base_type = std::unordered_map < key_type, mapped_type, hasher_t, equator_t, allocator_t >;
85 using equator = equator_t;
87 using hasher = hasher_t;
89
91
123 dictionary() noexcept = default;
134 dictionary(const xtd::collections::generic::idictionary < key_t, value_t >& dictionary) {
136 for (const auto& item : dictionary)
137 add(item);
138 }
139
142 dictionary(const xtd::collections::generic::ienumerable < value_type >& collection) {
143 for (const auto& item : collection)
144 add(item);
145 }
146
148 template<xtd::iterable iterable_t>
149 dictionary(iterable_t&& items) {
150 for (const auto& [key, value] : items)
151 add({key, value});
152 }
153
170
183
193 dictionary(const xtd::collections::generic::idictionary < key_t, value_t >& dictionary, const xtd::collections::generic::iequality_comparer<key_type>& comparer) : data_(xtd::new_ptr < dictionary_data>(comparer)) {
195 for (const auto& item : dictionary)
196 add(item);
197 }
198
202 dictionary(const xtd::collections::generic::ienumerable < value_type >& collection, const xtd::collections::generic::iequality_comparer<key_type>& comparer) : data_(xtd::new_ptr < dictionary_data>(comparer)) {
203 for (const auto& item : collection)
204 add(item);
205 }
206
209 dictionary(dictionary&& other) noexcept = default;
213 dictionary(const dictionary & other) : data_(xtd::new_ptr < dictionary_data > (*other.data_->comparer, other.data_->items, other.data_->version)) {}
217 dictionary(std::unordered_map < key_t, value_t > && other) {
218 data_->items.reserve(other.size());
219 for (auto&& item : other) {
220 data_->items.insert(std::move(item));
221 ++data_->version;
222 }
223 }
224
228 dictionary(const std::unordered_map < key_t, value_t >& other) {
229 for (const auto& [key, value] : other)
230 add(key, value);
231 }
232
239 dictionary(std::initializer_list < base_value_type > init) {
240 for (const auto& [key, value] : init)
241 add(key, value);
242 }
243
251 template < class init_key_t, typename init_value_t >
252 explicit dictionary(std::initializer_list < key_value_pair < init_key_t, init_value_t>> init) {
253 for (const auto& [key, value] : init)
254 add(key, value);
255 }
256
262 template < class input_iterator_t >
263 explicit dictionary(input_iterator_t first, input_iterator_t last) {
264 for (auto iterator = first; iterator != last; ++iterator) {
265 const auto& [key, value] = *iterator;
266 add(key, value);
267 }
268 }
269
270
272
277 [[nodiscard]] auto capacity() const noexcept -> size_type {return items().bucket_count();}
278
282 [[nodiscard]] auto comparer() const noexcept -> const iequality_comparer < key_t >& {
283 if (!data_->comparer) return equality_comparer <key_type>::default_equality_comparer();
284 return *data_->comparer;
285 }
286
292 [[nodiscard]] auto count() const noexcept -> size_type override {return data_->items.size();}
293
296 [[nodiscard]] virtual auto items() const noexcept -> const base_type& {return data_->items;}
299 [[nodiscard]] virtual auto items() noexcept -> base_type& {return data_->items;}
300
305 [[nodiscard]] auto keys() const noexcept -> key_collection override {
306 auto keys = key_collection {};
307 for (const auto& [key, value] : data_->items)
308 keys.add(key);
309 return keys;
310 }
311
316 [[nodiscard]] auto values() const noexcept -> value_collection override {
317 auto values = value_collection {};
318 for (const auto& [key, value] : data_->items)
319 values.add(value);
320 return values;
321 }
322
323
325
333 auto add(const key_t & key, const value_t& value) -> void override {
335 }
336
340 auto add(const value_type & item) -> void override {
341 add(item.key(), item.value());
342 }
343
346 auto clear() noexcept -> void override {
347 data_->items.clear();
348 ++data_->version;
349 }
350
354 [[nodiscard]] auto contains(const value_type & item) const noexcept -> bool override {
355 auto iterator = items().find(item.key());
356 if (iterator == items().end()) return false;
357 return iterator->second == item.value();
358 }
359
364 [[nodiscard]] auto contains_key(const key_t & key) const noexcept -> bool override {
365 return data_->items.find(key) != data_->items.end();
366 }
367
372 [[nodiscard]] auto contains_value(const value_t& value) const noexcept -> bool {
373 for (const auto& [item_key, item_value] : self_)
374 if (item_value == value) return true;
375 return false;
376 }
377
382 auto copy_to(xtd::array < value_type >& array, xtd::usize array_index) const -> void override {
384 for (const auto& item : self_)
385 array[array_index++] = item;
386 }
387
392 data_->items.reserve(capacity);
393 return self_.capacity();
394 }
395
398 [[nodiscard]] enumerator<value_type> get_enumerator() const noexcept override {
399 struct dictionary_enumerator : public ienumerator < value_type > {
400 explicit dictionary_enumerator(const dictionary & items, size_type version) : items_(items), version_(version) {}
401
402 [[nodiscard]] const value_type& current() const override {
404 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
405 return (value_ = value_type {*iterator_});
406 }
407
408 [[nodiscard]] bool move_next() override {
409 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
410 if (index_++ && iterator_ != items_.data_->items.cend()) ++iterator_;
411 else iterator_ = items_.items().cbegin();
412 return iterator_ != items_.data_->items.cend();
413 }
414
415 void reset() override {
416 index_ = 0;
417 version_ = items_.data_->version;
418 iterator_ = items_.items().cend();
419 }
420
421 private:
422 size_type index_ = 0;
423 const dictionary& items_;
424 typename dictionary::base_type::const_iterator iterator_ = items_.data_->items.cend();
425 mutable value_type value_;
426 size_type version_ = 0;
427 };
428 return {new_ptr < dictionary_enumerator > (self_, data_->version)};
429 }
430
435 auto remove(const key_t & key) noexcept -> bool override {
436 return items().erase(key) == 1;
437 }
438
442 auto remove(const value_type & item) noexcept -> bool override {
443 if (!contains_value(item.value())) return false;
444 return items().erase(item.key()) == 1;
445 }
446
450 auto remove(const key_t & key, value_t& value) noexcept -> bool {
451 auto iterator = items().find(key);
452 if (iterator == items().end()) return false;
453 value = iterator->value();
454 return items().erase(iterator) != items().end();
455 }
456
459 [[nodiscard]] auto to_string() const noexcept -> xtd::string override {return xtd::string::format("{{{}}}", xtd::string::join(", ", self_));}
460
469
476 auto trim_excess() -> void {
477 rehash(count());
478 }
479
485 [[nodiscard]] auto try_add(const key_t & key, const value_t value) noexcept -> bool {
486 const auto& [iterator, succeeded] = data_->items.insert(std::forward < base_value_type > ({key, value}));
487 if (succeeded) ++data_->version;
488 return succeeded;
489 }
490
495 [[nodiscard]] auto try_get_value(const key_t & key, value_t& value) const -> bool override {
496 auto iterator = items().find(key);
497 if (iterator != items().end()) {
498 value = iterator->second;
499 return true;
500 }
501 value = value_t {};
502 return false;
503 }
504
505
507
512 auto operator =(dictionary&& other) noexcept -> dictionary& {
513 data_->comparer = std::move(other.data_->comparer);
514 data_->items = std::move(other.data_->items);
515 data_->version = std::move(other.data_->version);
516 return self_;
517 }
518
521 auto operator =(std::unordered_map < key_t, value_t > && other) noexcept -> dictionary& {
522 data_->items = std::move(other);
523 ++data_->version;
524 return self_;
525 }
526
529 auto operator =(const dictionary & other) noexcept -> dictionary& = default;
533 auto operator =(const std::unordered_map < key_t, value_t >& other) noexcept -> dictionary& {
534 data_->items.clear();
535 for (const auto& [key, value] : other)
536 add(key, value);
537 }
538
541 auto operator =(std::initializer_list < base_value_type > ilist) -> dictionary& {
542 data_->items.clear();
543 for (const auto& [key, value] : ilist)
544 add(key, value);
545 }
546
549 template < class init_key_t, typename init_value_t >
550 auto operator =(std::initializer_list < key_value_pair < init_key_t, init_value_t>> ilist) -> dictionary& {
551 data_->items.clear();
552 for (const auto& [key, value] : ilist)
553 add(key, value);
554 }
555
563 [[nodiscard]] const value_t& operator [](const key_t & key) const override {
564 auto iterator = data_->items.find(key);
566 return iterator->second;
567 }
568
574 [[nodiscard]] value_t& operator [](const key_t & key) override {
575 ++data_->version;
576 return data_->items[key];
577 }
578
581 operator const base_type& () const noexcept {return data_->items;}
584 operator base_type& () noexcept {return data_->items;}
587 operator std::unordered_map<key_t, value_t>() const noexcept {
588 std::unordered_map<key_t, value_t> result;
589 for (auto& [key, value] : data_->items)
590 result[key] = value;
591 return result;
592 }
593
594
595 private:
596 auto is_read_only() const noexcept -> bool override {return false;}
597 auto is_synchronized() const noexcept -> bool override {return false;}
598 const xtd::object& sync_root() const noexcept override {return data_->sync_root;}
599
600 struct dictionary_data {
601 dictionary_data() = default;
602 dictionary_data(const xtd::collections::generic::iequality_comparer<key_type>& comparer) : comparer {&comparer}, items {size_type {}, hasher_t {comparer}, equator_t {comparer}} {}
603 dictionary_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}}, version {version} {
604 for (const auto& item : items)
605 self_.items.insert(item);
606 }
607 dictionary_data(base_type&& items, size_type version) noexcept : version {version} {
608 for (auto&& item : items)
609 self_.items.insert(item);
610 }
611
612 const xtd::collections::generic::iequality_comparer<key_type>* comparer = null;
613 base_type items;
614 size_type version = 0;
615 xtd::object sync_root;
616 };
618 };
619
621 // Deduction guides for xtd::collections::generic::dictionary
622 // {
623 template<typename key_t, typename value_t >
625
626 template<typename key_t, typename value_t >
628
629 template<xtd::iterable iterable_t>
630 dictionary(iterable_t&&) -> dictionary<std::remove_const_t<std::tuple_element_t<0, xtd::iterable_value_type<iterable_t>>>, std::remove_const_t<std::tuple_element_t<1, xtd::iterable_value_type<iterable_t>>>>;
631
632 template<typename key_t, typename value_t >
633 dictionary(std::initializer_list < key_value_pair < key_t, value_t>>) -> dictionary<key_t, value_t>;
634
635 template<typename key_t, typename value_t >
636 dictionary(std::initializer_list < std::pair < key_t, value_t>>) -> dictionary<key_t, value_t>;
637
638 template<typename input_iterator_t >
640 // }
642 }
643 }
644}
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:1258
Represents a collection of keys and values.
Definition dictionary.hpp:63
typename xtd::collections::generic::idictionary< xtd::intptr, xtd::ptr< collection_type > >::key_type key_type
Definition dictionary.hpp:69
auto try_get_value(const key_t &key, value_t &value) const -> bool override
Gets the value associated with the specified key.
Definition dictionary.hpp:495
dictionary(const xtd::collections::generic::ienumerable< value_type > &collection)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that c...
Definition dictionary.hpp:142
dictionary(dictionary &&other) noexcept=default
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
dictionary(const dictionary &other)
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:213
typename xtd::collections::generic::idictionary< key_type, mapped_type >::value_collection value_collection
Definition dictionary.hpp:83
const value_t & operator[](const key_t &key) const override
Gets the element with the specified key.
Definition dictionary.hpp:563
auto comparer() const noexcept -> const iequality_comparer< xtd::intptr > &
Definition dictionary.hpp:282
auto values() const noexcept -> value_collection override
Gets a collection containing the values in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:316
auto remove(const value_type &item) noexcept -> bool override
Removes the first occurrence of a specific object from the xtd::collections::generic::dictionary <key...
Definition dictionary.hpp:442
auto trim_excess() -> void
Sets the capacity of this dictionary to what it would be if it had been originally initialized with a...
Definition dictionary.hpp:476
auto to_string() const noexcept -> xtd::string override
Gets a string that represents the current object.
Definition dictionary.hpp:459
auto contains_value(const value_t &value) const noexcept -> bool
Determines whether the xtd::collections::generic::dictionary <key_t, value_t> contains the specified ...
Definition dictionary.hpp:372
dictionary(const xtd::collections::generic::ienumerable< value_type > &collection, const xtd::collections::generic::iequality_comparer< key_type > &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that c...
Definition dictionary.hpp:202
dictionary(const std::unordered_map< key_t, value_t > &other)
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:228
dictionary(std::initializer_list< base_value_type > init)
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:239
dictionary(input_iterator_t first, input_iterator_t last)
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:263
dictionary() noexcept=default
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
virtual auto items() const noexcept -> const base_type &
Definition dictionary.hpp:296
auto contains(const value_type &item) const noexcept -> bool override
Determines whether an element is in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:354
dictionary(xtd::usize capacity, const xtd::collections::generic::iequality_comparer< key_type > &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
Definition dictionary.hpp:180
dictionary(iterable_t &&items)
Initializes a new instance of the xtd::iterable that contains elements copied from the specified coll...
Definition dictionary.hpp:149
std::unordered_map< key_type, mapped_type, hasher_t, equator_t, allocator_t > base_type
Definition dictionary.hpp:79
auto capacity() const noexcept -> size_type
Definition dictionary.hpp:277
auto operator=(dictionary &&other) noexcept -> dictionary &
Move assignment operator. Replaces the contents with a copy of the contents of other.
Definition dictionary.hpp:512
auto keys() const noexcept -> key_collection override
Gets a collection containing the keys in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:305
auto trim_excess(size_type capacity) -> void
Sets the capacity of this dictionary to hold up a specified number of entries without any further exp...
Definition dictionary.hpp:465
auto try_add(const key_t &key, const value_t value) noexcept -> bool
Attempts to add the specified key and value to the dictionary.
Definition dictionary.hpp:485
auto contains_key(const key_t &key) const noexcept -> bool override
Determines whether the xtd::collections::generic::dictionary <key_t, value_t> contains the specified ...
Definition dictionary.hpp:364
std::pair< const xtd::intptr, xtd::ptr< collection_type > > base_value_type
Definition dictionary.hpp:77
virtual auto items() noexcept -> base_type &
Returns the underlying base type items.
Definition dictionary.hpp:299
auto add(const value_type &item) -> void override
Adds an item to the xtd::collections::generic::icollection <type_t>.
Definition dictionary.hpp:340
auto add(const key_t &key, const value_t &value) -> void override
Adds an element with the provided key and value to the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:333
dictionary(std::initializer_list< key_value_pair< init_key_t, init_value_t > > init)
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:252
dictionary(const xtd::collections::generic::idictionary< key_t, value_t > &dictionary, const xtd::collections::generic::iequality_comparer< key_type > &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that c...
Definition dictionary.hpp:193
enumerator< value_type > get_enumerator() const noexcept override
Returns an enumerator that iterates through the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:398
auto count() const noexcept -> size_type override
Gets the number of key/value pairs contained in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:292
auto copy_to(xtd::array< value_type > &array, xtd::usize array_index) const -> void override
Copies the elements of the xtd::collections::generic::icollection <type_t> to an xtd::array,...
Definition dictionary.hpp:382
auto remove(const key_t &key) noexcept -> bool override
Removes the value with the specified key from the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:435
auto remove(const key_t &key, value_t &value) noexcept -> bool
Removes the value with the specified key from the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:450
typename xtd::collections::generic::idictionary< key_type, mapped_type >::key_collection key_collection
Definition dictionary.hpp:81
auto clear() noexcept -> void override
Removes all keys and values from the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:346
typename xtd::collections::generic::idictionary< xtd::intptr, xtd::ptr< collection_type > >::mapped_type mapped_type
Definition dictionary.hpp:71
typename xtd::collections::generic::idictionary< key_type, mapped_type >::value_type value_type
Definition dictionary.hpp:73
dictionary(std::unordered_map< key_t, value_t > &&other)
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:217
auto ensure_capacity(xtd::usize capacity) noexcept -> size_type
Ensures that the dictionary can hold up to a specified number of entries without any further expansio...
Definition dictionary.hpp:391
dictionary(xtd::usize capacity)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
Definition dictionary.hpp:167
dictionary(const xtd::collections::generic::iequality_comparer< key_type > &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
Definition dictionary.hpp:158
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 generic collection of key/value pairs.
Definition idictionary.hpp:47
xtd::collections::generic::list< mapped_type > value_collection
Definition idictionary.hpp:65
xtd::collections::generic::list< key_type > key_collection
Definition idictionary.hpp:63
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...
virtual auto count() const noexcept -> xtd::usize=0
Gets the number of elements contained in the xtd::collections::generic::icollection <type_t>.
typename xtd::collections::generic::icollection< value_type >::iterator iterator
Represents the iterator of xtd::collections::generic::ienumerable value type.
Definition idictionary.hpp:59
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...
typename xtd::collections::generic::icollection< xtd::collections::generic::key_value_pair< xtd::any_object, xtd::any_object > >::value_type value_type
Definition idictionary.hpp:57
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
Definition ienumerable.hpp:40
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
Represents a collection of objects that can be individually accessed by index.
Definition ilist.hpp:43
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:45
Represents the version number of an assembly, operating system, or the xtd. This class cannot be inhe...
Definition version.hpp:115
xtd::collections::generic::comparer< xtd::any_object > comparer
Exposes a method that compares two objects.
Definition comparer.hpp:25
static auto format(const basic_string< char > &fmt, args_t &&... args) -> basic_string
std::tuple_element_t< 1, iterator_value_t< input_iterator_t > > iterator_mapped_t
Represents the mapped iterator type.
Definition iterator.hpp:57
@ argument
The argument is not valid.
Definition exception_case.hpp:31
@ argument_out_of_range
The argument is out of range.
Definition exception_case.hpp:35
@ invalid_operation
The operation is not valid.
Definition exception_case.hpp:65
@ key_not_found
The key is not found.
Definition exception_case.hpp:71
#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::list <type_t> class.
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
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:248
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:273
Contains xtd::new_ptr method.
Contains xtd::ptr type.
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:39
Defines a key/value pair that can be set or retrieved.
Definition key_value_pair.hpp:37