00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/error.H>
00027
00028
00029
00030 template<class T, class Key, class Hash>
00031 inline Foam::HashTable<T, Key, Hash>::hashedEntry::hashedEntry
00032 (
00033 const Key& key,
00034 hashedEntry* next,
00035 const T& newEntry
00036 )
00037 :
00038 key_(key),
00039 next_(next),
00040 obj_(newEntry)
00041 {}
00042
00043
00044
00045
00046 template<class T, class Key, class Hash>
00047 inline Foam::label
00048 Foam::HashTable<T, Key, Hash>::hashKeyIndex(const Key& key) const
00049 {
00050
00051 return Hash()(key) & (tableSize_ - 1);
00052 }
00053
00054
00055
00056
00057 template<class T, class Key, class Hash>
00058 inline Foam::label Foam::HashTable<T, Key, Hash>::size() const
00059 {
00060 return nElmts_;
00061 }
00062
00063
00064 template<class T, class Key, class Hash>
00065 inline bool Foam::HashTable<T, Key, Hash>::empty() const
00066 {
00067 return !nElmts_;
00068 }
00069
00070
00071 template<class T, class Key, class Hash>
00072 inline bool Foam::HashTable<T, Key, Hash>::insert
00073 (
00074 const Key& key,
00075 const T& newEntry
00076 )
00077 {
00078 return set(key, newEntry, true);
00079 }
00080
00081
00082 template<class T, class Key, class Hash>
00083 inline bool Foam::HashTable<T, Key, Hash>::set
00084 (
00085 const Key& key,
00086 const T& newEntry
00087 )
00088 {
00089 return set(key, newEntry, false);
00090 }
00091
00092
00093 template<class T, class Key, class Hash>
00094 inline Foam::Xfer<Foam::HashTable<T, Key, Hash> >
00095 Foam::HashTable<T, Key, Hash>::xfer()
00096 {
00097 return xferMove(*this);
00098 }
00099
00100
00101
00102
00103 template<class T, class Key, class Hash>
00104 inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
00105 {
00106 iterator iter = find(key);
00107
00108 if (iter == end())
00109 {
00110 FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&)")
00111 << key << " not found in table. Valid entries: "
00112 << toc()
00113 << exit(FatalError);
00114 }
00115
00116 return *iter;
00117 }
00118
00119
00120 template<class T, class Key, class Hash>
00121 inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
00122 {
00123 const_iterator iter = find(key);
00124
00125 if (iter == cend())
00126 {
00127 FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&) const")
00128 << key << " not found in table. Valid entries: "
00129 << toc()
00130 << exit(FatalError);
00131 }
00132
00133 return *iter;
00134 }
00135
00136
00137 template<class T, class Key, class Hash>
00138 inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
00139 {
00140 iterator iter = find(key);
00141
00142 if (iter == end())
00143 {
00144 insert(key, T());
00145 return *find(key);
00146 }
00147 else
00148 {
00149 return *iter;
00150 }
00151 }
00152
00153
00154
00155
00156 template<class T, class Key, class Hash>
00157 inline Foam::HashTable<T, Key, Hash>::iterator::iterator
00158 (
00159 HashTable<T, Key, Hash>& hashTbl,
00160 hashedEntry* elmt,
00161 label hashIndex
00162 )
00163 :
00164 hashTable_(hashTbl),
00165 elmtPtr_(elmt),
00166 hashIndex_(hashIndex)
00167 {}
00168
00169
00170 template<class T, class Key, class Hash>
00171 inline void Foam::HashTable<T, Key, Hash>::iterator::operator=
00172 (
00173 const iterator& iter
00174 )
00175 {
00176 elmtPtr_ = iter.elmtPtr_;
00177 hashIndex_ = iter.hashIndex_;
00178 }
00179
00180
00181 template<class T, class Key, class Hash>
00182 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
00183 (
00184 const iterator& iter
00185 ) const
00186 {
00187 return elmtPtr_ == iter.elmtPtr_;
00188 }
00189
00190
00191 template<class T, class Key, class Hash>
00192 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
00193 (
00194 const iterator& iter
00195 ) const
00196 {
00197 return elmtPtr_ != iter.elmtPtr_;
00198 }
00199
00200
00201 template<class T, class Key, class Hash>
00202 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
00203 (
00204 const const_iterator& iter
00205 ) const
00206 {
00207 return elmtPtr_ == iter.elmtPtr_;
00208 }
00209
00210
00211 template<class T, class Key, class Hash>
00212 inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
00213 (
00214 const const_iterator& iter
00215 ) const
00216 {
00217 return elmtPtr_ != iter.elmtPtr_;
00218 }
00219
00220
00221 template<class T, class Key, class Hash>
00222 inline T&
00223 Foam::HashTable<T, Key, Hash>::iterator::operator*()
00224 {
00225 return elmtPtr_->obj_;
00226 }
00227
00228
00229 template<class T, class Key, class Hash>
00230 inline T&
00231 Foam::HashTable<T, Key, Hash>::iterator::operator()()
00232 {
00233 return elmtPtr_->obj_;
00234 }
00235
00236
00237 template<class T, class Key, class Hash>
00238 inline const T&
00239 Foam::HashTable<T, Key, Hash>::iterator::operator*() const
00240 {
00241 return elmtPtr_->obj_;
00242 }
00243
00244
00245 template<class T, class Key, class Hash>
00246 inline const T&
00247 Foam::HashTable<T, Key, Hash>::iterator::operator()() const
00248 {
00249 return elmtPtr_->obj_;
00250 }
00251
00252
00253 template<class T, class Key, class Hash>
00254 inline
00255 typename Foam::HashTable<T, Key, Hash>::iterator&
00256 Foam::HashTable<T, Key, Hash>::iterator::operator++()
00257 {
00258
00259 if (hashIndex_ >= 0)
00260 {
00261
00262 if (elmtPtr_ && elmtPtr_->next_)
00263 {
00264 elmtPtr_ = elmtPtr_->next_;
00265 return *this;
00266 }
00267 }
00268
00269
00270 while
00271 (
00272 ++hashIndex_ < hashTable_.tableSize_
00273 && !(elmtPtr_ = hashTable_.table_[hashIndex_])
00274 )
00275 {}
00276
00277 if (hashIndex_ == hashTable_.tableSize_)
00278 {
00279
00280 elmtPtr_ = 0;
00281 hashIndex_ = 0;
00282 }
00283 return *this;
00284 }
00285
00286
00287 template<class T, class Key, class Hash>
00288 inline typename Foam::HashTable<T, Key, Hash>::iterator
00289 Foam::HashTable<T, Key, Hash>::iterator::operator++
00290 (
00291 int
00292 )
00293 {
00294 iterator tmp = *this;
00295 ++*this;
00296 return tmp;
00297 }
00298
00299
00300 template<class T, class Key, class Hash>
00301 inline
00302 const Key& Foam::HashTable<T, Key, Hash>::iterator::key() const
00303 {
00304 return elmtPtr_->key_;
00305 }
00306
00307
00308 template<class T, class Key, class Hash>
00309 inline typename Foam::HashTable<T, Key, Hash>::iterator
00310 Foam::HashTable<T, Key, Hash>::begin()
00311 {
00312 label i = 0;
00313
00314 if (nElmts_)
00315 {
00316 while (table_ && !table_[i] && ++i < tableSize_)
00317 {}
00318 }
00319 else
00320 {
00321 i = tableSize_;
00322 }
00323
00324 if (i == tableSize_)
00325 {
00326 # ifdef FULLDEBUG
00327 if (debug)
00328 {
00329 Info<< "HashTable is empty\n";
00330 }
00331 # endif
00332
00333 return HashTable<T, Key, Hash>::endIter_;
00334 }
00335 else
00336 {
00337 return iterator(*this, table_[i], i);
00338 }
00339 }
00340
00341
00342 template<class T, class Key, class Hash>
00343 inline const typename Foam::HashTable<T, Key, Hash>::iterator&
00344 Foam::HashTable<T, Key, Hash>::end()
00345 {
00346 return HashTable<T, Key, Hash>::endIter_;
00347 }
00348
00349
00350
00351
00352 template<class T, class Key, class Hash>
00353 inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
00354 (
00355 const HashTable<T, Key, Hash>& hashTbl,
00356 const hashedEntry* elmt,
00357 label hashIndex
00358 )
00359 :
00360 hashTable_(hashTbl),
00361 elmtPtr_(elmt),
00362 hashIndex_(hashIndex)
00363 {}
00364
00365
00366 template<class T, class Key, class Hash>
00367 inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
00368 (
00369 const iterator& iter
00370 )
00371 :
00372 hashTable_(iter.hashTable_),
00373 elmtPtr_(iter.elmtPtr_),
00374 hashIndex_(iter.hashIndex_)
00375 {}
00376
00377
00378 template<class T, class Key, class Hash>
00379 inline void Foam::HashTable<T, Key, Hash>::const_iterator::operator=
00380 (
00381 const const_iterator& iter
00382 )
00383 {
00384 elmtPtr_ = iter.elmtPtr_;
00385 hashIndex_ = iter.hashIndex_;
00386 }
00387
00388
00389 template<class T, class Key, class Hash>
00390 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
00391 (
00392 const const_iterator& iter
00393 ) const
00394 {
00395 return elmtPtr_ == iter.elmtPtr_;
00396 }
00397
00398
00399 template<class T, class Key, class Hash>
00400 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
00401 (
00402 const const_iterator& iter
00403 ) const
00404 {
00405 return elmtPtr_ != iter.elmtPtr_;
00406 }
00407
00408
00409 template<class T, class Key, class Hash>
00410 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
00411 (
00412 const iterator& iter
00413 ) const
00414 {
00415 return elmtPtr_ == iter.elmtPtr_;
00416 }
00417
00418
00419 template<class T, class Key, class Hash>
00420 inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
00421 (
00422 const iterator& iter
00423 ) const
00424 {
00425 return elmtPtr_ != iter.elmtPtr_;
00426 }
00427
00428
00429 template<class T, class Key, class Hash>
00430 inline const T&
00431 Foam::HashTable<T, Key, Hash>::const_iterator::operator*() const
00432 {
00433 return elmtPtr_->obj_;
00434 }
00435
00436 template<class T, class Key, class Hash>
00437 inline const T&
00438 Foam::HashTable<T, Key, Hash>::const_iterator::operator()() const
00439 {
00440 return elmtPtr_->obj_;
00441 }
00442
00443
00444 template<class T, class Key, class Hash>
00445 inline
00446 typename Foam::HashTable<T, Key, Hash>::const_iterator&
00447 Foam::HashTable<T, Key, Hash>::const_iterator::operator++()
00448 {
00449 if
00450 (
00451 !(elmtPtr_ = elmtPtr_->next_)
00452 && ++hashIndex_ < hashTable_.tableSize_
00453 && !(elmtPtr_ = hashTable_.table_[hashIndex_])
00454 )
00455 {
00456 while
00457 (
00458 ++hashIndex_ < hashTable_.tableSize_
00459 && !(elmtPtr_ = hashTable_.table_[hashIndex_])
00460 )
00461 {}
00462 }
00463
00464 return *this;
00465 }
00466
00467
00468 template<class T, class Key, class Hash>
00469 inline typename Foam::HashTable<T, Key, Hash>::const_iterator
00470 Foam::HashTable<T, Key, Hash>::const_iterator::operator++
00471 (
00472 int
00473 )
00474 {
00475 const_iterator tmp = *this;
00476 ++*this;
00477 return tmp;
00478 }
00479
00480
00481 template<class T, class Key, class Hash>
00482 inline
00483 const Key& Foam::HashTable<T, Key, Hash>::const_iterator::key() const
00484 {
00485 return elmtPtr_->key_;
00486 }
00487
00488
00489 template<class T, class Key, class Hash>
00490 inline typename Foam::HashTable<T, Key, Hash>::const_iterator
00491 Foam::HashTable<T, Key, Hash>::cbegin() const
00492 {
00493 label i = 0;
00494
00495 if (nElmts_)
00496 {
00497 while (table_ && !table_[i] && ++i < tableSize_)
00498 {}
00499 }
00500 else
00501 {
00502 i = tableSize_;
00503 }
00504
00505 if (i == tableSize_)
00506 {
00507 # ifdef FULLDEBUG
00508 if (debug)
00509 {
00510 Info<< "HashTable is empty\n";
00511 }
00512 # endif
00513
00514 return HashTable<T, Key, Hash>::endConstIter_;
00515 }
00516 else
00517 {
00518 return const_iterator(*this, table_[i], i);
00519 }
00520 }
00521
00522
00523 template<class T, class Key, class Hash>
00524 inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
00525 Foam::HashTable<T, Key, Hash>::cend() const
00526 {
00527 return HashTable<T, Key, Hash>::endConstIter_;
00528 }
00529
00530
00531 template<class T, class Key, class Hash>
00532 inline typename Foam::HashTable<T, Key, Hash>::const_iterator
00533 Foam::HashTable<T, Key, Hash>::begin() const
00534 {
00535 return this->cbegin();
00536 }
00537
00538
00539 template<class T, class Key, class Hash>
00540 inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
00541 Foam::HashTable<T, Key, Hash>::end() const
00542 {
00543 return HashTable<T, Key, Hash>::endConstIter_;
00544 }
00545
00546
00547