xtd 0.2.0
Loading...
Searching...
No Matches
dictionary.hpp
Go to the documentation of this file.
1
4#pragma once
6#include "helpers/equator.hpp"
7#include "helpers/hasher.hpp"
9#include "idictionary.hpp"
12#include "../../new_ptr.hpp"
13#include "../../ptr.hpp"
14#include <cmath>
15#include <unordered_map>
16
18namespace xtd {
20 namespace collections {
22 namespace generic {
66 template<class key_t, class value_t, class hasher_t = helpers::hasher<key_t>, class equator_t = helpers::equator<key_t>, class allocator_t = helpers::allocator<std::pair<const key_t, value_t >>>
67 class dictionary : public xtd::object, public xtd::collections::generic::idictionary<key_t, value_t> {
68 public:
70
81 using base_value_type = std::pair < const key_t, value_t >;
83 using base_type = std::unordered_map < key_type, mapped_type, hasher_t, equator_t, allocator_t >;
89 using equator = equator_t;
91 using hasher = hasher_t;
93
95
127 dictionary() noexcept = default;
138 dictionary(const idictionary < key_t, value_t >& dictionary) {
140 for (const auto& item : dictionary)
141 add(item);
142 }
143
147 for (const auto& item : collection)
148 add(item);
149 }
150
167
180
192 for (const auto& item : dictionary)
193 add(item);
194 }
195
200 for (const auto& item : collection)
201 add(item);
202 }
203
206 dictionary(dictionary&& other) noexcept = default;
210 dictionary(const dictionary & other) noexcept : data_(xtd::new_ptr < dictionary_data > (*other.data_->comparer, other.data_->items, other.data_->version)) {}
214 dictionary(std::unordered_map < key_t, value_t > && other) noexcept : data_(xtd::new_ptr < dictionary_data>(std::move(other))) {}
219 dictionary(const std::unordered_map < key_t, value_t >& other) {
220 for (auto iterator = other.begin(); iterator != other.end(); ++iterator) {
221 const auto& [key, value] = *iterator;
222 add(key, value);
223 }
224 }
225
232 dictionary(std::initializer_list < base_value_type > init) {
233 for (const auto& [key, value] : init) {
235 self_[key] = value;
236 }
237 }
238
246 template < class init_key_t, class init_value_t >
247 explicit dictionary(std::initializer_list < key_value_pair < init_key_t, init_value_t>> init) {
248 for (const auto& [key, value] : init) {
250 self_[key] = value;
251 }
252 }
253
259 template < class input_iterator_t >
260 explicit dictionary(input_iterator_t first, input_iterator_t last) {
261 for (auto iterator = first; iterator != last; ++iterator) {
262 const auto& [key, value] = *iterator;
263 add(key, value);
264 }
265 }
266
267
269
274 auto capacity() const noexcept -> size_type {return items().bucket_count();}
275
279 auto comparer() const noexcept -> const iequality_comparer < key_t >& {
280 if (!data_->comparer) return equality_comparer <key_type>::default_equality_comparer();
281 return *data_->comparer;
282 }
283
289 auto count() const noexcept -> size_type override {return data_->items.size();}
290
293 virtual auto items() const noexcept -> const base_type& {return data_->items;}
296 virtual auto items() noexcept -> base_type& {return data_->items;}
297
302 auto keys() const noexcept -> key_collection override {
303 auto keys = key_collection {};
304 for (const auto& [key, value] : data_->items)
305 keys.add(key);
306 return keys;
307 }
308
313 auto values() const noexcept -> value_collection override {
314 auto values = value_collection {};
315 for (const auto& [key, value] : data_->items)
316 values.add(value);
317 return values;
318 }
319
320
322
330 auto add(const key_t & key, const value_t& value) -> void override {
332 }
333
337 auto add(const value_type & item) -> void override {
338 add(item.key(), item.value());
339 }
340
343 auto clear() noexcept -> void override {
344 data_->items.clear();
345 ++data_->version;
346 }
347
351 auto contains(const value_type & item) const noexcept -> bool override {
352 auto iterator = items().find(item.key());
353 if (iterator == items().end()) return false;
354 return iterator->second == item.value();
355 }
356
361 auto contains_key(const key_t & key) const noexcept -> bool override {
362 return data_->items.find(key) != data_->items.end();
363 }
364
369 auto contains_value(const value_t& value) const noexcept -> bool {
370 for (const auto& [item_key, item_value] : self_)
371 if (item_value == value) return true;
372 return false;
373 }
374
379 auto copy_to(xtd::array < value_type >& array, xtd::size array_index) const -> void override {
381 for (const auto& item : self_)
382 array[array_index++] = item;
383 }
384
389 data_->items.reserve(capacity);
390 return self_.capacity();
391 }
392
395 enumerator<value_type> get_enumerator() const noexcept override {
396 struct dictionary_enumerator : public ienumerator < value_type > {
397 explicit dictionary_enumerator(const dictionary & items, size_type version) : items_(items), version_(version) {}
398
399 const value_type& current() const override {
401 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
402 return (value_ = value_type {*iterator_});
403 }
404
405 bool move_next() override {
406 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
407 if (index_++ && iterator_ != items_.data_->items.cend()) ++iterator_;
408 else iterator_ = items_.items().cbegin();
409 return iterator_ != items_.data_->items.cend();
410 }
411
412 void reset() override {
413 index_ = 0;
414 version_ = items_.data_->version;
415 iterator_ = items_.items().cend();
416 }
417
418 private:
419 size_type index_ = 0;
420 const dictionary& items_;
421 typename dictionary::base_type::const_iterator iterator_ = items_.data_->items.cend();
422 mutable value_type value_;
423 size_type version_ = 0;
424 };
425 return {new_ptr < dictionary_enumerator > (self_, data_->version)};
426 }
427
432 auto remove(const key_t & key) noexcept -> bool override {
433 return items().erase(key) == 1;
434 }
435
439 auto remove(const value_type & item) noexcept -> bool override {
440 if (!contains_value(item.value())) return false;
441 return items().erase(item.key()) == 1;
442 }
443
447 auto remove(const key_t & key, value_t& value) noexcept -> bool {
448 auto iterator = items().find(key);
449 if (iterator == items().end()) return false;
450 value = iterator->value();
451 return items().erase(iterator) != items().end();
452 }
453
456 auto to_string() const noexcept -> xtd::string override {return xtd::string::format("{{{}}}", xtd::string::join(", ", self_));}
457
466
473 auto trim_excess() -> void {
474 rehash(count());
475 }
476
482 auto try_add(const key_t & key, const value_t value) noexcept -> bool {
483 const auto& [iterator, succeeded] = data_->items.insert(std::forward < base_value_type > ({key, value}));
484 if (succeeded) ++data_->version;
485 return succeeded;
486 }
487
492 auto try_get_value(const key_t & key, value_t& value) const -> bool override {
493 auto iterator = items().find(key);
494 if (iterator != items().end()) {
495 value = iterator->second;
496 return true;
497 }
498 value = value_t {};
499 return false;
500 }
501
502
504
509 auto operator =(dictionary&& other) noexcept -> dictionary& {
510 data_->comparer = std::move(other.data_->comparer);
511 data_->items = std::move(other.data_->items);
512 data_->version = std::move(other.data_->version);
513 return self_;
514 }
515
518 auto operator =(std::unordered_map < key_t, value_t > && other) noexcept -> dictionary& {
519 data_->items = std::move(other);
520 ++data_->version;
521 return self_;
522 }
523
526 auto operator =(const dictionary & other) noexcept -> dictionary& = default;
530 auto operator =(const std::unordered_map < key_t, value_t >& other) noexcept -> dictionary& {
531 data_->items.clear();
532 for (const auto& [key, value] : other)
533 add(key, value);
534 }
535
538 auto operator =(std::initializer_list < base_value_type > ilist) -> dictionary& {
539 data_->items.clear();
540 for (const auto& [key, value] : ilist)
541 add(key, value);
542 }
543
546 template < class init_key_t, class init_value_t >
547 auto operator =(std::initializer_list < key_value_pair < init_key_t, init_value_t>> ilist) -> dictionary& {
548 data_->items.clear();
549 for (const auto& [key, value] : ilist)
550 add(key, value);
551 }
552
560 const value_t& operator [](const key_t & key) const override {
561 auto iterator = data_->items.find(key);
563 return iterator->second;
564 }
565
571 value_t& operator [](const key_t & key) override {
572 ++data_->version;
573 return data_->items[key];
574 }
575
578 operator const base_type& () const noexcept {return data_->items;}
581 operator base_type& () noexcept {return data_->items;}
584 operator std::unordered_map<key_t, value_t>() const noexcept {
585 std::unordered_map<key_t, value_t> result;
586 for (auto& [key, value] : data_->items)
587 result[key] = value;
588 return result;
589 }
590
591
592 private:
593 auto is_read_only() const noexcept -> bool override {return false;}
594 auto is_synchronized() const noexcept -> bool override {return false;}
595 const xtd::object& sync_root() const noexcept override {return data_->sync_root;}
596
597 struct dictionary_data {
598 dictionary_data() = default;
599 dictionary_data(const xtd::collections::generic::iequality_comparer<key_type>& comparer) : comparer {&comparer}, items {size_type {}, hasher_t {comparer}, equator_t {comparer}} {}
600 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} {
601 for (const auto& item : items)
602 self_.items.insert(item);
603 }
604 dictionary_data(base_type&& items, size_type version) noexcept : version {version} {
605 for (auto&& item : items)
606 self_.items.insert(item);
607 }
608
609 const xtd::collections::generic::iequality_comparer<key_type>* comparer = null;
610 base_type items;
611 size_type version = 0;
612 xtd::object sync_root;
613 };
615 };
616
618 // Deduction guides for xtd::collections::generic::dictionary
619 // {
620 template < class key_t, class value_t >
622
623 template < class key_t, class value_t >
624 dictionary(ienumerable < key_value_pair < key_t, value_t>>) -> dictionary<key_t, value_t>;
625
626 template < class key_t, class value_t >
627 dictionary(std::initializer_list < key_value_pair < key_t, value_t>>) -> dictionary<key_t, value_t>;
628
629 template < class key_t, class value_t >
630 dictionary(std::initializer_list < std::pair < key_t, value_t>>) -> dictionary<key_t, value_t>;
631
632 template < class input_iterator_t >
634 // }
636 }
637 }
638}
Contains xtd::collections::generic::helpers::allocator alias.
Contains xtd::argument_out_of_range_exception exception.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition array.hpp:64
virtual size_type length() const noexcept
Gets a size that represents the total number of elements in all the dimensions of the array.
Definition basic_array.hpp:124
static basic_string join(const basic_string &separator, const collection_t &values) noexcept
Definition basic_string.hpp:1702
Represents a collection of keys and values.
Definition dictionary.hpp:67
typename xtd::collections::generic::idictionary< key_t, value_t >::key_type key_type
Represents the dictionary key type.
Definition dictionary.hpp:73
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:492
dictionary(dictionary &&other) noexcept=default
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
typename xtd::collections::generic::idictionary< key_type, mapped_type >::value_collection value_collection
Represents the idictionary value collection type.
Definition dictionary.hpp:87
const value_t & operator[](const key_t &key) const override
Gets the element with the specified key.
Definition dictionary.hpp:560
auto comparer() const noexcept -> const iequality_comparer< key_type > &
Definition dictionary.hpp:279
auto values() const noexcept -> value_collection override
Gets a collection containing the values in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:313
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:439
dictionary(std::unordered_map< key_t, value_t > &&other) noexcept
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:214
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:473
auto to_string() const noexcept -> xtd::string override
Gets a string that represents the current object.
Definition dictionary.hpp:456
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:369
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:219
equator_t equator
Represents the dictionary equator type.
Definition dictionary.hpp:89
dictionary(size_t 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:177
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:232
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:260
dictionary(const 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:199
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 &
Returns the underlying base type items.
Definition dictionary.hpp:293
hasher_t hasher
Represents the dictionary hasher type.
Definition dictionary.hpp:91
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:351
std::unordered_map< key_type, mapped_type, hasher_t, equator_t, allocator_t > base_type
Represents the dictionary base type.
Definition dictionary.hpp:83
auto copy_to(xtd::array< value_type > &array, xtd::size array_index) const -> void override
Copies the elements of the xtd::collections::generic::icollection <type_t> to an xtd::array,...
Definition dictionary.hpp:379
auto capacity() const noexcept -> size_type
Definition dictionary.hpp:274
auto operator=(dictionary &&other) noexcept -> dictionary &
Move assignment operator. Replaces the contents with a copy of the contents of other.
Definition dictionary.hpp:509
auto keys() const noexcept -> key_collection override
Gets a collection containing the keys in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:302
dictionary(size_t capacity)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
Definition dictionary.hpp:164
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:462
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:482
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:361
std::pair< const key_t, value_t > base_value_type
Represents the dictionary base value type.
Definition dictionary.hpp:81
virtual auto items() noexcept -> base_type &
Returns the underlying base type items.
Definition dictionary.hpp:296
dictionary(const dictionary &other) noexcept
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:210
dictionary(const 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:190
auto add(const value_type &item) -> void override
Adds an item to the xtd::collections::generic::icollection <type_t>.
Definition dictionary.hpp:337
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:330
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:247
enumerator< value_type > get_enumerator() const noexcept override
Returns an enumerator that iterates through the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:395
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:289
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:432
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:447
typename xtd::collections::generic::idictionary< key_type, mapped_type >::key_collection key_collection
Represents the idictionary key collection type.
Definition dictionary.hpp:85
auto clear() noexcept -> void override
Removes all keys and values from the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:343
typename xtd::collections::generic::idictionary< key_t, value_t >::mapped_type mapped_type
Represents the dictionary mapped type.
Definition dictionary.hpp:75
typename xtd::collections::generic::idictionary< key_type, mapped_type >::value_type value_type
Represents the dictionary value type.
Definition dictionary.hpp:77
dictionary(const ienumerable< value_type > &collection)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that c...
Definition dictionary.hpp:146
auto ensure_capacity(xtd::size capacity) noexcept -> size_type
Ensures that the dictionary can hold up to a specified number of entries without any further expansio...
Definition dictionary.hpp:388
xtd::size size_type
Represents the dictionary size type.
Definition dictionary.hpp:79
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:155
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:44
xtd::collections::generic::list< mapped_type > value_collection
Definition idictionary.hpp:62
xtd::collections::generic::list< key_type > key_collection
Definition idictionary.hpp:60
typename xtd::collections::generic::icollection< value_type >::iterator iterator
Represents the iterator of xtd::collections::generic::ienumerable value type.
Definition idictionary.hpp:56
typename xtd::collections::generic::icollection< xtd::collections::generic::key_value_pair< xtd::any_object, xtd::any_object > >::value_type value_type
Definition idictionary.hpp:54
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
static void throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current())
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:44
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.
Contains xtd::collections::generic::idictionary <key_t, value_t> interface.
Contains xtd::collections::generic::key_not_found_exception exception.
generic::ienumerable< xtd::any_object > ienumerable
Exposes an enumerator, which supports a simple iteration over a non-generic collection.
Definition ienumerable.hpp:32
generic::idictionary< xtd::any_object, xtd::any_object > idictionary
interface IComparer exposes a method that compares two objects.
Definition idictionary.hpp:27
static basic_string format(const basic_string< char > &fmt, args_t &&... args)
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
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
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
ptr< type_t > new_ptr(args_t &&... args)
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
@ add
The Add key.
Definition console_key.hpp:170
Contains xtd::collections::generic::helpers::hasher struct.
Contains iteraors aliases.
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
read_only_span< type_t, count > first() const
Obtains a subspan consisting of the first count elements of the sequence.
Definition read_only_span.hpp:282
const_iterator end() const
Returns an iterator to the end.
Definition read_only_span.hpp:213
read_only_span< type_t, count > last() const
Obtains a subspan consisting of the last N elements of the sequence.
Definition read_only_span.hpp:307
Contains xtd::new_ptr method.
Contains xtd::ptr type.
Supports a simple iteration over a generic collection.
Definition enumerator.hpp:38