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
73 struct hasher {
75
78 using argument_type = key_t;
82
84
90 size_t operator()(const key_t& key) const {
91 if (comparer) return comparer->get_hash_code(key);
92 return hasher_t {}(key);
93 }
94
95
96private:
97 friend class dictionary;
98 hasher() = default;
100 const iequality_comparer<key_t>* comparer = nullptr;
101 };
102
104 struct equator {
106
109 using first_argument_type = key_t;
111 using second_argument_type = key_t;
113 using result_type = bool;
115
117
124 bool operator()(const key_t & a, const key_t & b) const {
125 if (&a == &b) return true;
126 if (comparer) return comparer->equals(a, b);
127 return equator_t {}(a, b);
128 }
129
130
131private:
132 friend class dictionary;
133 equator() = default;
134 explicit equator(const iequality_comparer < key_t > * comparer) : comparer {comparer} {}
135 const iequality_comparer < key_t > * comparer = nullptr;
136 };
137
138
140
151 using base_value_type = std::pair < const key_t, value_t >;
153 using base_type = std::unordered_map < key_type, mapped_type, hasher, equator, allocator_t >;
159
161
193 dictionary() noexcept = default;
204 dictionary(const idictionary < key_t, value_t > & dictionary) {
206 for (const auto& item : dictionary)
207 add(item);
208 }
209
213 for (const auto& item : collection)
214 add(item);
215 }
216
221 template < class equality_comparer_t >
222 dictionary(const equality_comparer_t& comparer) : data_(xtd::new_ptr < dictionary_data > (new_ptr < equality_comparer_t > (comparer))) {}
234
244 template < class equality_comparer_t >
245 dictionary(size_t capacity, const equality_comparer_t& comparer) : data_(xtd::new_ptr < dictionary_data > (new_ptr < equality_comparer_t > (comparer))) {
247 }
248
258 template < class equality_comparer_t >
259 dictionary(const idictionary < key_t, value_t > & dictionary, const equality_comparer_t& comparer) : data_(xtd::new_ptr < dictionary_data>(new_ptr < equality_comparer_t > (comparer))) {
261 for (const auto& item : dictionary)
262 add(item);
263 }
264
268 template < class equality_comparer_t >
269 dictionary(const ienumerable < value_type > & collection, const equality_comparer_t& comparer) : data_(xtd::new_ptr < dictionary_data>(new_ptr < equality_comparer_t > (comparer))) {
270 for (const auto& item : collection)
271 add(item);
272 }
273
279 template < class input_iterator_t >
280 explicit dictionary(input_iterator_t first, input_iterator_t last) {
281 for (auto iterator = first; iterator != last; ++iterator) {
282 const auto& [key, value] = *iterator;
283 add(key, value);
284 }
285 }
286
289 dictionary(const dictionary & other) noexcept : data_(xtd::new_ptr < dictionary_data > (other.data_->comparer, other.data_->items, other.data_->version)) {}
294 dictionary(const std::unordered_map < key_t, value_t > & other) {
295 for (auto iterator = other.begin(); iterator != other.end(); ++iterator) {
296 const auto& [key, value] = *iterator;
297 add(key, value);
298 }
299 }
300
303 dictionary(dictionary&& other) noexcept = default;
307 dictionary(std::unordered_map < key_t, value_t > && other) noexcept : data_(xtd::new_ptr < dictionary_data>(std::move(other.data_->items))) {}
315 dictionary(std::initializer_list < base_value_type > init) {
316 for (const auto& [key, value] : init) {
318 self_[key] = value;
319 }
320 }
321
329 template < class init_key_t, class init_value_t >
330 explicit dictionary(std::initializer_list < key_value_pair < init_key_t, init_value_t>> init) {
331 for (const auto& [key, value] : init) {
333 self_[key] = value;
334 }
335 }
336
337
339
344 size_type capacity() const noexcept {return items().bucket_count();}
345
349 const iequality_comparer < key_t > & comparer() const noexcept {
350 if (data_->comparer) return *data_->comparer;
352 }
353
359 size_type count() const noexcept override {return data_->items.size();}
360
363 virtual const base_type & items() const noexcept {return data_->items;}
366 virtual base_type & items() noexcept {return data_->items;}
367
372 key_collection keys() const noexcept override {
373 auto keys = key_collection {};
374 for (const auto& [key, value] : data_->items)
375 keys.add(key);
376 return keys;
377 }
378
383 value_collection values() const noexcept override {
384 auto values = value_collection {};
385 for (const auto& [key, value] : data_->items)
386 values.add(value);
387 return values;
388 }
389
390
392
400 void add(const key_t & key, const value_t value) override {
402 }
403
407 void add(const value_type & item) override {
408 add(item.key(), item.value());
409 }
410
413 void clear() noexcept override {
414 data_->items.clear();
415 ++data_->version;
416 }
417
421 bool contains(const value_type & item) const noexcept override {
422 auto iterator = items().find(item.key());
423 if (iterator == items().end()) return false;
424 return iterator->second == item.value();
425 }
426
431 bool contains_key(const key_t & key) const noexcept override {
432 return data_->items.find(key) != data_->items.end();
433 }
434
439 bool contains_value(const value_t& value) const noexcept {
440 for (const auto& [item_key, item_value] : self_)
441 if (item_value == value) return true;
442 return false;
443 }
444
449 void copy_to(xtd::array < value_type > & array, xtd::size array_index) const override {
451 auto index = size_type {0};
452 for (const auto& item : self_)
453 array[array_index + index++] = item;
454 }
455
460 data_->items.reserve(capacity);
461 return this->capacity();
462 }
463
466 enumerator < value_type > get_enumerator() const noexcept override {
467 struct internal_enumerator : public ienumerator < value_type > {
468 public:
469 explicit internal_enumerator(const dictionary & items, size_type version) : items_(items), version_(version) {}
470
471 const value_type & current() const override {
472 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
473 if (iterator_ != items_.items().cend()) {
474 static thread_local auto value = value_type {};
475 value = value_type {*iterator_};
476 return value;
477 }
478 static auto default_value_type = value_type {};
479 return default_value_type;
480 }
481
482 bool move_next() override {
483 if (version_ != items_.data_->version) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::invalid_operation, "Collection was modified; enumeration operation may not execute.");
484 if (!reset_) return ++iterator_ != items_.items().cend();
485 reset_ = false;
486 iterator_ = items_.items().cbegin();
487 return iterator_ != items_.items().cend();
488 }
489
490 void reset() override {
491 reset_ = true;
492 version_ = items_.data_->version;
493 iterator_ = items_.items().cend();
494 }
495
496protected:
497 bool reset_ = true;
498 const dictionary& items_;
499 typename dictionary::base_type::const_iterator iterator_ = items_.items().cend();
500 size_type version_ = 0;
501 };
502 return {new_ptr < internal_enumerator > (self_, data_->version)};
503 }
504
509 bool remove(const key_t & key) noexcept override {
510 return items().erase(key) == 1;
511 }
512
516 bool remove(const value_type & item) noexcept override {
517 if (!contains_value(item.value())) return false;
518 return items().erase(item.key()) == 1;
519 }
520
524 bool remove(const key_t & key, value_t& value) noexcept {
525 auto iterator = items().find(key);
526 if (iterator == items().end()) return false;
527 value = iterator->value();
528 return items().erase(iterator) != items().end();
529 }
530
533 xtd::string to_string() const noexcept override {return xtd::string::format("{{{}}}", xtd::string::join(", ", self_));}
534
543
550 void trim_excess() {
551 rehash(count());
552 }
553
559 bool try_add(const key_t & key, const value_t value) noexcept {
560 const auto& [iterator, succeeded] = data_->items.insert(std::forward < base_value_type > ({key, value}));
561 if (succeeded) ++data_->version;
562 return succeeded;
563 }
564
569 bool try_get_value(const key_t & key, value_t& value) const override {
570 auto iterator = items().find(key);
571 if (iterator != items().end()) {
572 value = iterator->second;
573 return true;
574 }
575 value = value_t {};
576 return false;
577 }
578
579
581
587 data_->comparer = std::move(other.data_->comparer);
588 data_->items = std::move(other.data_->items);
589 data_->version = std::move(other.data_->version);
590 return self_;
591 }
592
595 dictionary& operator =(std::unordered_map < key_t, value_t > && other) noexcept {
596 data_->items = std::move(other);
597 ++data_->version;
598 return self_;
599 }
600
603 dictionary& operator =(const dictionary & other) noexcept = default;
607 dictionary& operator =(const std::unordered_map < key_t, value_t > & other) noexcept {
608 data_->items.clear();
609 for (const auto& [key, value] : other)
610 add(key, value);
611 }
612
615 dictionary& operator =(std::initializer_list < base_value_type > ilist) {
616 data_->items.clear();
617 for (const auto& [key, value] : ilist)
618 add(key, value);
619 }
620
623 template < class init_key_t, class init_value_t >
624 dictionary& operator =(std::initializer_list < key_value_pair < init_key_t, init_value_t>> ilist) {
625 data_->items.clear();
626 for (const auto& [key, value] : ilist)
627 add(key, value);
628 }
629
637 const value_t& operator [](const key_t & key) const override {
638 auto iterator = data_->items.find(key);
640 return iterator->second;
641 }
642
648 value_t& operator [](const key_t & key) override {
649 ++data_->version;
650 return data_->items[key];
651 }
652
655 operator const base_type & () const noexcept {return data_->items;}
658 operator base_type & () noexcept {return data_->items;}
660
661 private:
662 bool is_read_only() const noexcept override {return false;}
663 bool is_synchronized() const noexcept override {return false;}
664 const xtd::object & sync_root() const noexcept override {return data_->sync_root;}
665
666 struct dictionary_data {
667 dictionary_data() : items {size_type {}, hasher {}, equator {}, allocator_t {}} {}
668 dictionary_data(ptr < iequality_comparer < key_t>> comparer) : comparer {comparer}, items {size_type {}, hasher {comparer.get()}, equator {comparer.get()}, allocator_t {}} {}
669 dictionary_data(ptr < iequality_comparer < key_t>> comparer, const base_type & items, size_type version) noexcept : comparer {comparer}, items {size_type {}, hasher {comparer.get()}, equator {comparer.get()}, allocator_t {}}, version {version} {
670 for (const auto& item : items)
671 this->items.insert(item);
672 }
673 dictionary_data(base_type&& items, size_type version) noexcept : items {size_type {}, hasher {}, equator {}, allocator_t {}}, version {version} {
674 for (auto&& item : items)
675 this->items.insert(item);
676 }
677
679 base_type items;
680 size_type version = 0;
681 xtd::object sync_root;
682 };
684 };
685
687 // C++17 deduction guides for xtd::collections::generic::dictionary
688 // {
689 template < class key_t, class value_t >
691
692 template < class key_t, class value_t >
694
695 template < class key_t, class value_t >
696 dictionary(std::initializer_list < key_value_pair < key_t, value_t>>) -> dictionary < key_t, value_t >;
697
698 template < class key_t, class value_t >
699 dictionary(std::initializer_list < std::pair < key_t, value_t>>) -> dictionary < key_t, value_t >;
700
701 template < class input_iterator_t >
702 dictionary(input_iterator_t, input_iterator_t) -> dictionary < helpers::iterator_key_t < input_iterator_t>, helpers::iterator_mapped_t<input_iterator_t >>;
703 // }
705 }
706 }
707}
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:63
Provides a base class for implementations of the xtd::collections::generic::icomparer <type_t> generi...
Definition comparer.hpp:33
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:143
void trim_excess(size_type capacity)
Sets the capacity of this dictionary to hold up a specified number of entries without any further exp...
Definition dictionary.hpp:539
dictionary(dictionary &&other) noexcept=default
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
bool remove(const key_t &key, value_t &value) noexcept
Removes the value with the specified key from the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:524
typename xtd::collections::generic::idictionary< key_type, mapped_type >::value_collection value_collection
Represents the idictionary value collection type.
Definition dictionary.hpp:157
const value_t & operator[](const key_t &key) const override
Gets the element with the specified key.
Definition dictionary.hpp:637
bool contains_value(const value_t &value) const noexcept
Determines whether the xtd::collections::generic::dictionary <key_t, value_t> contains the specified ...
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:307
void add(const value_type &item) override
Adds an item to the xtd::collections::generic::icollection <type_t>.
Definition dictionary.hpp:407
size_type capacity() const noexcept
Definition dictionary.hpp:344
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:294
const iequality_comparer< key_t > & comparer() const noexcept
Gets the td::collections::generic::iequality_comparer <type_t> that is used to determine equality of ...
Definition dictionary.hpp:349
dictionary(const ienumerable< value_type > &collection, const equality_comparer_t &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that c...
Definition dictionary.hpp:269
dictionary(size_t capacity, const equality_comparer_t &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
Definition dictionary.hpp:245
void copy_to(xtd::array< value_type > &array, xtd::size array_index) const override
Copies the elements of the xtd::collections::generic::icollection <type_t> to an xtd::array,...
Definition dictionary.hpp:449
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:315
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:280
xtd::size ensure_capacity(xtd::size capacity) noexcept
Ensures that the dictionary can hold up to a specified number of entries without any further expansio...
Definition dictionary.hpp:459
void clear() noexcept override
Removes all keys and values from the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:413
dictionary() noexcept=default
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
bool try_add(const key_t &key, const value_t value) noexcept
Attempts to add the specified key and value to the dictionary.
Definition dictionary.hpp:559
bool remove(const value_type &item) noexcept override
Removes the first occurrence of a specific object from the xtd::collections::generic::dictionary <key...
Definition dictionary.hpp:516
bool remove(const key_t &key) noexcept override
Removes the value with the specified key from the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:509
void trim_excess()
Sets the capacity of this dictionary to what it would be if it had been originally initialized with a...
Definition dictionary.hpp:550
dictionary & operator=(dictionary &&other) noexcept
Move assignment operator. Replaces the contents with a copy of the contents of other.
Definition dictionary.hpp:586
dictionary(size_t capacity)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
Definition dictionary.hpp:231
void add(const key_t &key, const value_t value) override
Adds an element with the provided key and value to the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:400
bool contains(const value_type &item) const noexcept override
Determines whether an element is in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:421
value_collection values() const noexcept override
Gets a collection containing the values in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:383
std::pair< const key_t, value_t > base_value_type
Represents the dictionary base value type.
Definition dictionary.hpp:151
dictionary(const dictionary &other) noexcept
Initializes instance of the xtd::collections::generic::dictionary <key_t, value_t> class from a varie...
Definition dictionary.hpp:289
std::unordered_map< key_type, mapped_type, hasher, equator, allocator_t > base_type
Represents the dictionary base type.
Definition dictionary.hpp:153
dictionary(const idictionary< key_t, value_t > &dictionary, const equality_comparer_t &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that c...
Definition dictionary.hpp:259
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:330
enumerator< value_type > get_enumerator() const noexcept override
Returns an enumerator that iterates through the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:466
key_collection keys() const noexcept override
Gets a collection containing the keys in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:372
virtual const base_type & items() const noexcept
Returns the underlying base type items.
Definition dictionary.hpp:363
bool try_get_value(const key_t &key, value_t &value) const override
Gets the value associated with the specified key.
Definition dictionary.hpp:569
dictionary(const equality_comparer_t &comparer)
Initializes a new instance of the xtd::collections::generic::dictionary <key_t, value_t> class that i...
Definition dictionary.hpp:222
bool contains_key(const key_t &key) const noexcept override
Determines whether the xtd::collections::generic::dictionary <key_t, value_t> contains the specified ...
Definition dictionary.hpp:431
typename xtd::collections::generic::idictionary< key_type, mapped_type >::key_collection key_collection
Represents the idictionary key collection type.
Definition dictionary.hpp:155
typename xtd::collections::generic::idictionary< key_t, value_t >::mapped_type mapped_type
Represents the dictionary mapped type.
Definition dictionary.hpp:145
typename xtd::collections::generic::idictionary< key_type, mapped_type >::value_type value_type
Represents the dictionary value type.
Definition dictionary.hpp:147
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:212
xtd::string to_string() const noexcept override
Gets a string that represents the current object.
Definition dictionary.hpp:533
virtual base_type & items() noexcept
Returns the underlying base type items.
Definition dictionary.hpp:366
xtd::size size_type
Represents the dictionary size type.
Definition dictionary.hpp:149
size_type count() const noexcept override
Gets the number of key/value pairs contained in the xtd::collections::generic::dictionary <key_t,...
Definition dictionary.hpp:359
static const equality_comparer & default_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
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:114
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::enumerator< xtd::any_object > enumerator
Supports a simple iteration over a non-generic collection.
Definition enumerator.hpp:28
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
std::allocator< type_t > allocator
Represent an allocator alias.
Definition allocator.hpp:38
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:63
@ key_not_found
The key is not found.
Definition exception_case.hpp:69
#define self_
The self_ expression is a reference value expression whose value is the reference of the implicit obj...
Definition self.hpp:20
xtd::basic_string< char > string
Represents text as a sequence of UTF-8 code units.
Definition __string_definitions.hpp:43
size_t size
Represents a size of any object in bytes.
Definition size.hpp:23
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:58
@ a
The A key.
Definition console_key.hpp:88
@ add
The Add key.
Definition console_key.hpp:170
@ b
The B key.
Definition console_key.hpp:90
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.
Represents the dictionary equator type.
Definition dictionary.hpp:104
bool operator()(const key_t &a, const key_t &b) const
checks if the specified a and b keys are equal.
Definition dictionary.hpp:124
key_t first_argument_type
Represents the first argument type.
Definition dictionary.hpp:109
bool result_type
Represents the result type.
Definition dictionary.hpp:113
key_t second_argument_type
Represents the second argument type.
Definition dictionary.hpp:111
Represents the dictionary hasher type.
Definition dictionary.hpp:73
key_t argument_type
Represents the argument type.
Definition dictionary.hpp:78
xtd::size result_type
Represents the result type.
Definition dictionary.hpp:80
size_t operator()(const key_t &key) const
Serves as a hash function for a specified key with a particular type (type_t).
Definition dictionary.hpp:90
Implements a function object for performing comparisons. Unless specialised, invokes operator== on ty...
Definition equator.hpp:38