/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Class Foam::HashSet Description A HashTable with keys but without contents that is similar to \c std::unordered_set. The entries are considered \a unordered since their placement depends on the method used to generate the hash key index, the table capacity, insertion order etc. When the key order is important, use the sortedToc() method to obtain a list of sorted keys and use that for further access. Note The HashSet iterator dereferences to the key, so the following range-for works as expected: \code labelHashSet someLabels{10, 20, 30, 40, ...}; for (const label i : someLabels) { Info<< "val:" << i << nl; } \endcode Typedef Foam::wordHashSet Description A HashSet with word keys and string hasher. Typedef Foam::labelHashSet Description A HashSet with label keys and label hasher. \*---------------------------------------------------------------------------*/ #ifndef Foam_HashSet_H #define Foam_HashSet_H #include "HashTable.H" #include "IndirectList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // Forward Declarations template class MinMax; template class HashSet; // Common hash-set types //- A HashSet of words, uses string hasher. typedef HashSet> wordHashSet; //- A HashSet of labels, uses label hasher. typedef HashSet> labelHashSet; /*---------------------------------------------------------------------------*\ Class HashSet Declaration \*---------------------------------------------------------------------------*/ template> class HashSet : public HashTable { // Private Member Functions //- Assign from the input iterator range template inline label assignMany ( const label nItems, InputIter first, InputIter last ); public: //- The template instance used for this HashSet typedef HashSet this_type; //- The template instance used for the parent HashTable typedef HashTable parent_type; //- An iterator, returning reference to the key using iterator = typename parent_type::key_iterator; //- A const_iterator, returning reference to the key using const_iterator = typename parent_type::const_key_iterator; // Constructors //- Default construct with default (128) table capacity HashSet() : parent_type() {} //- Copy construct HashSet(const this_type& rhs) : parent_type(rhs) {} //- Move construct HashSet(this_type&& rhs) : parent_type(std::move(rhs)) {} //- Construct given initial table capacity explicit HashSet(const label size) : parent_type(size) {} //- Construct from Istream with default table capacity explicit HashSet(Istream& is) : parent_type(is) {} //- Construct from FixedList of Key template explicit HashSet(const FixedList& list); //- Construct from UList of Key explicit HashSet(const UList& list); //- Construct from an indirect list template explicit HashSet(const IndirectListBase& list); //- Construct from an initializer list of Key HashSet(std::initializer_list list); //- Construct from the keys of another HashTable, //- the type of values held is arbitrary. template explicit HashSet(const HashTable& tbl); // Member Functions //- Same as contains() - return true if key exists in the set. // Method name compatibility with bitSet and boolList. bool test(const Key& key) const { return this->contains(key); } // Edit //- Insert a new entry, not overwriting existing entries. // \return True if the entry inserted, which means that it did // not previously exist in the set. bool insert(const Key& key) { return this->parent_type::emplace(key); } //- Same as insert (no value to overwrite) bool set(const Key& key) { return this->parent_type::emplace(key); } //- Unset the specified key - same as erase // \return True if the entry existed and was removed bool unset(const Key& key) { return this->parent_type::erase(key); } //- Attempts to extract entries from source parameter and insert them //- into \c this, does not overwrite existing entries. //- The source will contains any items that could not be merged. void merge(HashSet& source); //- Attempts to extract entries from source parameter and insert them //- into \c this, does not overwrite existing entries. //- The source will contains any items that could not be merged. void merge(HashSet&& source); // Convenience //- Insert keys from the input iterator range // \return The number of new elements inserted template inline label insert(InputIter first, InputIter last); //- Insert keys from a initializer list of Key // \return The number of new elements inserted inline label insert(std::initializer_list list); //- Insert keys from the list of Key // \return The number of new elements inserted template inline label insert(const FixedList& list); //- Insert keys from the list of Key // \return The number of new elements inserted inline label insert(const UList& list); //- Insert keys from the list of Key // \return The number of new elements inserted template inline label insert(const IndirectListBase& list); //- Same as insert (no value to overwrite) template inline label set(InputIter first, InputIter last) { return insert(first, last); } //- Same as insert (no value to overwrite) inline label set(std::initializer_list list) { return insert(list); } //- Same as insert (no value to overwrite) template inline label set(const FixedList& list) { return insert(list); } //- Same as insert (no value to overwrite) inline label set(const UList& list) { return insert(list); } //- Same as insert (no value to overwrite) template inline label set(const IndirectListBase& list) { return insert(list); } //- Same as insert (no value to overwrite) // \note Method name compatibility with bitSet template inline label setMany(InputIter first, InputIter last) { return insert(first, last); } //- Unset the keys listed in the input iterator range // \return The number of items removed template inline label unset(InputIter first, InputIter last); //- Unset the listed keys - same as erase // \return The number of items removed inline label unset(std::initializer_list list); //- Unset the listed keys - same as erase // \return The number of items removed template inline label unset(const FixedList& list); //- Unset the listed keys - same as erase // \return The number of items removed inline label unset(const UList& list); //- Unset the listed keys - same as erase // \return The number of items removed template inline label unset(const IndirectListBase& list); // STL iterators inline iterator begin(); inline const_iterator begin() const; inline const_iterator cbegin() const; inline iterator end() noexcept; inline const_iterator end() const noexcept; inline constexpr const_iterator cend() const noexcept; // Writing //- Write unordered keys (list), with line-breaks //- when length exceeds shortLen. // Using '0' suppresses line-breaks entirely. Ostream& writeList(Ostream& os, const label shortLen=0) const { return this->writeKeys(os, shortLen); } // Member Operators //- Return true if the entry exists, same as contains() // \note this allows use of HashSet as a predicate test inline bool operator()(const Key& key) const noexcept; //- Return true if the entry exists, same as contains(). inline bool operator[](const Key& key) const noexcept; //- Copy assign void operator=(const this_type& rhs) { parent_type::operator=(rhs); } //- Move assign void operator=(this_type&& rhs) { parent_type::operator=(std::move(rhs)); } // Comparison //- Sets are equal if all keys are equal, //- independent of order or underlying storage size. bool operator==(const this_type& rhs) const; //- The opposite of the equality operation. bool operator!=(const this_type& rhs) const; // Assignment //- Assignment from a UList of keys void operator=(const UList& rhs); //- Assignment from a FixedList of keys template void operator=(const FixedList& rhs); //- Assignment from an initializer list of keys void operator=(std::initializer_list rhs); // Logical and set operations //- Add entries to this HashSet this_type& operator|=(const this_type& rhs); //- Only retain entries contained in both HashSets inline this_type& operator&=(const this_type& rhs); //- Only retain unique entries (xor) this_type& operator^=(const this_type& rhs); //- Add entries to this HashSet. Same as the '|=' operator inline this_type& operator+=(const this_type& rhs); //- Remove entries from this HashSet. Uses erase() inline this_type& operator-=(const this_type& rhs); // Housekeeping //- Not applicable for HashSet template List tocValues(const UnaryPredicate&, const bool) = delete; //- Not applicable for HashSet template List tocEntries(const BinaryPredicate&, const bool) = delete; //- Not applicable for HashSet template label countValues(const UnaryPredicate&, const bool) = delete; //- Not applicable for HashSet template label countEntries(const BinaryPredicate&, const bool) = delete; //- Not applicable for HashSet template label filterValues(const UnaryPredicate&, const bool) = delete; //- Not applicable for HashSet template label filterEntries(const BinaryPredicate&, const bool) = delete; }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Global Functions //- Find the min value in labelHashSet, optionally limited by second argument. // For an empty set, returns the second argument (eg, labelMax). label min(const labelHashSet& set, label minValue = labelMax); //- Find the max value in labelHashSet, optionally limited by second argument. // For an empty set, returns the second argument (eg, labelMin). label max(const labelHashSet& set, label maxValue = labelMin); //- Find the min/max values of labelHashSet MinMax