HashTableIter.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) 2017-2023 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
29 
30 template<class T, class Key, class Hash>
31 template<bool Const>
33 (
34  table_type* tbl,
35  const Key& key
36 )
37 :
38  entry_(nullptr),
39  container_(tbl),
40  index_(0)
41 {
42  if (container_ && container_->size())
43  {
44  const label index = container_->hashKeyIndex(key);
45 
46  for (node_type* ep = container_->table_[index]; ep; ep = ep->next_)
47  {
48  if (key == ep->key())
49  {
50  entry_ = ep;
51  index_ = index;
52  break;
53  }
54  }
55  }
56 }
57 
58 
59 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
60 
61 //
62 // Any changes here may need changes in the iterator increment() method
63 //
64 template<class T, class Key, class Hash>
66 {
67  node_type* entry = iter.entry_;
68  const label index = iter.index_;
69 
70  // Safeguard against the following:
71  // - empty table
72  // - nullptr entry
73  // - end iterator (which is also a nullptr)
74  // - negative index from a previous erase. See comment below.
75  if (!size_ || !entry || index < 0)
76  {
77  return false;
78  }
79 
80  // Decrease count
81  --size_;
82 
83  // The previous element in the singly linked list
84  node_type* prev = nullptr;
85 
86  for (node_type* ep = table_[index]; ep; ep = ep->next_)
87  {
88  if (ep == entry)
89  {
90  break;
91  }
92  prev = ep;
93  }
94 
95  if (prev)
96  {
97  // Had previous element in linked list - reposition to there
98  prev->next_ = entry->next_;
99  delete entry;
100 
101  iter.entry_ = prev;
102  return true;
103  }
104 
105  // Was first element on linked list
106  table_[index] = entry->next_;
107  delete entry;
108 
109  // Assign any non-nullptr value so it doesn't look like end()
110  iter.entry_ = reinterpret_cast<node_type*>(this);
111 
112  // Mark the present index to continue and bring it back to the present
113  // location with the next index.
114  //
115  // Save: (-index-1), which has no ambiguity for index 0.
116  // Retrieve: (-(index+1))
117 
118  iter.index_ = (-index - 1);
119 
120  return true;
121 }
122 
123 
124 //
125 // Any changes here may need changes in the iterator increment() method
126 //
127 template<class T, class Key, class Hash>
130 {
131  node_type* entry = iter.entry_;
132  const label index = iter.index_;
133 
134  // Safeguard against the following:
135  // - empty table
136  // - nullptr entry
137  // - end iterator (which is also a nullptr)
138  // - negative index from a previous erase. See comment below.
139  if (!size_ || !entry || index < 0)
140  {
141  return nullptr;
142  }
143 
144  // Decrease count
145  --size_;
146 
147  // The previous element in the singly linked list
148  node_type* prev = nullptr;
149 
150  for (node_type* ep = table_[index]; ep; ep = ep->next_)
151  {
152  if (ep == entry)
153  {
154  break;
155  }
156  prev = ep;
157  }
158 
159  if (prev)
160  {
161  // Had previous element in linked list - reposition iterator to there
162  prev->next_ = entry->next_;
163  iter.entry_ = prev;
164 
165  entry->next_ = nullptr;
166  return entry;
167  }
168 
169  // Was first element on linked list
170  table_[index] = entry->next_;
171  iter.entry_ = table_[index];
172  entry->next_ = nullptr;
173 
174  // Mark the present index to continue and bring it back to the present
175  // location with the next index.
176  //
177  // Save: (-index-1), which has no ambiguity for index 0.
178  // Retrieve: (-(index+1))
179 
180  iter.index_ = (-index - 1);
181 
182  return entry;
183 }
184 
185 
186 // ************************************************************************* //
node_type * entry_
The selected entry.
Definition: HashTable.H:909
label index_
Index within the hash-table data.
Definition: HashTable.H:924
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
typename std::conditional< Const, const this_type::node_type, this_type::node_type >::type node_type
The node-type being addressed.
Definition: HashTable.H:881
Forward iterator with non-const access.
Definition: HashTable.H:1024
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
typename std::conditional< Const, const this_type, this_type >::type table_type
The HashTable container type.
Definition: HashTable.H:871
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
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63