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-2024 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 key/value pairs in initializer list
256  // By default, uses insert not overwrite semantics for duplicates.
257  HashTable
258  (
259  std::initializer_list<std::pair<Key, T>> list,
260  const bool overwrite = false
261  );
262 
263  //- Construct from key/value pairs
264  // By default, uses insert not overwrite semantics for duplicates.
265  HashTable
266  (
267  const UList<Key>& keys,
268  const UList<T>& values,
269  const bool overwrite = false
270  );
271 
272 
273  //- Destructor
274  ~HashTable();
275 
276 
277  // Member Functions
278 
279  // Capacity
280 
281  //- True if the hash table is empty
282  bool empty() const noexcept { return !size_; }
283 
284  //- The number of elements in table
285  label size() const noexcept { return size_; }
286 
287  //- The size of the underlying table (the number of buckets)
288  label capacity() const noexcept { return capacity_; }
289 
290 
291  // Access
292 
293  //- Find and return a hashed entry. FatalError if it does not exist.
294  inline T& at(const Key& key);
295 
296  //- Find and return a hashed entry. FatalError if it does not exist.
297  inline const T& at(const Key& key) const;
298 
299  //- True if hashed key is contained (found) in table
300  inline bool contains(const Key& key) const;
301 
302  //- Find and return an iterator set at the hashed entry
303  // If not found iterator = end()
304  inline iterator find(const Key& key);
305 
306  //- Find and return an const_iterator set at the hashed entry
307  // If not found iterator = end()
308  inline const_iterator find(const Key& key) const;
309 
310  //- Find and return an const_iterator set at the hashed entry
311  // If not found iterator = end()
312  inline const_iterator cfind(const Key& key) const;
313 
314  //- Return hashed entry if it exists, or return the given default
315  inline const T& lookup(const Key& key, const T& deflt) const;
316 
317 
318  // Table of contents
319 
320  //- The table of contents (the keys) in unsorted order.
321  List<Key> toc() const;
322 
323  //- The table of contents (the keys) in sorted order
324  List<Key> sortedToc() const;
325 
326  //- The table of contents (the keys) sorted according to the
327  //- specified comparator
328  template<class Compare>
329  List<Key> sortedToc(const Compare& comp) const;
330 
331  //- The table of contents (the keys) selected according to the
332  //- unary predicate applied to the \b keys.
333  // \param invert changes the logic to select when the predicate
334  // is false
335  // \return sorted list of selected keys
336  template<class UnaryPredicate>
337  List<Key> tocKeys
338  (
339  const UnaryPredicate& pred,
340  const bool invert = false
341  ) const;
342 
343  //- The table of contents (the keys) selected according to the
344  //- unary predicate applied to the \b values.
345  // \param invert changes the logic to select when the predicate
346  // is false
347  // \return sorted list of selected keys
348  template<class UnaryPredicate>
349  List<Key> tocValues
350  (
351  const UnaryPredicate& pred,
352  const bool invert = false
353  ) const;
354 
355  //- The table of contents (the keys) selected according to the
356  //- binary predicate applied to the \b keys and \b values.
357  // \param invert changes the logic to select when the predicate
358  // is false
359  // \return sorted list of selected keys
360  template<class BinaryPredicate>
362  (
363  const BinaryPredicate& pred,
364  const bool invert = false
365  ) const;
366 
367 
368  // Sorted entries
369 
370  //- Const access to the hash-table contents in sorted order
371  //- (sorted by keys).
372  // The lifetime of the returned content cannot exceed the parent!
374 
375  //- Non-const access to the hash-table contents in sorted order
376  //- (sorted by keys).
377  // The lifetime of the returned content cannot exceed the parent!
379 
380 
381  // Counting
382 
383  //- Count the number of keys that satisfy the unary predicate
384  // \param invert changes the logic to select when the predicate
385  // is false
386  template<class UnaryPredicate>
387  label countKeys
388  (
389  const UnaryPredicate& pred,
390  const bool invert = false
391  ) const;
392 
393  //- Count the number of values that satisfy the unary predicate
394  // \param invert changes the logic to select when the predicate
395  // is false
396  template<class UnaryPredicate>
397  label countValues
398  (
399  const UnaryPredicate& pred,
400  const bool invert = false
401  ) const;
402 
403  //- Count the number of entries that satisfy the binary predicate.
404  // \param invert changes the logic to select when the predicate
405  // is false
406  template<class BinaryPredicate>
407  label countEntries
408  (
409  const BinaryPredicate& pred,
410  const bool invert = false
411  ) const;
412 
413 
414  // Edit
415 
416  //- Emplace insert a new entry, not overwriting existing entries.
417  // \return True if the entry did not previously exist in the table.
418  template<class... Args>
419  inline bool emplace(const Key& key, Args&&... args);
420 
421  //- Emplace set an entry, overwriting any existing entries.
422  // \return True, since it always overwrites any entries.
423  template<class... Args>
424  inline bool emplace_set(const Key& key, Args&&... args);
425 
426  //- Copy insert a new entry, not overwriting existing entries.
427  // \return True if the entry did not previously exist in the table.
428  inline bool insert(const Key& key, const T& obj);
429 
430  //- Move insert a new entry, not overwriting existing entries.
431  // \return True if the entry did not previously exist in the table.
432  inline bool insert(const Key& key, T&& obj);
433 
434  //- Copy assign a new entry, overwriting existing entries.
435  // \return True, since it always overwrites any entries.
436  inline bool set(const Key& key, const T& obj);
437 
438  //- Move assign a new entry, overwriting existing entries.
439  // \return True, since it always overwrites any entries.
440  inline bool set(const Key& key, T&& obj);
441 
442  //- Erase an entry specified by given iterator
443  // This invalidates the iterator until the next ++ operation.
444  //
445  // Includes a safeguard against the end-iterator such that the
446  // following is safe:
447  // \code
448  // auto iter = table.find(unknownKey);
449  // table.erase(iter);
450  // \endcode
451  // which is what \code table.erase(unknownKey) \endcode does anyhow.
452  //
453  // \return True if the corresponding entry existed and was removed
454  bool erase(const iterator& iter);
455 
456  //- Erase an entry specified by the given key
457  // \return True if the entry existed and was removed
458  bool erase(const Key& key);
459 
460  //- Remove table entries given by keys of the other hash-table.
461  //
462  // The other hash-table must have the same type of key, but the
463  // type of values held and the hashing function are arbitrary.
464  //
465  // \return The number of items removed
466  template<class AnyType, class AnyHash>
467  label erase(const HashTable<AnyType, Key, AnyHash>& other);
468 
469  //- Remove table entries given by the listed keys
470  // \return The number of items removed
471  inline label erase(std::initializer_list<Key> keys);
472 
473  //- Remove multiple entries using an iterator range of keys
474  template<class InputIter>
475  inline label erase(InputIter first, InputIter last);
476 
477  //- Remove table entries given by the listed keys
478  // \return The number of items removed
479  template<unsigned N>
480  inline label erase(const FixedList<Key, N>& keys);
481 
482  //- Remove table entries given by the listed keys
483  // \return The number of items removed
484  inline label erase(const UList<Key>& keys);
485 
486  //- Retain table entries given by keys of the other hash-table.
487  //
488  // The other hash-table must have the same type of key, but the
489  // type of values held and the hashing function are arbitrary.
490  //
491  // \return The number of items changed (removed)
492  template<class AnyType, class AnyHash>
493  label retain(const HashTable<AnyType, Key, AnyHash>& other);
494 
495  //- Generalized means to filter table entries based on their keys.
496  // Keep (or optionally prune) entries with keys that satisfy
497  // the unary predicate, which has the following signature:
498  // \code
499  // bool operator()(const Key& k);
500  // \endcode
501  //
502  // For example,
503  // \code
504  // wordRes goodFields = ...;
505  // allFieldNames.filterKeys
506  // (
507  // [&goodFields](const word& k){ return goodFields.match(k); }
508  // );
509  // \endcode
510  //
511  // \return The number of items changed (removed)
512  template<class UnaryPredicate>
513  label filterKeys
514  (
515  const UnaryPredicate& pred,
516  const bool pruning = false
517  );
518 
519  //- Generalized means to filter table entries based on their values.
520  // Keep (or optionally prune) entries with values that satisfy
521  // the unary predicate, which has the following signature:
522  // \code
523  // bool operator()(const T& v);
524  // \endcode
525  //
526  // \return The number of items changed (removed)
527  template<class UnaryPredicate>
528  label filterValues
529  (
530  const UnaryPredicate& pred,
531  const bool pruning = false
532  );
533 
534  //- Generalized means to filter table entries based on their key/value.
535  // Keep (or optionally prune) entries with keys/values that satisfy
536  // the binary predicate, which has the following signature:
537  // \code
538  // bool operator()(const Key& k, const T& v);
539  // \endcode
540  //
541  // \return The number of items changed (removed)
542  template<class BinaryPredicate>
543  label filterEntries
544  (
545  const BinaryPredicate& pred,
546  const bool pruning = false
547  );
548 
549 
550  //- Remove all entries from table
551  void clear();
552 
553  //- Remove all entries from table and the table itself.
554  // Equivalent to clear() followed by setCapacity(0)
555  void clearStorage();
556 
557  //- Change the hash table capacity (number of buckets).
558  // Setting a zero capacity will only remove the underlying
559  // storage if the table is empty.
560  void setCapacity(label newCapacity);
561 
562  //- Rehash the hash table with new number of buckets.
563  //- Currently identical to setCapacity()
564  void resize(label newCapacity);
565 
566  //- Reserve space for at least the specified number of elements
567  //- (not the number of buckets) and regenerates the hash table.
568  void reserve(label numEntries);
569 
570  //- Swap contents into this table
572 
573  //- Transfer contents into this table.
575 
576  //- Attempts to extract entries from source parameter and insert them
577  //- into \c this, does not overwrite existing entries.
578  //- The source will contains any items that could not be merged.
579  void merge(HashTable<T, Key, Hash>& source);
580 
581  //- Attempts to extract entries from source parameter and insert them
582  //- into \c this, does not overwrite existing entries.
583  //- The source will contains any items that could not be merged.
584  void merge(HashTable<T, Key, Hash>&& source);
585 
586 
587  // Member Operators
588 
589  //- Find and return a hashed entry. FatalError if it does not exist.
590  // Same as at().
591  inline T& operator[](const Key& key);
592 
593  //- Find and return a hashed entry. FatalError if it does not exist.
594  // Same as at().
595  inline const T& operator[](const Key& key) const;
596 
597  //- Return existing entry or create a new entry.
598  // A newly created entry is created as a nameless T() and is thus
599  // value-initialized. For primitives, this will be zero.
600  inline T& operator()(const Key& key);
601 
602  //- Return existing entry or insert a new entry.
603  inline T& operator()(const Key& key, const T& deflt);
604 
605  //- Copy assign
606  void operator=(const this_type& rhs);
607 
608  //- Copy assign from an initializer list
609  // Duplicate entries are handled by overwriting
610  void operator=(std::initializer_list<std::pair<Key, T>> rhs);
611 
612  //- Move assign
613  void operator=(this_type&& rhs);
614 
615  //- Equality. Tables are equal if all keys and values are equal,
616  //- independent of order or underlying storage size.
617  bool operator==(const this_type& rhs) const;
618 
619  //- The opposite of the equality operation.
620  bool operator!=(const this_type& rhs) const;
621 
622  //- Add entries into this HashTable
623  this_type& operator+=(const this_type& rhs);
624 
625 
626 protected:
627 
628  // Iterators and helpers
629 
630  //- Internally used base for iterator and const_iterator
631  template<bool Const> class Iterator;
632 
633  //- Allow iterator access to HashTable internals.
634  friend class Iterator<true>;
635 
636  //- Allow iterator access to HashTable internals.
637  friend class Iterator<false>;
638 
639  //- The iterator base for HashTable (internal use only).
640  // Note: data and functions are protected, to allow reuse by iterator
641  // and prevent most external usage.
642  // iterator and const_iterator have the same size, allowing
643  // us to reinterpret_cast between them (if desired)
644 
645  template<bool Const>
646  class Iterator
647  {
648  public:
649 
650  // Typedefs
651  using iterator_category = std::forward_iterator_tag;
653 
654  //- The HashTable container type
655  using table_type = typename std::conditional
656  <
657  Const,
658  const this_type,
659  this_type
660  >::type;
661 
662  //- The node-type being addressed
663  using node_type = typename std::conditional
664  <
665  Const,
666  const this_type::node_type,
668  >::type;
669 
670  //- The key type
672 
673  //- The object type being addressed
674  using mapped_type = typename std::conditional
675  <
676  Const,
679  >::type;
680 
681 
682  protected:
683 
684  // Protected Data
685 
686  //- The selected entry.
687  // MUST be the first member for easy comparison between iterators
688  // and to support reinterpret_cast from nullObject
689  node_type* entry_;
690 
691  //- The hash-table container being iterated on.
692  // Uses pointer for default copy/assignment
694 
695  //- Index within the hash-table data.
696  // A signed value, since iterator_erase() needs a negative value
697  // to mark the position.
698  label index_;
699 
700  // Friendship with HashTable, for begin/find constructors
701  friend class HashTable;
702 
703 
704  // Protected Constructors
705 
706  //- Default construct. Also the same as the end iterator
707  inline constexpr Iterator() noexcept;
708 
709  //- Construct from begin of hash-table
710  inline explicit Iterator(table_type* tbl);
711 
712  //- Construct by finding key in hash table
713  Iterator(table_type* tbl, const Key& key);
714 
715 
716  // Protected Member Functions
717 
718  //- Increment to the next position
719  inline void increment();
720 
721  //- Permit explicit cast to the other (const/non-const) iterator
722  template<bool Any>
723  explicit operator const Iterator<Any>&() const
724  {
725  return *reinterpret_cast<const Iterator<Any>*>(this);
726  }
727 
728 
729  public:
730 
731  // Member Functions
732 
733  //- True if iterator points to an entry
734  // This can be used directly instead of comparing to end()
735  bool good() const noexcept { return entry_; }
736 
737  //- True if iterator points to an entry - same as good()
738  bool found() const noexcept { return entry_; }
739 
740  //- The key associated with the iterator
741  const Key& key() const { return entry_->key(); }
742 
743  //- Write the (key, val) pair
744  inline Ostream& print(Ostream& os) const;
745 
746 
747  // Member Operators
748 
749  //- True if iterator points to an entry
750  // This can be used directly instead of comparing to end()
751  explicit operator bool() const noexcept { return entry_; }
752 
753  //- Compare hash-entry element pointers.
754  // Independent of const/non-const access
755  template<bool Any>
756  bool operator==(const Iterator<Any>& iter) const noexcept
757  {
758  return (entry_ == iter.entry_);
759  }
760 
761  template<bool Any>
762  bool operator!=(const Iterator<Any>& iter) const noexcept
763  {
764  return (entry_ != iter.entry_);
765  }
766  };
767 
768 public:
769 
770  //- Forward iterator with non-const access
771  class iterator
772  :
773  public Iterator<false>
774  {
775  public:
776 
777  // Typedefs
778  using iterator_category = std::forward_iterator_tag;
780 
785  using pointer = this_type::pointer;
789 
790 
791  // Constructors
792 
793  //- Default construct (end iterator)
794  iterator() = default;
795 
796  //- Copy construct from similar access type
797  explicit iterator(const Iterator<false>& iter)
798  :
799  Iterator<false>(iter)
800  {}
801 
802 
803  // Member Functions/Operators
804 
805  //- Const access to the entry (node)
806  const node_type* node() const noexcept
807  {
809  }
810 
811  //- Non-const access to the entry (node)
813  {
815  }
816 
817  //- Const access to referenced object (value)
818  const_reference val() const
819  {
820  return Iterator<false>::entry_->cval();
821  }
822 
823  //- Non-const access to referenced object (value)
824  reference val()
825  {
826  return Iterator<false>::entry_->val();
827  }
828 
829  //- Const access to referenced object (value)
830  const_reference operator*() const { return this->val(); }
831  const_reference operator()() const { return this->val(); }
832 
833  //- Non-const access to referenced object (value)
834  reference operator*() { return this->val(); }
835  reference operator()() { return this->val(); }
836 
837  inline iterator& operator++();
838  inline iterator operator++(int);
839  };
840 
841 
842  // STL const_iterator
843 
844  //- Forward iterator with const access
845  class const_iterator
846  :
847  public Iterator<true>
848  {
849  public:
850 
851  // Typedefs
852  using iterator_category = std::forward_iterator_tag;
854 
857  using mapped_type = const this_type::mapped_type;
858  using value_type = const this_type::value_type;
861 
862 
863  // Generated Methods
864 
865  //- Default construct (end iterator)
866  const_iterator() = default;
867 
868  //- Copy construct
869  const_iterator(const const_iterator&) = default;
870 
871  //- Copy assignment
872  const_iterator& operator=(const const_iterator&) = default;
873 
874 
875  // Constructors
877  //- Copy construct from any access type
878  template<bool Any>
879  const_iterator(const Iterator<Any>& iter)
880  :
881  Iterator<true>(static_cast<const Iterator<Any>&>(iter))
882  {}
883 
884  //- Implicit conversion from dissimilar access type
885  const_iterator(const iterator& iter)
886  :
887  const_iterator(reinterpret_cast<const const_iterator&>(iter))
888  {}
889 
890 
891  // Member Functions/Operators
892 
893  //- Const access to the entry (node)
894  const node_type* node() const noexcept
895  {
896  return Iterator<true>::entry_;
897  }
898 
899  //- Const access to referenced object (value)
900  reference val() const
901  {
902  return Iterator<true>::entry_->cval();
903  }
904 
905  //- Const access to referenced object (value)
906  reference operator*() const { return this->val(); }
907  reference operator()() const { return this->val(); }
908 
909  inline const_iterator& operator++();
910  inline const_iterator operator++(int);
911 
913  // Assignment
914 
915  // Allow assign from iterator to const_iterator
916  const_iterator& operator=(const iterator& iter)
917  {
918  return this->operator=
919  (
920  reinterpret_cast<const const_iterator&>(iter)
921  );
922  }
923  };
924 
926  // Iterator (keys)
927 
928  //- An iterator wrapper for returning a reference to the key
929  template<class Iter>
930  class key_iterator_base
931  :
932  public Iter
933  {
934  public:
935 
937  using pointer = const Key*;
938  using reference = const Key&;
939 
940  //- Default construct (end iterator)
941  constexpr key_iterator_base() noexcept
942  :
943  Iter()
944  {}
945 
946  //- Copy construct with implicit conversion
947  explicit key_iterator_base(const Iter& iter)
948  :
949  Iter(iter)
950  {}
951 
952  //- Return the key
953  reference operator*() const { return this->key(); }
954  reference operator()() const { return this->key(); }
955 
957  {
958  this->increment();
959  return *this;
960  }
961 
963  {
964  key_iterator_base iter(*this);
965  this->increment();
966  return iter;
967  }
968  };
969 
970 
971  //- Forward iterator returning the key
972  using key_iterator = key_iterator_base<iterator>;
973 
974  //- Forward const iterator returning the key
976 
977  //- A const iterator begin/end pair for iterating over keys
979  {
981  }
982 
983 
984  // Iterator access
985 
986  //- iterator set to the beginning of the HashTable
987  inline iterator begin();
988 
989  //- const_iterator set to the beginning of the HashTable
990  inline const_iterator begin() const;
991 
992  //- const_iterator set to the beginning of the HashTable
993  inline const_iterator cbegin() const;
994 
995  //- iterator to signal the end (for any HashTable)
996  inline iterator end() noexcept;
997 
998  //- const_iterator to signal the end (for any HashTable)
999  inline const_iterator end() const noexcept;
1001  //- const_iterator to signal the end (for any HashTable)
1002  inline constexpr const_iterator cend() const noexcept;
1003 
1004 
1005  // Reading/writing
1006 
1007  //- Print information
1008  Ostream& printInfo(Ostream& os) const;
1009 
1010  //- Write unordered keys (list), with line-breaks
1011  //- when length exceeds shortLen.
1012  // Using '0' suppresses line-breaks entirely.
1013  Ostream& writeKeys(Ostream& os, const label shortLen=0) const;
1014 
1016  // IOstream Operators
1017 
1018  friend Istream& operator>> <T, Key, Hash>
1019  (
1020  Istream&,
1021  HashTable<T, Key, Hash>& tbl
1022  );
1024  friend Ostream& operator<< <T, Key, Hash>
1025  (
1026  Ostream&,
1027  const HashTable<T, Key, Hash>& tbl
1028  );
1030 
1031  // Housekeeping
1032 
1033  //- Same as contains()
1034  bool found(const Key& key) const { return this->contains(key); }
1035 
1036  //- Deprecated(2023-07) use csorted() method
1037  // \deprecated(2023-07) - use csorted() method
1038  FOAM_DEPRECATED_FOR(2023-07, "csorted() method")
1039  UPtrList<const node_type> sorted() const { return this->csorted(); }
1040 };
1041 
1042 
1043 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1044 
1045 } // End namespace Foam
1046 
1047 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1049 #include "HashTableI.H"
1052 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1054 #ifndef NoHashTableC // Excluded from token.H
1055 #ifdef NoRepository
1056  #include "HashTable.C"
1057 #endif
1058 #endif
1059 
1060 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1061 
1062 #endif
1063 
1064 // ************************************************************************* //
reference operator*() const
Return the key.
Definition: HashTable.H:1264
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:925
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:1139
reference val() const
Const access to referenced object (value)
Definition: HashTable.H:1201
Factory class for creating a begin/end pair for any const iterator.
Definition: HashTableCore.H:87
const_reference operator()() const
Definition: HashTable.H:1114
type
Types of root.
Definition: Roots.H:52
label index_
Index within the hash-table data.
Definition: HashTable.H:940
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:1081
bool operator!=(const this_type &rhs) const
The opposite of the equality operation.
Definition: HashTable.C:1011
this_type & operator+=(const this_type &rhs)
Add entries into this HashTable.
Definition: HashTable.C:1021
Internally used base for iterator and const_iterator.
Definition: HashTable.H:849
Forward iterator with const access.
Definition: HashTable.H:1132
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:876
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:1370
this_type::value_type value_type
Definition: HashTable.H:1053
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:1055
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:188
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:659
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:1097
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)
const_reference operator*() const
Const access to referenced object (value)
Definition: HashTable.H:1113
UPtrList< node_type > sorted()
Non-const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:207
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:985
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:1040
const node_type * node() const noexcept
Const access to the entry (node)
Definition: HashTable.H:1193
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
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.
key_iterator_base< iterator > key_iterator
Forward iterator returning the key.
Definition: HashTable.H:1285
reference operator*() const
Const access to referenced object (value)
Definition: HashTable.H:1209
reference operator()() const
Definition: HashTable.H:1210
label capacity() const noexcept
The size of the underlying table (the number of buckets)
Definition: HashTable.H:363
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:749
this_type::node_type node_type
Definition: HashTable.H:1050
constexpr key_iterator_base() noexcept
Default construct (end iterator)
Definition: HashTable.H:1248
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:1056
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:995
this_type::pointer pointer
Definition: HashTable.H:1054
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:1051
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:1000
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:1267
void resize(label newCapacity)
Rehash the hash table with new number of buckets. Currently identical to setCapacity() ...
Definition: HashTable.C:729
typename std::conditional< Const, const this_type, this_type >::type table_type
The HashTable container type.
Definition: HashTable.H:887
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:353
An iterator wrapper for returning a reference to the key.
Definition: HashTable.H:1235
this_type::const_reference const_reference
Definition: HashTable.H:1057
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:1029
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:496
std::forward_iterator_tag iterator_category
Definition: HashTable.H:1047
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:30
table_type * container_
The hash-table container being iterated on.
Definition: HashTable.H:932
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:895
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:163
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition: HashTable.C:736
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition: HashTable.C:801
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:68
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:787
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:1048
friend class Iterator< false >
Allow iterator access to HashTable internals.
Definition: HashTable.H:859
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:148
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
this_type::mapped_type mapped_type
Definition: HashTable.H:1052
bool good() const noexcept
True if iterator points to an entry.
Definition: HashTable.H:990
Foam::argList args(argc, argv)
bool operator==(const Iterator< Any > &iter) const noexcept
Compare hash-entry element pointers.
Definition: HashTable.H:1023
const_iterator_pair< const_key_iterator, this_type > keys() const
A const iterator begin/end pair for iterating over keys.
Definition: HashTable.H:1295
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:774
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...