FreeFOAM The Cross-Platform CFD Toolkit
StaticHashTableI.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 | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include <OpenFOAM/error.H>
27 #include <OpenFOAM/IOstreams.H>
28 
29 // * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * //
30 
31 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
32 
33 template<class T, class Key, class Hash>
34 inline Foam::label
36 {
37  // size is power of two - this is the modulus
38  return Hash()(key) & (keys_.size() - 1);
39 }
40 
41 
42 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
43 
44 template<class T, class Key, class Hash>
46 {
47  return nElmts_;
48 }
49 
50 
51 template<class T, class Key, class Hash>
53 {
54  return !nElmts_;
55 }
56 
57 
58 template<class T, class Key, class Hash>
60 (
61  const Key& key,
62  const T& newEntry
63 )
64 {
65  return set(key, newEntry, true);
66 }
67 
68 
69 template<class T, class Key, class Hash>
71 (
72  const Key& key,
73  const T& newEntry
74 )
75 {
76  return set(key, newEntry, false);
77 }
78 
79 
80 template<class T, class Key, class Hash>
83 {
84  return xferMove(*this);
85 }
86 
87 
88 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
89 
90 template<class T, class Key, class Hash>
92 {
93  iterator iter = find(key);
94 
95  if (iter == end())
96  {
97  FatalErrorIn("StaticHashTable<T, Key, Hash>::operator[](const Key&)")
98  << key << " not found in table. Valid entries: "
99  << toc()
100  << exit(FatalError);
101  }
102 
103  return *iter;
104 }
105 
106 
107 template<class T, class Key, class Hash>
109 (
110  const Key& key
111 ) const
112 {
113  const_iterator iter = find(key);
114 
115  if (iter == cend())
116  {
118  (
119  "StaticHashTable<T, Key, Hash>::operator[](const Key&) const"
120  ) << key << " not found in table. Valid entries: "
121  << toc()
122  << exit(FatalError);
123  }
124 
125  return *iter;
126 }
127 
128 
129 template<class T, class Key, class Hash>
131 {
132  iterator iter = find(key);
133 
134  if (iter == end())
135  {
136  insert(key, T());
137  return *find(key);
138  }
139  else
140  {
141  return *iter;
142  }
143 }
144 
145 
146 // * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
147 
148 template<class T, class Key, class Hash>
149 template<class TRef, class TableRef>
151 (
152  TableRef hashTbl,
153  label hashIndex,
154  label elemIndex
155 )
156 :
157  hashTable_(hashTbl),
158  hashIndex_(hashIndex),
159  elemIndex_(elemIndex)
160 {}
161 
162 
163 template<class T, class Key, class Hash>
164 template<class TRef, class TableRef>
166 (
167  const iterator& iter
168 )
169 :
170  hashTable_(iter.hashTable_),
171  hashIndex_(iter.hashIndex_),
172  elemIndex_(iter.elemIndex_)
173 {}
174 
175 
176 template<class T, class Key, class Hash>
177 template<class TRef, class TableRef>
178 inline void
180 (
181  const iterator& iter
182 )
183 {
184  this->hashIndex_ = iter.hashIndex_;
185  this->elemIndex_ = iter.elemIndex_;
186 }
187 
188 
189 template<class T, class Key, class Hash>
190 template<class TRef, class TableRef>
191 inline bool
193 (
194  const iterator& iter
195 ) const
196 {
197  return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_;
198 }
199 
200 
201 template<class T, class Key, class Hash>
202 template<class TRef, class TableRef>
203 inline bool
205 (
206  const const_iterator& iter
207 ) const
208 {
209  return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_;
210 }
211 
212 
213 template<class T, class Key, class Hash>
214 template<class TRef, class TableRef>
215 inline bool
217 (
218  const iterator& iter
219 ) const
220 {
221  return !operator==(iter);
222 }
223 
224 
225 template<class T, class Key, class Hash>
226 template<class TRef, class TableRef>
227 inline bool
229 (
230  const const_iterator& iter
231 ) const
232 {
233  return !operator==(iter);
234 }
235 
236 
237 template<class T, class Key, class Hash>
238 template<class TRef, class TableRef>
239 inline TRef
241 {
242  return hashTable_.objects_[hashIndex_][elemIndex_];
243 }
244 
245 
246 template<class T, class Key, class Hash>
247 template<class TRef, class TableRef>
248 inline TRef
250 {
251  return operator*();
252 }
253 
254 
255 template<class T, class Key, class Hash>
256 template<class TRef, class TableRef>
257 inline
259 <
260  TRef,
261  TableRef
262 >&
264 <
265  TRef,
266  TableRef
267 >::operator++()
268 {
269  // Check for special value from erase. (sets hashIndex to -1)
270  if (hashIndex_ >= 0)
271  {
272  // Try the next element on the local list
273  elemIndex_++;
274 
275  if (elemIndex_ < hashTable_.objects_[hashIndex_].size())
276  {
277  return *this;
278  }
279  }
280 
281  // Step to the next table entry
282  elemIndex_ = 0;
283 
284  while
285  (
286  ++hashIndex_ < hashTable_.objects_.size()
287  && !hashTable_.objects_[hashIndex_].size()
288  )
289  {}
290 
291 
292  if (hashIndex_ >= hashTable_.objects_.size())
293  {
294  // make end iterator
295  hashIndex_ = hashTable_.keys_.size();
296  }
297 
298  return *this;
299 }
300 
301 
302 template<class T, class Key, class Hash>
303 template<class TRef, class TableRef>
304 inline
306 <
307  TRef,
308  TableRef
309 >
311 <
312  TRef,
313  TableRef
314 >::operator++
315 (
316  int
317 )
318 {
319  iterator tmp = *this;
320  ++*this;
321  return tmp;
322 }
323 
324 
325 template<class T, class Key, class Hash>
326 template<class TRef, class TableRef>
327 inline const Key&
329 {
330  return hashTable_.keys_[hashIndex_][elemIndex_];
331 }
332 
333 
334 template<class T, class Key, class Hash>
337 {
338  // Find first non-empty entry
339  forAll(keys_, hashIdx)
340  {
341  if (keys_[hashIdx].size())
342  {
343  return iterator(*this, hashIdx, 0);
344  }
345  }
346 
347 # ifdef FULLDEBUG
348  if (debug)
349  {
350  Info<< "StaticHashTable is empty\n";
351  }
352 # endif
353 
355 }
356 
357 
358 template<class T, class Key, class Hash>
361 {
363 }
364 
365 
366 template<class T, class Key, class Hash>
369 {
370  // Find first non-empty entry
371  forAll(keys_, hashIdx)
372  {
373  if (keys_[hashIdx].size())
374  {
375  return const_iterator(*this, hashIdx, 0);
376  }
377  }
378 
379 # ifdef FULLDEBUG
380  if (debug)
381  {
382  Info<< "StaticHashTable is empty\n";
383  }
384 # endif
385 
387 }
388 
389 
390 template<class T, class Key, class Hash>
393 {
395 }
396 
397 
398 template<class T, class Key, class Hash>
401 {
402  return this->cbegin();
403 }
404 
405 
406 template<class T, class Key, class Hash>
409 {
411 }
412 
413 
414 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
415 
416 // ************************ vim: set sw=4 sts=4 et: ************************ //