HashTable.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Class
28  Foam::HashTable
29 
30 Description
31  A HashTable similar to \c std::unordered_map.
32 
33  The entries are considered \a unordered since their placement
34  depends on the method used to generate the hash key index, the
35  table capacity, insertion order etc. When the key order is
36  important, use the sortedToc() method to obtain a list of sorted
37  keys and use that for further access, or the csorted()/sorted() methods
38  to obtain a UPtrList of entries to traverse in sorted order.
39 
40  Internally the table uses closed addressing into a flat storage space
41  with collisions handled by linked-list chaining.
42 
43  - The max_load_factor is 0.8, but a load factor 0.5 is generally
44  assumed when initially creating a HashTable (ie, use an capacity
45  of twice the expected number elements).
46  - When inserting into a table without an initial capacity,
47  a default capacity (bucket count) of 128 is used.
48 
49  The end iterator of all hash-tables has a nullptr to the hash entry.
50  Thus avoid separate allocation for each table and use a single one with
51  a nullptr. The hash-table iterators always have an entry-pointer as the
52  first member data, which allows reinterpret_cast from anything else with
53  a nullptr as its first data member.
54  The nullObject is such an item (with a nullptr data member).
55 
56 Note
57  For historical reasons, dereferencing the table iterator
58  (eg, \a *iter) returns a reference to the stored object value
59  rather than the stored key/val pair like std::unordered_map does.
60 
61  The HashTable iterator:
62  \code
63  forAllConstIters(table, iter)
64  {
65  Info<< "val:" << *iter << nl
66  << "key:" << iter.key() << nl
67  << "val:" << iter.val() << nl;
68  }
69  \endcode
70  whereas for the \c std::unordered_map iterator:
71  \code
72  forAllConstIters(stdmap, iter)
73  {
74  Info<< "key/val:" << *iter << nl
75  << "key:" << iter->first << nl
76  << "val:" << iter->second << nl;
77  }
78  \endcode
79  This difference is most evident when using range-for syntax.
80 
81 SourceFiles
82  HashTableI.H
83  HashTableIterI.H
84  HashTable.C
85  HashTableIO.C
86  HashTableIter.C
87 
88 \*---------------------------------------------------------------------------*/
89 
90 #ifndef Foam_HashTable_H
91 #define Foam_HashTable_H
92 
93 #include "stdFoam.H"
94 #include "word.H"
95 #include "zero.H"
96 #include "Hash.H"
97 #include "HashTableDetail.H"
98 #include "HashTableCore.H"
99 
100 #include <iterator>
101 
102 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
103 
104 namespace Foam
105 {
107 // Forward Declarations
109 template<class T> class List;
110 template<class T> class UList;
111 template<class T> class UPtrList;
112 template<class T, unsigned N> class FixedList;
113 template<class T, class Key, class Hash> class HashTable;
114 
115 template<class T, class Key, class Hash>
117 
118 template<class T, class Key, class Hash>
119 Ostream& operator<<(Ostream&, const HashTable<T, Key, Hash>&);
120 
121 /*---------------------------------------------------------------------------*\
122  Class HashTable Declaration
123 \*---------------------------------------------------------------------------*/
124 
125 template<class T, class Key=word, class Hash=Foam::Hash<Key>>
126 class HashTable
127 :
128  public HashTableCore
129 {
130 public:
131 
132  // Data Types
133 
134  //- The template instance used for this HashTable
136 
137  //- A table entry (node) that encapsulates the key/val tuple
138  //- with an additional linked-list entry for hash collisions
139  typedef typename std::conditional
140  <
144  >::type node_type;
145 
146 
147  // STL type definitions
148 
149  //- The second template parameter, type of keys used.
150  typedef Key key_type;
152  //- The first template parameter, type of objects contained.
153  typedef T mapped_type;
154 
155  //- Same as mapped_type for OpenFOAM HashTables
156  // Note that this is different than the std::map definition.
157  typedef T value_type;
158 
159  //- The third template parameter, the hash index method.
160  typedef Hash hasher;
161 
162  //- Pointer type for storing into value_type objects.
163  // This type is usually 'value_type*'.
164  typedef T* pointer;
165 
166  //- Reference to the stored value_type.
167  // This type is usually 'value_type&'.
168  typedef T& reference;
169 
170  //- Const pointer type for the stored value_type.
171  typedef const T* const_pointer;
172 
173  //- Const reference to the stored value_type.
174  typedef const T& const_reference;
176  //- The type to represent the difference between two iterators
177  typedef label difference_type;
178 
179  //- The type that can represent the size of a HashTable.
180  typedef label size_type;
181 
183  //- Forward iterator with non-const access
184  class iterator;
185 
186  //- Forward iterator with const access
187  class const_iterator;
188 
189 
190 private:
191 
192  // Private Data
193 
194  //- The number of elements currently stored in table
195  label size_;
196 
197  //- Number of buckets allocated in table
198  label capacity_;
199 
200  //- The table of primary nodes
201  node_type** table_;
203 
204  // Private Member Functions
205 
206  //- Return the hash index of the Key within the current table size.
207  // No checks for zero-sized tables.
208  inline label hashKeyIndex(const Key& key) const;
209 
210  //- Assign a new hash-entry to a possibly already existing key.
211  // \return True if the new entry was set.
212  template<class... Args>
213  bool setEntry(const bool overwrite, const Key& key, Args&&... args);
214 
215  //- Insert node (low-level). The node must not previously exist!
216  void insert_node(node_type* entry);
217 
218  //- Low-level entry erasure using iterator internals.
219  // This invalidates the iterator until the next ++ operation.
220  // \return True if the corresponding entry existed and was removed
221  bool iterator_erase(iterator& iter);
222 
223  //- Unlink node from iterator (low-level).
224  node_type* iterator_extract(iterator& iter);
225 
226  //- Read hash table
227  Istream& readTable(Istream& is);
228 
229  //- Write hash table
230  Ostream& writeTable(Ostream& os) const;
231 
232 
233 public:
234 
235  // Constructors
236 
237  //- Default construct: empty without allocation (capacity=0)
239 
240  //- Construct empty without allocation (capacity=0)
241  explicit HashTable(const Foam::zero) noexcept;
242 
243  //- Construct empty with initial table capacity
244  explicit HashTable(const label initialCapacity);
245 
246  //- Construct from Istream
247  HashTable(Istream& is);
248 
249  //- Copy construct
250  HashTable(const this_type& ht);
251 
252  //- Move construct
254 
255  //- Construct from an initializer list
256  // Duplicate entries are handled by overwriting
257  HashTable(std::initializer_list<std::pair<Key, T>> list);
258 
259 
260  //- Destructor
261  ~HashTable();
262 
263 
264  // Member Functions
265 
266  // Capacity
267 
268  //- True if the hash table is empty
269  bool empty() const noexcept { return !size_; }
270 
271  //- The number of elements in table
272  label size() const noexcept { return size_; }
273 
274  //- The size of the underlying table (the number of buckets)
275  label capacity() const noexcept { return capacity_; }
276 
277 
278  // Access
279 
280  //- Find and return a hashed entry. FatalError if it does not exist.
281  inline T& at(const Key& key);
282 
283  //- Find and return a hashed entry. FatalError if it does not exist.
284  inline const T& at(const Key& key) const;
285 
286  //- True if hashed key is contained (found) in table
287  inline bool contains(const Key& key) const;
288 
289  //- Find and return an iterator set at the hashed entry
290  // If not found iterator = end()
291  inline iterator find(const Key& key);
292 
293  //- Find and return an const_iterator set at the hashed entry
294  // If not found iterator = end()
295  inline const_iterator find(const Key& key) const;
296 
297  //- Find and return an const_iterator set at the hashed entry
298  // If not found iterator = end()
299  inline const_iterator cfind(const Key& key) const;
300 
301  //- Return hashed entry if it exists, or return the given default
302  inline const T& lookup(const Key& key, const T& deflt) const;
303 
304 
305  // Table of contents
306 
307  //- The table of contents (the keys) in unsorted order.
308  List<Key> toc() const;
309 
310  //- The table of contents (the keys) in sorted order
311  List<Key> sortedToc() const;
312 
313  //- The table of contents (the keys) sorted according to the
314  //- specified comparator
315  template<class Compare>
316  List<Key> sortedToc(const Compare& comp) const;
317 
318  //- The table of contents (the keys) selected according to the
319  //- unary predicate applied to the \b keys.
320  // \param invert changes the logic to select when the predicate
321  // is false
322  // \return sorted list of selected keys
323  template<class UnaryPredicate>
324  List<Key> tocKeys
325  (
326  const UnaryPredicate& pred,
327  const bool invert = false
328  ) const;
329 
330  //- The table of contents (the keys) selected according to the
331  //- unary predicate applied to the \b values.
332  // \param invert changes the logic to select when the predicate
333  // is false
334  // \return sorted list of selected keys
335  template<class UnaryPredicate>
336  List<Key> tocValues
337  (
338  const UnaryPredicate& pred,
339  const bool invert = false
340  ) const;
341 
342  //- The table of contents (the keys) selected according to the
343  //- binary predicate applied to the \b keys and \b values.
344  // \param invert changes the logic to select when the predicate
345  // is false
346  // \return sorted list of selected keys
347  template<class BinaryPredicate>
349  (
350  const BinaryPredicate& pred,
351  const bool invert = false
352  ) const;
353 
354 
355  // Sorted entries
356 
357  //- Const access to the hash-table contents in sorted order
358  //- (sorted by keys).
359  // The lifetime of the returned content cannot exceed the parent!
361 
362  //- Non-const access to the hash-table contents in sorted order
363  //- (sorted by keys).
364  // The lifetime of the returned content cannot exceed the parent!
366 
367 
368  // Counting
369 
370  //- Count the number of keys that satisfy the unary predicate
371  // \param invert changes the logic to select when the predicate
372  // is false
373  template<class UnaryPredicate>
374  label countKeys
375  (
376  const UnaryPredicate& pred,
377  const bool invert = false
378  ) const;
379 
380  //- Count the number of values that satisfy the unary predicate
381  // \param invert changes the logic to select when the predicate
382  // is false
383  template<class UnaryPredicate>
384  label countValues
385  (
386  const UnaryPredicate& pred,
387  const bool invert = false
388  ) const;
389 
390  //- Count the number of entries that satisfy the binary predicate.
391  // \param invert changes the logic to select when the predicate
392  // is false
393  template<class BinaryPredicate>
394  label countEntries
395  (
396  const BinaryPredicate& pred,
397  const bool invert = false
398  ) const;
399 
400 
401  // Edit
402 
403  //- Emplace insert a new entry, not overwriting existing entries.
404  // \return True if the entry did not previously exist in the table.
405  template<class... Args>
406  inline bool emplace(const Key& key, Args&&... args);
407 
408  //- Emplace set an entry, overwriting any existing entries.
409  // \return True, since it always overwrites any entries.
410  template<class... Args>
411  inline bool emplace_set(const Key& key, Args&&... args);
412 
413  //- Copy insert a new entry, not overwriting existing entries.
414  // \return True if the entry did not previously exist in the table.
415  inline bool insert(const Key& key, const T& obj);
416 
417  //- Move insert a new entry, not overwriting existing entries.
418  // \return True if the entry did not previously exist in the table.
419  inline bool insert(const Key& key, T&& obj);
420 
421  //- Copy assign a new entry, overwriting existing entries.
422  // \return True, since it always overwrites any entries.
423  inline bool set(const Key& key, const T& obj);
424 
425  //- Move assign a new entry, overwriting existing entries.
426  // \return True, since it always overwrites any entries.
427  inline bool set(const Key& key, T&& obj);
428 
429  //- Erase an entry specified by given iterator
430  // This invalidates the iterator until the next ++ operation.
431  //
432  // Includes a safeguard against the end-iterator such that the
433  // following is safe:
434  // \code
435  // auto iter = table.find(unknownKey);
436  // table.erase(iter);
437  // \endcode
438  // which is what \code table.erase(unknownKey) \endcode does anyhow.
439  //
440  // \return True if the corresponding entry existed and was removed
441  bool erase(const iterator& iter);
442 
443  //- Erase an entry specified by the given key
444  // \return True if the entry existed and was removed
445  bool erase(const Key& key);
446 
447  //- Remove table entries given by keys of the other hash-table.
448  //
449  // The other hash-table must have the same type of key, but the
450  // type of values held and the hashing function are arbitrary.
451  //
452  // \return The number of items removed
453  template<class AnyType, class AnyHash>
454  label erase(const HashTable<AnyType, Key, AnyHash>& other);
455 
456  //- Remove table entries given by the listed keys
457  // \return The number of items removed
458  inline label erase(std::initializer_list<Key> keys);
459 
460  //- Remove multiple entries using an iterator range of keys
461  template<class InputIter>
462  inline label erase(InputIter first, InputIter last);
463 
464  //- Remove table entries given by the listed keys
465  // \return The number of items removed
466  template<unsigned N>
467  inline label erase(const FixedList<Key, N>& keys);
468 
469  //- Remove table entries given by the listed keys
470  // \return The number of items removed
471  inline label erase(const UList<Key>& keys);
472 
473  //- Retain table entries given by keys of the other hash-table.
474  //
475  // The other hash-table must have the same type of key, but the
476  // type of values held and the hashing function are arbitrary.
477  //
478  // \return The number of items changed (removed)
479  template<class AnyType, class AnyHash>
480  label retain(const HashTable<AnyType, Key, AnyHash>& other);
481 
482  //- Generalized means to filter table entries based on their keys.
483  // Keep (or optionally prune) entries with keys that satisfy
484  // the unary predicate, which has the following signature:
485  // \code
486  // bool operator()(const Key& k);
487  // \endcode
488  //
489  // For example,
490  // \code
491  // wordRes goodFields = ...;
492  // allFieldNames.filterKeys
493  // (
494  // [&goodFields](const word& k){ return goodFields.match(k); }
495  // );
496  // \endcode
497  //
498  // \return The number of items changed (removed)
499  template<class UnaryPredicate>
500  label filterKeys
501  (
502  const UnaryPredicate& pred,
503  const bool pruning = false
504  );
505 
506  //- Generalized means to filter table entries based on their values.
507  // Keep (or optionally prune) entries with values that satisfy
508  // the unary predicate, which has the following signature:
509  // \code
510  // bool operator()(const T& v);
511  // \endcode
512  //
513  // \return The number of items changed (removed)
514  template<class UnaryPredicate>
515  label filterValues
516  (
517  const UnaryPredicate& pred,
518  const bool pruning = false
519  );
520 
521  //- Generalized means to filter table entries based on their key/value.
522  // Keep (or optionally prune) entries with keys/values that satisfy
523  // the binary predicate, which has the following signature:
524  // \code
525  // bool operator()(const Key& k, const T& v);
526  // \endcode
527  //
528  // \return The number of items changed (removed)
529  template<class BinaryPredicate>
530  label filterEntries
531  (
532  const BinaryPredicate& pred,
533  const bool pruning = false
534  );
535 
536 
537  //- Remove all entries from table
538  void clear();
539 
540  //- Remove all entries from table and the table itself.
541  // Equivalent to clear() followed by setCapacity(0)
542  void clearStorage();
543 
544  //- Change the hash table capacity (number of buckets).
545  // Setting a zero capacity will only remove the underlying
546  // storage if the table is empty.
547  void setCapacity(label newCapacity);
548 
549  //- Rehash the hash table with new number of buckets.
550  //- Currently identical to setCapacity()
551  void resize(label newCapacity);
552 
553  //- Reserve space for at least the specified number of elements
554  //- (not the number of buckets) and regenerates the hash table.
555  void reserve(label numEntries);
556 
557  //- Swap contents into this table
559 
560  //- Transfer contents into this table.
562 
563  //- Attempts to extract entries from source parameter and insert them
564  //- into \c this, does not overwrite existing entries.
565  //- The source will contains any items that could not be merged.
566  void merge(HashTable<T, Key, Hash>& source);
567 
568  //- Attempts to extract entries from source parameter and insert them
569  //- into \c this, does not overwrite existing entries.
570  //- The source will contains any items that could not be merged.
571  void merge(HashTable<T, Key, Hash>&& source);
572 
573 
574  // Member Operators
575 
576  //- Find and return a hashed entry. FatalError if it does not exist.
577  // Same as at().
578  inline T& operator[](const Key& key);
579 
580  //- Find and return a hashed entry. FatalError if it does not exist.
581  // Same as at().
582  inline const T& operator[](const Key& key) const;
583 
584  //- Return existing entry or create a new entry.
585  // A newly created entry is created as a nameless T() and is thus
586  // value-initialized. For primitives, this will be zero.
587  inline T& operator()(const Key& key);
588 
589  //- Return existing entry or insert a new entry.
590  inline T& operator()(const Key& key, const T& deflt);
591 
592  //- Copy assign
593  void operator=(const this_type& rhs);
594 
595  //- Copy assign from an initializer list
596  // Duplicate entries are handled by overwriting
597  void operator=(std::initializer_list<std::pair<Key, T>> rhs);
598 
599  //- Move assign
600  void operator=(this_type&& rhs);
601 
602  //- Equality. Tables are equal if all keys and values are equal,
603  //- independent of order or underlying storage size.
604  bool operator==(const this_type& rhs) const;
605 
606  //- The opposite of the equality operation.
607  bool operator!=(const this_type& rhs) const;
608 
609  //- Add entries into this HashTable
610  this_type& operator+=(const this_type& rhs);
611 
612 
613 protected:
614 
615  // Iterators and helpers
616 
617  //- Internally used base for iterator and const_iterator
618  template<bool Const> class Iterator;
619 
620  //- Allow iterator access to HashTable internals.
621  friend class Iterator<true>;
622 
623  //- Allow iterator access to HashTable internals.
624  friend class Iterator<false>;
625 
626  //- The iterator base for HashTable (internal use only).
627  // Note: data and functions are protected, to allow reuse by iterator
628  // and prevent most external usage.
629  // iterator and const_iterator have the same size, allowing
630  // us to reinterpret_cast between them (if desired)
631 
632  template<bool Const>
633  class Iterator
634  {
635  public:
636 
637  // Typedefs
638  using iterator_category = std::forward_iterator_tag;
640 
641  //- The HashTable container type
642  using table_type = typename std::conditional
643  <
644  Const,
645  const this_type,
646  this_type
647  >::type;
648 
649  //- The node-type being addressed
650  using node_type = typename std::conditional
651  <
652  Const,
653  const this_type::node_type,
655  >::type;
656 
657  //- The key type
659 
660  //- The object type being addressed
661  using mapped_type = typename std::conditional
662  <
663  Const,
666  >::type;
667 
668 
669  protected:
670 
671  // Protected Data
672 
673  //- The selected entry.
674  // MUST be the first member for easy comparison between iterators
675  // and to support reinterpret_cast from nullObject
676  node_type* entry_;
677 
678  //- The hash-table container being iterated on.
679  // Uses pointer for default copy/assignment
681 
682  //- Index within the hash-table data.
683  // A signed value, since iterator_erase() needs a negative value
684  // to mark the position.
685  label index_;
686 
687  // Friendship with HashTable, for begin/find constructors
688  friend class HashTable;
689 
690 
691  // Protected Constructors
692 
693  //- Default construct. Also the same as the end iterator
694  inline constexpr Iterator() noexcept;
695 
696  //- Construct from begin of hash-table
697  inline explicit Iterator(table_type* tbl);
698 
699  //- Construct by finding key in hash table
700  Iterator(table_type* tbl, const Key& key);
701 
702 
703  // Protected Member Functions
704 
705  //- Increment to the next position
706  inline void increment();
707 
708  //- Permit explicit cast to the other (const/non-const) iterator
709  template<bool Any>
710  explicit operator const Iterator<Any>&() const
711  {
712  return *reinterpret_cast<const Iterator<Any>*>(this);
713  }
714 
715 
716  public:
717 
718  // Member Functions
719 
720  //- True if iterator points to an entry
721  // This can be used directly instead of comparing to end()
722  bool good() const noexcept { return entry_; }
723 
724  //- True if iterator points to an entry - same as good()
725  bool found() const noexcept { return entry_; }
726 
727  //- The key associated with the iterator
728  const Key& key() const { return entry_->key(); }
729 
730  //- Write the (key, val) pair
731  inline Ostream& print(Ostream& os) const;
732 
733 
734  // Member Operators
735 
736  //- True if iterator points to an entry
737  // This can be used directly instead of comparing to end()
738  explicit operator bool() const noexcept { return entry_; }
739 
740  //- Compare hash-entry element pointers.
741  // Independent of const/non-const access
742  template<bool Any>
743  bool operator==(const Iterator<Any>& iter) const noexcept
744  {
745  return (entry_ == iter.entry_);
746  }
747 
748  template<bool Any>
749  bool operator!=(const Iterator<Any>& iter) const noexcept
750  {
751  return (entry_ != iter.entry_);
752  }
753  };
754 
755 public:
756 
757  //- Forward iterator with non-const access
758  class iterator
759  :
760  public Iterator<false>
761  {
762  public:
763 
764  // Typedefs
765  using iterator_category = std::forward_iterator_tag;
767 
772  using pointer = this_type::pointer;
776 
777 
778  // Constructors
779 
780  //- Default construct (end iterator)
781  iterator() = default;
782 
783  //- Copy construct from similar access type
784  explicit iterator(const Iterator<false>& iter)
785  :
786  Iterator<false>(iter)
787  {}
788 
789 
790  // Member Functions/Operators
791 
792  //- Const access to the entry (node)
793  const node_type* node() const noexcept
794  {
796  }
797 
798  //- Non-const access to the entry (node)
800  {
802  }
803 
804  //- Const access to referenced object (value)
805  const_reference val() const
806  {
807  return Iterator<false>::entry_->cval();
808  }
809 
810  //- Non-const access to referenced object (value)
811  reference val()
812  {
813  return Iterator<false>::entry_->val();
814  }
815 
816  //- Const access to referenced object (value)
817  const_reference operator*() const { return this->val(); }
818  const_reference operator()() const { return this->val(); }
819 
820  //- Non-const access to referenced object (value)
821  reference operator*() { return this->val(); }
822  reference operator()() { return this->val(); }
823 
824  inline iterator& operator++();
825  inline iterator operator++(int);
826  };
827 
828 
829  // STL const_iterator
830 
831  //- Forward iterator with const access
832  class const_iterator
833  :
834  public Iterator<true>
835  {
836  public:
837 
838  // Typedefs
839  using iterator_category = std::forward_iterator_tag;
841 
844  using mapped_type = const this_type::mapped_type;
845  using value_type = const this_type::value_type;
848 
849 
850  // Generated Methods
851 
852  //- Default construct (end iterator)
853  const_iterator() = default;
854 
855  //- Copy construct
856  const_iterator(const const_iterator&) = default;
857 
858  //- Copy assignment
859  const_iterator& operator=(const const_iterator&) = default;
862  // Constructors
863 
864  //- Copy construct from any access type
865  template<bool Any>
866  const_iterator(const Iterator<Any>& iter)
867  :
868  Iterator<true>(static_cast<const Iterator<Any>&>(iter))
869  {}
870 
871  //- Implicit conversion from dissimilar access type
872  const_iterator(const iterator& iter)
873  :
874  const_iterator(reinterpret_cast<const const_iterator&>(iter))
875  {}
876 
877 
878  // Member Functions/Operators
879 
880  //- Const access to the entry (node)
881  const node_type* node() const noexcept
882  {
883  return Iterator<true>::entry_;
884  }
885 
886  //- Const access to referenced object (value)
887  reference val() const
888  {
889  return Iterator<true>::entry_->cval();
890  }
891 
892  //- Const access to referenced object (value)
893  reference operator*() const { return this->val(); }
894  reference operator()() const { return this->val(); }
895 
897  inline const_iterator operator++(int);
898 
899 
900  // Assignment
901 
902  // Allow assign from iterator to const_iterator
903  const_iterator& operator=(const iterator& iter)
904  {
905  return this->operator=
906  (
907  reinterpret_cast<const const_iterator&>(iter)
908  );
909  }
910  };
911 
912 
913  // Iterator (keys)
914 
915  //- An iterator wrapper for returning a reference to the key
916  template<class Iter>
917  class key_iterator_base
918  :
919  public Iter
920  {
921  public:
922 
924  using pointer = const Key*;
925  using reference = const Key&;
926 
927  //- Default construct (end iterator)
928  constexpr key_iterator_base() noexcept
929  :
930  Iter()
931  {}
932 
933  //- Copy construct with implicit conversion
934  explicit key_iterator_base(const Iter& iter)
935  :
936  Iter(iter)
937  {}
938 
939  //- Return the key
940  reference operator*() const { return this->key(); }
941  reference operator()() const { return this->key(); }
942 
944  {
945  this->increment();
946  return *this;
947  }
948 
950  {
951  key_iterator_base iter(*this);
952  this->increment();
953  return iter;
954  }
955  };
956 
957 
958  //- Forward iterator returning the key
960 
961  //- Forward const iterator returning the key
963 
964  //- A const iterator begin/end pair for iterating over keys
966  {
968  }
969 
970 
971  // Iterator access
972 
973  //- iterator set to the beginning of the HashTable
974  inline iterator begin();
975 
976  //- const_iterator set to the beginning of the HashTable
977  inline const_iterator begin() const;
978 
979  //- const_iterator set to the beginning of the HashTable
980  inline const_iterator cbegin() const;
981 
982  //- iterator to signal the end (for any HashTable)
983  inline iterator end() noexcept;
985  //- const_iterator to signal the end (for any HashTable)
986  inline const_iterator end() const noexcept;
987 
988  //- const_iterator to signal the end (for any HashTable)
989  inline constexpr const_iterator cend() const noexcept;
990 
991 
992  // Reading/writing
993 
994  //- Print information
995  Ostream& printInfo(Ostream& os) const;
996 
997  //- Write unordered keys (list), with line-breaks
998  //- when length exceeds shortLen.
999  // Using '0' suppresses line-breaks entirely.
1000  Ostream& writeKeys(Ostream& os, const label shortLen=0) const;
1001 
1002 
1003  // IOstream Operators
1004 
1005  friend Istream& operator>> <T, Key, Hash>
1006  (
1008  HashTable<T, Key, Hash>& tbl
1009  );
1010 
1011  friend Ostream& operator<< <T, Key, Hash>
1012  (
1014  const HashTable<T, Key, Hash>& tbl
1015  );
1016 
1017 
1018  // Housekeeping
1019 
1020  //- Same as contains()
1021  bool found(const Key& key) const { return this->contains(key); }
1022 
1023  //- Deprecated(2023-07) use csorted() method
1024  // \deprecated(2023-07) - use csorted() method
1025  FOAM_DEPRECATED_FOR(2023-07, "csorted() method")
1026  UPtrList<const node_type> sorted() const { return this->csorted(); }
1027 };
1028 
1029 
1030 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1032 } // End namespace Foam
1033 
1034 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1036 #include "HashTableI.H"
1039 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1041 #ifndef NoHashTableC // Excluded from token.H
1042 #ifdef NoRepository
1043  #include "HashTable.C"
1044 #endif
1045 #endif
1046 
1047 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1048 
1049 #endif
1050 
1051 // ************************************************************************* //
reference operator*() const
Return the key.
Definition: HashTable.H:1248
label countValues(const UnaryPredicate &pred, const bool invert=false) const
Count the number of values that satisfy the unary predicate.
node_type * entry_
The selected entry.
Definition: HashTable.H:909
void increment()
Increment to the next position.
List< Key > tocKeys(const UnaryPredicate &pred, const bool invert=false) const
The table of contents (the keys) selected according to the unary predicate applied to the keys...
std::forward_iterator_tag iterator_category
Definition: HashTable.H:1123
reference val() const
Const access to referenced object (value)
Definition: HashTable.H:1185
Factory class for creating a begin/end pair for any const iterator.
Definition: HashTableCore.H:87
const_reference operator()() const
Definition: HashTable.H:1098
type
Types of root.
Definition: Roots.H:52
label index_
Index within the hash-table data.
Definition: HashTable.H:924
bool emplace(const Key &key, Args &&... args)
Emplace insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:129
const node_type * node() const noexcept
Const access to the entry (node)
Definition: HashTable.H:1065
bool operator!=(const this_type &rhs) const
The opposite of the equality operation.
Definition: HashTable.C:987
this_type & operator+=(const this_type &rhs)
Add entries into this HashTable.
Definition: HashTable.C:997
Internally used base for iterator and const_iterator.
Definition: HashTable.H:833
Forward iterator with const access.
Definition: HashTable.H:1116
label filterValues(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their values.
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:107
std::forward_iterator_tag iterator_category
Definition: HashTable.H:860
label retain(const HashTable< AnyType, Key, AnyHash > &other)
Retain table entries given by keys of the other hash-table.
bool found(const Key &key) const
Same as contains()
Definition: HashTable.H:1354
this_type::value_type value_type
Definition: HashTable.H:1037
Internal storage type for HashSet entries.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
this_type::reference reference
Definition: HashTable.H:1039
iterator()=default
Default construct (end iterator)
friend Ostream & operator(Ostream &, const HashTable< T, Key, Hash > &tbl)
label size_type
The type that can represent the size of a HashTable.
Definition: HashTable.H:202
Hash hasher
The third template parameter, the hash index method.
Definition: HashTable.H:168
UPtrList< const node_type > csorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:164
HashTable< T, Key, Hash > this_type
The template instance used for this HashTable.
Definition: HashTable.H:132
void setCapacity(label newCapacity)
Change the hash table capacity (number of buckets).
Definition: HashTable.C:635
T & at(const Key &key)
Find and return a hashed entry. FatalError if it does not exist.
Definition: HashTableI.H:38
const_reference val() const
Const access to referenced object (value)
Definition: HashTable.H:1081
std::conditional< std::is_same< Foam::zero, typename std::remove_cv< T >::type >::value, Detail::HashTableSingle< Key >, Detail::HashTablePair< Key, T > >::type node_type
A table entry (node) that encapsulates the key/val tuple with an additional linked-list entry for has...
Definition: HashTable.H:143
HashTable() noexcept
Default construct: empty without allocation (capacity=0)
Definition: HashTable.C:33
iterator end() noexcept
iterator to signal the end (for any HashTable)
typename std::conditional< Const, const this_type::node_type, this_type::node_type >::type node_type
The node-type being addressed.
Definition: HashTable.H:881
const_reference operator*() const
Const access to referenced object (value)
Definition: HashTable.H:1097
UPtrList< node_type > sorted()
Non-const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:183
const_iterator & operator=(const const_iterator &)=default
Copy assignment.
bool operator==(const this_type &rhs) const
Equality. Tables are equal if all keys and values are equal, independent of order or underlying stora...
Definition: HashTable.C:961
List< Key > tocEntries(const BinaryPredicate &pred, const bool invert=false) const
The table of contents (the keys) selected according to the binary predicate applied to the keys and v...
bool emplace_set(const Key &key, Args &&... args)
Emplace set an entry, overwriting any existing entries.
Definition: HashTableI.H:141
class FOAM_DEPRECATED_FOR(2017-05, "Foam::Enum") NamedEnum
Definition: NamedEnum.H:65
T * pointer
Pointer type for storing into value_type objects.
Definition: HashTable.H:175
Forward iterator with non-const access.
Definition: HashTable.H:1024
const node_type * node() const noexcept
Const access to the entry (node)
Definition: HashTable.H:1177
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:342
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
label countEntries(const BinaryPredicate &pred, const bool invert=false) const
Count the number of entries that satisfy the binary predicate.
reference operator*() const
Const access to referenced object (value)
Definition: HashTable.H:1193
reference operator()() const
Definition: HashTable.H:1194
label capacity() const noexcept
The size of the underlying table (the number of buckets)
Definition: HashTable.H:347
bool contains(const Key &key) const
True if hashed key is contained (found) in table.
Definition: HashTableI.H:72
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:113
Ostream & writeKeys(Ostream &os, const label shortLen=0) const
Write unordered keys (list), with line-breaks when length exceeds shortLen.
Definition: HashTableIO.C:77
void operator=(const this_type &rhs)
Copy assign.
A class for handling words, derived from Foam::string.
Definition: word.H:63
iterator find(const Key &key)
Find and return an iterator set at the hashed entry.
Definition: HashTableI.H:86
label filterEntries(const BinaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their key/value.
Ostream & printInfo(Ostream &os) const
Print information.
Definition: HashTableIO.C:40
Istream & operator>>(Istream &, directionInfo &)
void clear()
Remove all entries from table.
Definition: HashTable.C:725
this_type::node_type node_type
Definition: HashTable.H:1034
constexpr key_iterator_base() noexcept
Default construct (end iterator)
Definition: HashTable.H:1232
T & operator()(const Key &key)
Return existing entry or create a new entry.
Definition: HashTableI.H:249
this_type::const_pointer const_pointer
Definition: HashTable.H:1040
T mapped_type
The first template parameter, type of objects contained.
Definition: HashTable.H:156
bool found() const noexcept
True if iterator points to an entry - same as good()
Definition: HashTable.H:979
this_type::pointer pointer
Definition: HashTable.H:1038
label difference_type
The type to represent the difference between two iterators.
Definition: HashTable.H:197
iterator begin()
iterator set to the beginning of the HashTable
const_iterator()=default
Default construct (end iterator)
this_type::key_type key_type
Definition: HashTable.H:1035
label countKeys(const UnaryPredicate &pred, const bool invert=false) const
Count the number of keys that satisfy the unary predicate.
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
const Key & key() const
The key associated with the iterator.
Definition: HashTable.H:984
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
key_iterator_base & operator++()
Definition: HashTable.H:1251
void resize(label newCapacity)
Rehash the hash table with new number of buckets. Currently identical to setCapacity() ...
Definition: HashTable.C:705
typename std::conditional< Const, const this_type, this_type >::type table_type
The HashTable container type.
Definition: HashTable.H:871
const T & const_reference
Const reference to the stored value_type.
Definition: HashTable.H:192
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
bool empty() const noexcept
True if the hash table is empty.
Definition: HashTable.H:337
An iterator wrapper for returning a reference to the key.
Definition: HashTable.H:1219
this_type::const_reference const_reference
Definition: HashTable.H:1041
T value_type
Same as mapped_type for OpenFOAM HashTables.
Definition: HashTable.H:163
Key key_type
The second template parameter, type of keys used.
Definition: HashTable.H:151
OBJstream os(runTime.globalPath()/outputName)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
bool operator!=(const Iterator< Any > &iter) const noexcept
Definition: HashTable.H:1013
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:472
std::forward_iterator_tag iterator_category
Definition: HashTable.H:1031
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:29
table_type * container_
The hash-table container being iterated on.
Definition: HashTable.H:916
const T & lookup(const Key &key, const T &deflt) const
Return hashed entry if it exists, or return the given default.
Definition: HashTableI.H:222
Bits that are independent of HashTable template parameters.
Definition: HashTableCore.H:54
constexpr Iterator() noexcept
Default construct. Also the same as the end iterator.
Hash function class. The default definition is for primitives. Non-primitives used to hash entries on...
Definition: Hash.H:47
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
void merge(HashTable< T, Key, Hash > &source)
Attempts to extract entries from source parameter and insert them into this, does not overwrite exist...
Definition: HashTable.C:871
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:139
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition: HashTable.C:712
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition: HashTable.C:777
T & reference
Reference to the stored value_type.
Definition: HashTable.H:182
Internal storage type for HashTable entries.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:66
label filterKeys(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their keys.
void swap(HashTable< T, Key, Hash > &rhs) noexcept
Swap contents into this table.
Definition: HashTable.C:763
Includes some standard C++ headers, defines global macros and templates used in multiple places by Op...
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
this_type::difference_type difference_type
Definition: HashTable.H:1032
friend class Iterator< false >
Allow iterator access to HashTable internals.
Definition: HashTable.H:843
const T * const_pointer
Const pointer type for the stored value_type.
Definition: HashTable.H:187
Ostream & print(Ostream &os) const
Write the (key, val) pair.
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:124
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
this_type::mapped_type mapped_type
Definition: HashTable.H:1036
bool good() const noexcept
True if iterator points to an entry.
Definition: HashTable.H:974
Foam::argList args(argc, argv)
bool operator==(const Iterator< Any > &iter) const noexcept
Compare hash-entry element pointers.
Definition: HashTable.H:1007
const_iterator_pair< const_key_iterator, this_type > keys() const
A const iterator begin/end pair for iterating over keys.
Definition: HashTable.H:1279
constexpr const_iterator cend() const noexcept
const_iterator to signal the end (for any HashTable)
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
void clearStorage()
Remove all entries from table and the table itself.
Definition: HashTable.C:750
T & operator[](const Key &key)
Find and return a hashed entry. FatalError if it does not exist.
Definition: HashTableI.H:235
List< Key > tocValues(const UnaryPredicate &pred, const bool invert=false) const
The table of contents (the keys) selected according to the unary predicate applied to the values...