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-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 \*---------------------------------------------------------------------------*/
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  // Same as default sizing
363  resize(128);
364  }
365 
366  const label index = hashKeyIndex(key);
367 
368  node_type* curr = nullptr;
369  node_type* prev = nullptr;
370 
371  for (node_type* ep = table_[index]; ep; ep = ep->next_)
372  {
373  if (key == ep->key())
374  {
375  curr = ep;
376  break;
377  }
378  prev = ep;
379  }
380 
381  if (!curr)
382  {
383  // Not found, insert it at the head
384  table_[index] =
385  new node_type(table_[index], key, std::forward<Args>(args)...);
386 
387  ++size_;
388  if (0.8*capacity_ < size_) // Resize after 80% fill factor
389  {
390  if (capacity_ < maxTableSize) resize(2*capacity_);
391  }
392  }
393  else if (overwrite)
394  {
395  // Overwrite current entry (Perl convention).
396 
397  // Can skip if the value is not stored anyhow (Eg, HashSet)
398  // - this avoids a useless delete/new
399  if (!node_type::stores_value())
400  {
401  return true;
402  }
403 
404  node_type* ep = curr->next_; // next in the linked list
405 
406  // In some cases the delete/new could be avoided in favour of move
407  // assignment, but cannot be certain that all objects support this
408  // or that it behaves the same as a copy construct.
409 
410  delete curr;
411  ep = new node_type(ep, key, std::forward<Args>(args)...);
412 
413  // Replace current element - within list or insert at the head
414  if (prev)
415  {
416  prev->next_ = ep;
417  }
418  else
419  {
420  table_[index] = ep;
421  }
422  }
423  else
424  {
425  // Not overwriting existing entry
426  return false;
427  }
428 
429  return true;
430 }
431 
432 
433 template<class T, class Key, class Hash>
434 void Foam::HashTable<T, Key, Hash>::insert_node(node_type* entry)
435 {
436  if (!entry) return;
437 
438  if (!capacity_)
439  {
440  // Same as default sizing
441  resize(128);
442  }
443 
444  const label index = hashKeyIndex(entry->key());
445 
446  node_type* curr = nullptr;
447  //node_type* prev = nullptr;
448 
449  for (node_type* ep = table_[index]; ep; ep = ep->next_)
450  {
451  if (entry->key() == ep->key())
452  {
453  curr = ep;
454  break;
455  }
456  //prev = ep;
457  }
458 
459  if (!curr)
460  {
461  // Not found, insert it at the head
462  table_[index] = entry;
463 
464  ++size_;
465  if (0.8*capacity_ < size_) // Resize after 80% fill factor
466  {
467  if (capacity_ < maxTableSize) resize(2*capacity_);
468  }
469  }
470  else
471  {
473  << "Not inserting " << entry->key() << ": already in table\n"
474  << exit(FatalError);
475  }
476 }
477 
478 
479 template<class T, class Key, class Hash>
480 bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
481 {
482  // NOTE: we use (const iterator&) here, but treat its contents as mutable.
483  //
484  // The parameter should be (iterator&), but then the compiler doesn't find
485  // it correctly and tries to call as (iterator) instead.
486 
487  return iterator_erase(const_cast<iterator&>(iter));
488 }
489 
490 
491 template<class T, class Key, class Hash>
493 {
494  iterator iter(find(key));
495  return iterator_erase(iter);
496 }
497 
498 
499 template<class T, class Key, class Hash>
500 template<class InputIter>
501 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
502 (
503  InputIter first,
504  InputIter last
505 )
506 {
507  label changed = 0;
508 
509  for
510  (
511  const label nTotal = this->size();
512  changed < nTotal && first != last; // terminate early
513  ++first
514  )
515  {
516  if (this->erase(*first))
517  {
518  ++changed;
519  }
520  }
522  return changed;
523 }
524 
525 
526 template<class T, class Key, class Hash>
527 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
528 (
529  std::initializer_list<Key> keys
530 )
531 {
532  return erase(keys.begin(), keys.end());
533 }
534 
535 
536 template<class T, class Key, class Hash>
537 template<unsigned N>
538 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
539 (
540  const FixedList<Key, N>& keys
541 )
542 {
543  return erase(keys.cbegin(), keys.cend());
544 }
545 
546 
547 template<class T, class Key, class Hash>
548 inline Foam::label Foam::HashTable<T, Key, Hash>::erase
549 (
550  const UList<Key>& keys
551 )
552 {
553  return erase(keys.cbegin(), keys.cend());
554 }
555 
556 
557 template<class T, class Key, class Hash>
558 template<class AnyType, class AnyHash>
560 (
562 )
563 {
564  const label nTotal = this->size();
565  label changed = 0;
566 
567  if (other.size() <= nTotal)
568  {
569  // The other is smaller/same-size, use its keys for removal
570 
571  for
572  (
573  auto iter = other.cbegin();
574  changed < nTotal && iter != other.cend(); // Terminate early
575  ++iter
576  )
577  {
578  if (erase(iter.key()))
579  {
580  ++changed;
581  }
582  }
583  }
584  else
585  {
586  // We are smaller: remove if found in the other hash
587  for
588  (
589  iterator iter = begin();
590  changed < nTotal && iter != end(); // Terminate early
591  ++iter
592  )
593  {
594  if (other.contains(iter.key()) && erase(iter))
595  {
596  ++changed;
597  }
598  }
599  }
600 
601  return changed;
602 }
603 
604 
605 template<class T, class Key, class Hash>
606 template<class AnyType, class AnyHash>
608 (
610 )
611 {
612  const label nTotal = this->size();
613  label changed = 0;
614 
615  if (other.empty())
616  {
617  // Trivial case
618  changed = nTotal;
619  this->clear();
620  }
621  else
622  {
623  // Inverted logic: remove if *not* found in the other hash
624 
625  for (iterator iter = begin(); iter != end(); ++iter)
626  {
627  if (!other.contains(iter.key()) && erase(iter))
628  {
629  ++changed;
630  }
631  }
632  }
633 
634  return changed;
635 }
636 
637 
638 template<class T, class Key, class Hash>
639 void Foam::HashTable<T, Key, Hash>::resize(const label sz)
640 {
641  const label newCapacity = HashTableCore::canonicalSize(sz);
642  const label oldCapacity = capacity_;
643 
644  if (newCapacity == oldCapacity)
645  {
646  return;
647  }
648  else if (!newCapacity)
649  {
650  // Special treatment for resize(0)
651  if (size_)
652  {
654  << "HashTable contains " << size_
655  << " elements, cannot resize(0)" << nl;
656  }
657  else
658  {
659  if (table_)
660  {
661  delete[] table_;
662  capacity_ = 0;
663  }
664 
665  table_ = nullptr;
666  }
667 
668  return;
669  }
670 
671  // Swap primary table entries: size_ is left untouched
672 
673  auto oldTable = table_;
674  capacity_ = newCapacity;
675 
676  table_ = new node_type*[capacity_];
677  for (label i=0; i < capacity_; ++i)
678  {
679  table_[i] = nullptr;
680  }
681 
682  // Move to new table[] but with new chaining.
683 
684  for (label i = 0, nPending = size_; nPending && i < oldCapacity; ++i)
685  {
686  for (node_type* ep = oldTable[i]; ep; /*nil*/)
687  {
688  node_type* next = ep->next_;
689 
690  // Move to new location
691  {
692  const label newIdx = hashKeyIndex(ep->key());
693 
694  ep->next_ = table_[newIdx]; // add to head
695  table_[newIdx] = ep;
696  }
697 
698  ep = next; // continue in the linked-list
699  --nPending; // note any early completion
700  }
701  oldTable[i] = nullptr;
702  }
703 
704  if (oldTable)
705  {
706  delete[] oldTable;
707  }
708 }
709 
710 
711 template<class T, class Key, class Hash>
713 {
714  for (label i=0; size_ && i<capacity_; ++i)
715  {
716  for (node_type* ep = table_[i]; ep; /*nil*/)
717  {
718  node_type* next = ep->next_;
719 
720  delete ep;
721 
722  ep = next; // continue in the linked-list
723  --size_; // note any early completion
724  }
725  table_[i] = nullptr;
726  }
727 }
728 
729 
730 template<class T, class Key, class Hash>
732 {
733  clear();
734  resize(0);
735 }
736 
737 
738 template<class T, class Key, class Hash>
740 {
741  if (this == &rhs)
742  {
743  return; // Self-swap is a no-op
744  }
745 
746  std::swap(size_, rhs.size_);
747  std::swap(capacity_, rhs.capacity_);
748  std::swap(table_, rhs.table_);
749 }
750 
751 
752 template<class T, class Key, class Hash>
754 {
755  if (this == &rhs)
756  {
757  return; // Self-assignment is a no-op
758  }
759 
760  clear();
761  swap(rhs);
762 }
763 
764 
765 template<class T, class Key, class Hash>
766 template<class UnaryPredicate>
768 (
769  const UnaryPredicate& pred,
770  const bool pruning
771 )
772 {
773  label changed = 0;
774 
775  for (iterator iter = begin(); iter != end(); ++iter)
776  {
777  // Matches? either prune (pruning) or keep (!pruning)
778  if
779  (
780  (pred(iter.key()) ? pruning : !pruning)
781  && erase(iter)
782  )
783  {
784  ++changed;
785  }
786  }
787 
788  return changed;
789 }
790 
791 
792 template<class T, class Key, class Hash>
793 template<class UnaryPredicate>
795 (
796  const UnaryPredicate& pred,
797  const bool pruning
798 )
799 {
800  label changed = 0;
801 
802  for (iterator iter = begin(); iter != end(); ++iter)
803  {
804  // Matches? either prune (pruning) or keep (!pruning)
805  if
806  (
807  (pred(iter.val()) ? pruning : !pruning)
808  && erase(iter)
809  )
810  {
811  ++changed;
812  }
813  }
814 
815  return changed;
816 }
817 
818 
819 template<class T, class Key, class Hash>
820 template<class BinaryPredicate>
822 (
823  const BinaryPredicate& pred,
824  const bool pruning
825 )
826 {
827  label changed = 0;
828 
829  for (iterator iter = begin(); iter != end(); ++iter)
830  {
831  // Matches? either prune (pruning) or keep (!pruning)
832  if
833  (
834  (pred(iter.key(), iter.val()) ? pruning : !pruning)
835  && erase(iter)
836  )
837  {
838  ++changed;
839  }
840  }
841 
842  return changed;
843 }
844 
845 
846 template<class T, class Key, class Hash>
847 void Foam::HashTable<T, Key, Hash>::merge(HashTable<T, Key, Hash>& source)
848 {
849  // Self-merge implicitly a no-op
850 
851  if (node_type::stores_value())
852  {
853  // key/val pair
854  for (iterator iter = source.begin(); iter != source.end(); ++iter)
855  {
856  if (!contains(iter.key()))
857  {
858  node_type* entry = source.iterator_extract(iter);
859  this->insert_node(entry);
860  }
861  }
862  }
863  else
864  {
865  // key only, does not store a value.
866  // Since the key is const, juggling the node does not work
867 
868  for (iterator iter = source.begin(); iter != source.end(); ++iter)
869  {
870  if (emplace(iter.key()))
871  {
872  source.erase(iter);
873  }
874  }
875  }
876 }
877 
878 
879 template<class T, class Key, class Hash>
880 void Foam::HashTable<T, Key, Hash>::merge(HashTable<T, Key, Hash>&& source)
881 {
882  merge(source);
883 }
884 
885 
886 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
887 
888 template<class T, class Key, class Hash>
890 (
891  const HashTable<T, Key, Hash>& rhs
892 )
893 {
894  if (this == &rhs)
895  {
896  return; // Self-assignment is a no-op
897  }
898 
899  if (!capacity_)
900  {
901  // Zero-sized from a previous transfer()?
902  resize(rhs.capacity_);
903  }
904  else
905  {
906  clear();
907  }
908 
909  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
910  {
911  insert(iter.key(), iter.val());
912  }
913 }
914 
915 
916 template<class T, class Key, class Hash>
918 (
919  std::initializer_list<std::pair<Key, T>> rhs
920 )
921 {
922  if (!capacity_)
923  {
924  // Zero-sized from a previous transfer()?
925  resize(2*rhs.size());
926  }
927  else
928  {
929  clear();
930  }
931 
932  for (const auto& keyval : rhs)
933  {
934  set(keyval.first, keyval.second);
935  }
936 }
937 
938 
939 template<class T, class Key, class Hash>
941 (
942  HashTable<T, Key, Hash>&& rhs
943 )
944 {
945  if (this == &rhs)
946  {
947  return; // Self-assignment is a no-op
948  }
950  transfer(rhs);
951 }
952 
953 
954 template<class T, class Key, class Hash>
956 (
957  const HashTable<T, Key, Hash>& rhs
958 ) const
959 {
960  // Sizes (number of keys) must match
961  if (size() != rhs.size())
962  {
963  return false;
964  }
965 
966  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
967  {
968  const const_iterator other(this->cfind(iter.key()));
969 
970  if (!other.good() || other.val() != iter.val())
971  {
972  return false;
973  }
974  }
976  return true;
977 }
978 
979 
980 template<class T, class Key, class Hash>
982 (
983  const HashTable<T, Key, Hash>& rhs
984 ) const
985 {
986  return !operator==(rhs);
987 }
988 
989 
990 template<class T, class Key, class Hash>
992 (
993  const HashTable<T, Key, Hash>& rhs
994 )
995 {
996  // Avoid no-ops:
997  if (rhs.size() || this != &rhs)
998  {
999  if (this->size())
1000  {
1001  for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
1002  {
1003  insert(iter.key(), iter.val());
1004  }
1005  }
1006  else
1007  {
1008  (*this) = rhs;
1009  }
1010  }
1011 
1012  return *this;
1013 }
1014 
1015 
1016 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1017 
1018 // Iterators, Friend Operators
1019 
1020 #include "HashTableIter.C"
1021 #include "HashTableIO.C"
1022 
1023 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1024 
1025 #endif
1026 
1027 // ************************************************************************* //
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:379
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
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")
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
label retain(const HashTable< AnyType, Key, AnyHash > &other)
Retain table entries given by keys of the other hash-table.
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
void resize(const label sz)
Resize the hash table for efficiency.
Definition: HashTable.C:632
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 size() const noexcept
The number of elements in table.
Definition: HashTable.H:331
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:732
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
bool contains(const Key &key) const
True if hashed key is contained (found) in table.
Definition: HashTableI.H:72
label filterEntries(const BinaryPredicate &pred, const bool pruning=false)
Generalized means to filter table entries based on their key/value.
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:348
void clear()
Clear all entries from table.
Definition: HashTable.C:705
patchWriters clear()
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
Definition: stdFoam.H:216
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: HashTable.H:326
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:194
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:183
const volScalarField & T
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant FixedList.
Definition: FixedListI.H:546
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:473
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
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:840
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:746
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:335
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant FixedList.
Definition: FixedListI.H:570
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:161
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)
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
void clearStorage()
Clear the table entries and the table itself.
Definition: HashTable.C:724
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: UPtrList.H:361
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...