HashTable.C
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-2022 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 \*---------------------------------------------------------------------------*/
28 
29 #ifndef Foam_HashTable_C
30 #define Foam_HashTable_C
31 
32 #include "HashTable.H"
33 #include "List.H"
34 #include "FixedList.H"
35 #include "UPtrList.H"
36 
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
39 template<class T, class Key, class Hash>
41 :
42  HashTable<T, Key, Hash>(128)
43 {}
44 
45 
46 template<class T, class Key, class Hash>
48 :
49  HashTableCore(),
50  size_(0),
51  capacity_(HashTableCore::canonicalSize(size)),
52  table_(nullptr)
53 {
54  if (capacity_)
55  {
56  table_ = new node_type*[capacity_];
57  for (label i=0; i < capacity_; ++i)
58  {
59  table_[i] = nullptr;
60  }
61  }
62 }
63 
64 
65 template<class T, class Key, class Hash>
66 Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
67 :
68  HashTable<T, Key, Hash>(ht.capacity_)
69 {
70  for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter)
71  {
72  insert(iter.key(), iter.val());
73  }
74 }
75 
76 
77 template<class T, class Key, class Hash>
78 Foam::HashTable<T, Key, Hash>::HashTable(HashTable<T, Key, Hash>&& rhs)
79 :
80  HashTableCore(),
81  size_(rhs.size_),
82  capacity_(rhs.capacity_),
83  table_(rhs.table_)
84 {
85  rhs.size_ = 0;
86  rhs.capacity_ = 0;
87  rhs.table_ = nullptr;
88 }
89 
90 
91 template<class T, class Key, class Hash>
93 (
94  std::initializer_list<std::pair<Key, T>> list
95 )
96 :
97  HashTable<T, Key, Hash>(2*list.size())
98 {
99  for (const auto& keyval : list)
100  {
101  set(keyval.first, keyval.second);
102  }
103 }
104 
105 
106 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
107 
108 template<class T, class Key, class Hash>
110 {
111  if (table_)
112  {
113  clear();
114  delete[] table_;
115  }
116 }
117 
118 
119 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
120 
121 template<class T, class Key, class Hash>
123 {
124  List<Key> list(size_);
125  label count = 0;
126 
127  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
128  {
129  list[count++] = iter.key();
130  }
131 
132  return list;
133 }
134 
135 
136 template<class T, class Key, class Hash>
138 {
139  List<Key> list(this->toc());
140  Foam::sort(list);
141 
142  return list;
143 }
144 
145 
146 template<class T, class Key, class Hash>
147 template<class Compare>
149 (
150  const Compare& comp
151 ) const
152 {
153  List<Key> list(this->toc());
154  Foam::sort(list, comp);
156  return list;
157 }
158 
159 
160 template<class T, class Key, class Hash>
163 {
164  UPtrList<const node_type> result(size_);
165 
166  label count = 0;
167 
168  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
169  {
170  result.set(count++, iter.node());
171  }
172 
173  Foam::sort(result);
175  return result;
176 }
177 
178 
179 template<class T, class Key, class Hash>
182 {
183  return csorted();
184 }
185 
186 
187 template<class T, class Key, class Hash>
190 {
191  UPtrList<node_type> result(size_);
192 
193  label count = 0;
194 
195  for (iterator iter = begin(); iter != end(); ++iter)
196  {
197  result.set(count++, iter.node());
198  }
199 
200  Foam::sort(result);
201 
202  return result;
203 }
204 
205 
206 
207 template<class T, class Key, class Hash>
208 template<class UnaryPredicate>
210 (
211  const UnaryPredicate& pred,
212  const bool invert
213 ) const
214 {
215  List<Key> list(size_);
216  label count = 0;
217 
218  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
219  {
220  if ((pred(iter.key()) ? !invert : invert))
221  {
222  list[count++] = iter.key();
223  }
224  }
225 
226  list.resize(count);
227  Foam::sort(list);
228 
229  return list;
230 }
231 
232 
233 template<class T, class Key, class Hash>
234 template<class UnaryPredicate>
236 (
237  const UnaryPredicate& pred,
238  const bool invert
239 ) const
240 {
241  List<Key> list(size_);
242  label count = 0;
243 
244  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
245  {
246  if ((pred(iter.val()) ? !invert : invert))
247  {
248  list[count++] = iter.key();
249  }
250  }
251 
252  list.resize(count);
253  Foam::sort(list);
254 
255  return list;
256 }
257 
258 
259 template<class T, class Key, class Hash>
260 template<class BinaryPredicate>
262 (
263  const BinaryPredicate& pred,
264  const bool invert
265 ) const
266 {
267  List<Key> list(size_);
268  label count = 0;
269 
270  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
271  {
272  if ((pred(iter.key(), iter.val()) ? !invert : invert))
273  {
274  list[count++] = iter.key();
275  }
276  }
277 
278  list.resize(count);
279  Foam::sort(list);
280 
281  return list;
282 }
283 
284 
285 template<class T, class Key, class Hash>
286 template<class UnaryPredicate>
288 (
289  const UnaryPredicate& pred,
290  const bool invert
291 ) const
292 {
293  label count = 0;
294 
295  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
296  {
297  if ((pred(iter.key()) ? !invert : invert))
298  {
299  ++count;
300  }
301  }
302 
303  return count;
304 }
305 
306 
307 template<class T, class Key, class Hash>
308 template<class UnaryPredicate>
310 (
311  const UnaryPredicate& pred,
312  const bool invert
313 ) const
314 {
315  label count = 0;
316 
317  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
318  {
319  if ((pred(iter.val()) ? !invert : invert))
320  {
321  ++count;
322  }
323  }
324 
325  return count;
326 }
327 
328 
329 template<class T, class Key, class Hash>
330 template<class BinaryPredicate>
332 (
333  const BinaryPredicate& pred,
334  const bool invert
335 ) const
336 {
337  label count = 0;
338 
339  for (const_iterator iter = cbegin(); iter != cend(); ++iter)
340  {
341  if ((pred(iter.key(), iter.val()) ? !invert : invert))
342  {
343  ++count;
344  }
345  }
346 
347  return count;
348 }
349 
350 
351 template<class T, class Key, class Hash>
352 template<class... Args>
354 (
355  const bool overwrite,
356  const Key& key,
357  Args&&... args
358 )
359 {
360  if (!capacity_)
361  {
362  resize(2);
363  }
364 
365  const label index = hashKeyIndex(key);
366 
367  node_type* curr = nullptr;
368  node_type* prev = nullptr;
369 
370  for (node_type* ep = table_[index]; ep; ep = ep->next_)
371  {
372  if (key == ep->key())
373  {
374  curr = ep;
375  break;
376  }
377  prev = ep;
378  }
379 
380  if (!curr)
381  {
382  // Not found, insert it at the head
383  table_[index] =
384  new node_type(table_[index], key, std::forward<Args>(args)...);
385 
386  ++size_;
387  if (double(size_)/capacity_ > 0.8 && capacity_ < maxTableSize)
388  {
389  #ifdef FULLDEBUG
390  DebugInFunction << "Doubling table size\n";
391  #endif
392 
393  resize(2*capacity_);
394  }
395  }
396  else if (overwrite)
397  {
398  // Overwrite current entry (Perl convention).
399 
400  // Can skip if the value is not stored anyhow (Eg, HashSet)
401  // - this avoids a useless delete/new
402  if (!node_type::stores_value())
403  {
404  return true;
405  }
406 
407  node_type* ep = curr->next_; // next in the linked list
408 
409  // In some cases the delete/new could be avoided in favour of move
410  // assignment, but cannot be certain that all objects support this
411  // or that it behaves the same as a copy construct.
412 
413  delete curr;
414  ep = new node_type(ep, key, std::forward<Args>(args)...);
415 
416  // Replace current element - within list or insert at the head
417  if (prev)
418  {
419  prev->next_ = ep;
420  }
421  else
422  {
423  table_[index] = ep;
424  }
425  }
426  else
427  {
428  // Do not overwrite existing entry (STL 'insert' convention)
429  #ifdef FULLDEBUG
430  DebugInFunction << "Not inserting " << key << ": already in table\n";
431  #endif
432  return false;
433  }
434 
435  return true;
436 }
437 
438 
439 template<class T, class Key, class Hash>
440 bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
441 {
442  // NOTE: we use (const iterator&) here, but treat its contents as mutable.
443  //
444  // The parameter should be (iterator&), but then the compiler doesn't find
445  // it correctly and tries to call as (iterator) instead.
446 
447  iterator& it = const_cast<iterator&>(iter);
448 
449  return iterator_erase(it.entry_, it.index_);
450 }
451 
452 
453 template<class T, class Key, class Hash>
455 {
456  iterator iter(find(key));
457  return erase(iter);
458 }
459 
460 
461 template<class T, class Key, class Hash>
462 template<class InputIter>
463 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
464 (
465  InputIter first,
466  InputIter last
467 )
468 {
469  label changed = 0;
470 
471  for
472  (
473  const label nTotal = this->size();
474  changed < nTotal && first != last; // terminate early
475  ++first
476  )
477  {
478  if (this->erase(*first))
479  {
480  ++changed;
481  }
482  }
484  return changed;
485 }
486 
487 
488 template<class T, class Key, class Hash>
489 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
490 (
491  std::initializer_list<Key> keys
492 )
493 {
494  return erase(keys.begin(), keys.end());
495 }
496 
497 
498 template<class T, class Key, class Hash>
499 template<unsigned N>
500 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
501 (
502  const FixedList<Key, N>& keys
503 )
504 {
505  return erase(keys.cbegin(), keys.cend());
506 }
507 
508 
509 template<class T, class Key, class Hash>
510 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
511 (
512  const UList<Key>& keys
513 )
514 {
515  return erase(keys.cbegin(), keys.cend());
516 }
517 
518 
519 template<class T, class Key, class Hash>
520 template<class AnyType, class AnyHash>
522 (
524 )
525 {
526  const label nTotal = this->size();
527  label changed = 0;
528 
529  if (other.size() <= nTotal)
530  {
531  // The other is smaller/same-size, use its keys for removal
532 
533  for
534  (
535  auto iter = other.cbegin();
536  changed < nTotal && iter != other.cend(); // Terminate early
537  ++iter
538  )
539  {
540  if (erase(iter.key()))
541  {
542  ++changed;
543  }
544  }
545  }
546  else
547  {
548  // We are smaller: remove if found in the other hash
549  for
550  (
551  iterator iter = begin();
552  changed < nTotal && iter != end(); // Terminate early
553  ++iter
554  )
555  {
556  if (other.found(iter.key()) && erase(iter))
557  {
558  ++changed;
559  }
560  }
561  }
562 
563  return changed;
564 }
565 
566 
567 template<class T, class Key, class Hash>
568 template<class AnyType, class AnyHash>
570 (
572 )
573 {
574  const label nTotal = this->size();
575  label changed = 0;
576 
577  if (other.empty())
578  {
579  // Trivial case
580  changed = nTotal;
581  this->clear();
582  }
583  else
584  {
585  // Inverted logic: remove if *not* found in the other hash
586 
587  for (iterator iter = begin(); iter != end(); ++iter)
588  {
589  if (!other.found(iter.key()) && erase(iter))
590  {
591  ++changed;
592  }
593  }
594  }
595 
596  return changed;
597 }
598 
599 
600 template<class T, class Key, class Hash>
601 void Foam::HashTable<T, Key, Hash>::resize(const label sz)
602 {
603  const label newCapacity = HashTableCore::canonicalSize(sz);
604  const label oldCapacity = capacity_;
605 
606  if (newCapacity == oldCapacity)
607  {
608  #ifdef FULLDEBUG
609  DebugInFunction << "New table size == old table size\n";
610  #endif
611 
612  return;
613  }
614  else if (!newCapacity)
615  {
616  // Special treatment for resize(0)
617  if (size_)
618  {
620  << "HashTable contains " << size_ << " cannot resize(0)" << nl;
621  }
622  else
623  {
624  if (table_)
625  {
626  delete[] table_;
627  capacity_ = 0;
628  }
629 
630  table_ = nullptr;
631  }
632 
633  return;
634  }
635 
636  // Swap primary table entries: size_ is left untouched
637 
638  auto oldTable = table_;
639  capacity_ = newCapacity;
640 
641  table_ = new node_type*[capacity_];
642  for (label i=0; i < capacity_; ++i)
643  {
644  table_[i] = nullptr;
645  }
646 
647  // Move to new table[] but with new chaining.
648 
649  label nMove = size_; // Allow early completion
650  for (label i=0; nMove && i < oldCapacity; ++i)
651  {
652  for (node_type* ep = oldTable[i]; ep; /*nil*/)
653  {
654  node_type* next = ep->next_;
655 
656  // Move to new location
657  {
658  const label newIdx = hashKeyIndex(ep->key());
659 
660  ep->next_ = table_[newIdx]; // add to head
661  table_[newIdx] = ep;
662  }
663 
664  ep = next; // continue in the linked-list
665  --nMove; // note any early completion
666  }
667  oldTable[i] = nullptr;
668  }
669 
670  if (oldTable)
671  {
672  delete[] oldTable;
673  }
674 }
675 
676 
677 template<class T, class Key, class Hash>
679 {
680  for (label i=0; size_ && i<capacity_; ++i)
681  {
682  for (node_type* ep = table_[i]; ep; /*nil*/)
683  {
684  node_type* next = ep->next_;
685 
686  delete ep;
687 
688  ep = next; // continue in the linked-list
689  --size_; // note any early completion
690  }
691  table_[i] = nullptr;
692  }
693 }
694 
695 
696 template<class T, class Key, class Hash>
698 {
699  clear();
700  resize(0);
701 }
702 
703 
704 template<class T, class Key, class Hash>
706 {
707  if (this == &rhs)
708  {
709  return; // Self-swap is a no-op
710  }
711 
712  std::swap(size_, rhs.size_);
713  std::swap(capacity_, rhs.capacity_);
714  std::swap(table_, rhs.table_);
715 }
716 
717 
718 template<class T, class Key, class Hash>
720 {
721  if (this == &rhs)
722  {
723  return; // Self-assignment is a no-op
724  }
725 
726  clear();
727  swap(rhs);
728 }
729 
730 
731 template<class T, class Key, class Hash>
732 template<class UnaryPredicate>
734 (
735  const UnaryPredicate& pred,
736  const bool pruning
737 )
738 {
739  label changed = 0;
740 
741  for (iterator iter = begin(); iter != end(); ++iter)
742  {
743  // Matches? either prune (pruning) or keep (!pruning)
744  if
745  (
746  (pred(iter.key()) ? pruning : !pruning)
747  && erase(iter)
748  )
749  {
750  ++changed;
751  }
752  }
753 
754  return changed;
755 }
756 
757 
758 template<class T, class Key, class Hash>
759 template<class UnaryPredicate>
761 (
762  const UnaryPredicate& pred,
763  const bool pruning
764 )
765 {
766  label changed = 0;
767 
768  for (iterator iter = begin(); iter != end(); ++iter)
769  {
770  // Matches? either prune (pruning) or keep (!pruning)
771  if
772  (
773  (pred(iter.val()) ? pruning : !pruning)
774  && erase(iter)
775  )
776  {
777  ++changed;
778  }
779  }
780 
781  return changed;
782 }
783 
784 
785 template<class T, class Key, class Hash>
786 template<class BinaryPredicate>
788 (
789  const BinaryPredicate& pred,
790  const bool pruning
791 )
792 {
793  label changed = 0;
794 
795  for (iterator iter = begin(); iter != end(); ++iter)
796  {
797  // Matches? either prune (pruning) or keep (!pruning)
798  if
799  (
800  (pred(iter.key(), iter.val()) ? pruning : !pruning)
801  && erase(iter)
802  )
803  {
804  ++changed;
805  }
806  }
807 
808  return changed;
809 }
810 
811 
812 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
813 
814 template<class T, class Key, class Hash>
816 (
817  const HashTable<T, Key, Hash>& rhs
818 )
819 {
820  if (this == &rhs)
821  {
822  return; // Self-assignment is a no-op
823  }
824 
825  if (!capacity_)
826  {
827  // Zero-sized from a previous transfer()?
828  resize(rhs.capacity_);
829  }
830  else
831  {
832  clear();
833  }
834 
835  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
836  {
837  insert(iter.key(), iter.val());
838  }
839 }
840 
841 
842 template<class T, class Key, class Hash>
844 (
845  std::initializer_list<std::pair<Key, T>> rhs
846 )
847 {
848  if (!capacity_)
849  {
850  // Zero-sized from a previous transfer()?
851  resize(2*rhs.size());
852  }
853  else
854  {
855  clear();
856  }
857 
858  for (const auto& keyval : rhs)
859  {
860  set(keyval.first, keyval.second);
861  }
862 }
863 
864 
865 template<class T, class Key, class Hash>
867 (
868  HashTable<T, Key, Hash>&& rhs
869 )
870 {
871  if (this == &rhs)
872  {
873  return; // Self-assignment is a no-op
874  }
876  transfer(rhs);
877 }
878 
879 
880 template<class T, class Key, class Hash>
882 (
883  const HashTable<T, Key, Hash>& rhs
884 ) const
885 {
886  // Sizes (number of keys) must match
887  if (size() != rhs.size())
888  {
889  return false;
890  }
891 
892  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
893  {
894  const const_iterator other(this->cfind(iter.key()));
895 
896  if (!other.good() || other.val() != iter.val())
897  {
898  return false;
899  }
900  }
902  return true;
903 }
904 
905 
906 template<class T, class Key, class Hash>
908 (
909  const HashTable<T, Key, Hash>& rhs
910 ) const
911 {
912  return !operator==(rhs);
913 }
914 
915 
916 template<class T, class Key, class Hash>
918 (
919  const HashTable<T, Key, Hash>& rhs
920 )
921 {
922  // Avoid no-ops:
923  if (rhs.size() || this != &rhs)
924  {
925  if (this->size())
926  {
927  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
928  {
929  insert(iter.key(), iter.val());
930  }
931  }
932  else
933  {
934  (*this) = rhs;
935  }
936  }
937 
938  return *this;
939 }
940 
941 
942 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
943 
944 // Iterators, Friend Operators
945 
946 #include "HashTableIter.C"
947 #include "HashTableIO.C"
948 
949 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
950 
951 #endif
952 
953 // ************************************************************************* //
label countValues(const UnaryPredicate &pred, const bool invert=false) const
Count the number of values that satisfy the unary predicate.
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as ListOps::find_if.
Definition: ListOps.H:790
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...
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant UList.
Definition: UListI.H:357
patchWriters resize(patchIds.size())
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:101
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:132
srcOptions erase("case")
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
True if hashed key is found in table.
Definition: HashTableI.H:93
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
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
UPtrList< const node_type > csorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:155
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:45
void resize(const label sz)
Resize the hash table for efficiency.
Definition: HashTable.C:594
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: UPtrListI.H:134
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...
~HashTable()
Destructor.
Definition: HashTable.C:102
label countEntries(const BinaryPredicate &pred, const bool invert=false) const
Count the number of entries that satisfy the binary predicate.
void swap(HashTable< T, Key, Hash > &rhs)
Swap contents into this table.
Definition: HashTable.C:698
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
label filterEntries(const BinaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their key/value.
#define DebugInFunction
Report an information message using Foam::Info.
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:334
void clear()
Clear all entries from table.
Definition: HashTable.C:671
patchWriters clear()
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
Definition: stdFoam.H:215
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:102
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:100
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:99
bool empty() const noexcept
True if the hash table is empty.
Definition: HashTableI.H:52
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:193
HashTable()
Default construct with default (128) table capacity.
Definition: HashTable.C:33
constexpr auto cbegin(const C &c) -> decltype(c.begin())
Return const_iterator to the beginning of the container c.
Definition: stdFoam.H:182
const volScalarField & T
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant FixedList.
Definition: FixedListI.H:550
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:433
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:29
Bits that are independent of HashTable template parameters.
Definition: HashTableCore.H:54
#define WarningInFunction
Report a warning using Foam::Warning.
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
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:130
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
Definition: HashTable.C:712
UPtrList< const node_type > sorted() const
Const access to the hash-table contents in sorted order (sorted by keys).
Definition: HashTable.C:174
label filterKeys(const UnaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their keys.
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant UList.
Definition: UListI.H:336
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant FixedList.
Definition: FixedListI.H:574
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:115
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
Foam::argList args(argc, argv)
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:160
List< label > toc(const UList< bool > &bools)
Return the (sorted) values corresponding to &#39;true&#39; entries.
Definition: BitOps.C:158
constexpr const_iterator cend() const noexcept
const_iterator to signal the end (for any HashTable)
void clearStorage()
Clear the table entries and the table itself.
Definition: HashTable.C:690
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...