Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
10License
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/>.
26\*---------------------------------------------------------------------------*/
27
28// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
29
30template<class T, class Key, class Hash>
31template<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//
64template<class T, class Key, class Hash>
65bool Foam::HashTable<T, Key, Hash>::iterator_erase(iterator& iter)
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//
127template<class T, class Key, class Hash>
129Foam::HashTable<T, Key, Hash>::iterator_extract(iterator& iter)
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:925
constexpr Iterator() noexcept
Default construct. Also the same as the end iterator.
std::conditional_t< Const, const this_type, this_type > table_type
The HashTable container type.
Definition HashTable.H:882
label index_
Index within the hash-table data.
Definition HashTable.H:940
const Key & key() const
The key associated with the iterator.
Definition HashTable.H:1000
table_type * container_
The hash-table container being iterated on.
Definition HashTable.H:932
Forward iterator with non-const access.
Definition HashTable.H:1043
std::conditional_t< std::is_same_v< Foam::zero, std::remove_cv_t< T > >, Detail::HashTableSingle< Key >, Detail::HashTablePair< Key, T > > node_type
A table entry (node) that encapsulates the key/val tuple with an additional linked-list entry for has...
Definition HashTable.H:138
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66