FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

StaticHashTableI.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include <OpenFOAM/error.H>
00027 #include <OpenFOAM/IOstreams.H>
00028 
00029 // * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * //
00030 
00031 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
00032 
00033 template<class T, class Key, class Hash>
00034 inline Foam::label
00035 Foam::StaticHashTable<T, Key, Hash>::hashKeyIndex(const Key& key) const
00036 {
00037     // size is power of two - this is the modulus
00038     return Hash()(key) & (keys_.size() - 1);
00039 }
00040 
00041 
00042 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
00043 
00044 template<class T, class Key, class Hash>
00045 inline Foam::label Foam::StaticHashTable<T, Key, Hash>::size() const
00046 {
00047     return nElmts_;
00048 }
00049 
00050 
00051 template<class T, class Key, class Hash>
00052 inline bool Foam::StaticHashTable<T, Key, Hash>::empty() const
00053 {
00054     return !nElmts_;
00055 }
00056 
00057 
00058 template<class T, class Key, class Hash>
00059 inline bool Foam::StaticHashTable<T, Key, Hash>::insert
00060 (
00061     const Key& key,
00062     const T& newEntry
00063 )
00064 {
00065     return set(key, newEntry, true);
00066 }
00067 
00068 
00069 template<class T, class Key, class Hash>
00070 inline bool Foam::StaticHashTable<T, Key, Hash>::set
00071 (
00072     const Key& key,
00073     const T& newEntry
00074 )
00075 {
00076     return set(key, newEntry, false);
00077 }
00078 
00079 
00080 template<class T, class Key, class Hash>
00081 inline Foam::Xfer< Foam::StaticHashTable<T, Key, Hash> >
00082 Foam::StaticHashTable<T, Key, Hash>::xfer()
00083 {
00084     return xferMove(*this);
00085 }
00086 
00087 
00088 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00089 
00090 template<class T, class Key, class Hash>
00091 inline T& Foam::StaticHashTable<T, Key, Hash>::operator[](const Key& key)
00092 {
00093     iterator iter = find(key);
00094 
00095     if (iter == end())
00096     {
00097         FatalErrorIn("StaticHashTable<T, Key, Hash>::operator[](const Key&)")
00098             << key << " not found in table.  Valid entries: "
00099             << toc()
00100             << exit(FatalError);
00101     }
00102 
00103     return *iter;
00104 }
00105 
00106 
00107 template<class T, class Key, class Hash>
00108 inline const T& Foam::StaticHashTable<T, Key, Hash>::operator[]
00109 (
00110     const Key& key
00111 ) const
00112 {
00113     const_iterator iter = find(key);
00114 
00115     if (iter == cend())
00116     {
00117         FatalErrorIn
00118         (
00119             "StaticHashTable<T, Key, Hash>::operator[](const Key&) const"
00120         )   << key << " not found in table.  Valid entries: "
00121             << toc()
00122             << exit(FatalError);
00123     }
00124 
00125     return *iter;
00126 }
00127 
00128 
00129 template<class T, class Key, class Hash>
00130 inline T& Foam::StaticHashTable<T, Key, Hash>::operator()(const Key& key)
00131 {
00132     iterator iter = find(key);
00133 
00134     if (iter == end())
00135     {
00136         insert(key, T());
00137         return *find(key);
00138     }
00139     else
00140     {
00141         return *iter;
00142     }
00143 }
00144 
00145 
00146 // * * * * * * * * * * * * * * * * STL iterator  * * * * * * * * * * * * * * //
00147 
00148 template<class T, class Key, class Hash>
00149 template<class TRef, class TableRef>
00150 inline Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::Iterator
00151 (
00152     TableRef hashTbl,
00153     label hashIndex,
00154     label elemIndex
00155 )
00156 :
00157     hashTable_(hashTbl),
00158     hashIndex_(hashIndex),
00159     elemIndex_(elemIndex)
00160 {}
00161 
00162 
00163 template<class T, class Key, class Hash>
00164 template<class TRef, class TableRef>
00165 inline Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::Iterator
00166 (
00167     const iterator& iter
00168 )
00169 :
00170     hashTable_(iter.hashTable_),
00171     hashIndex_(iter.hashIndex_),
00172     elemIndex_(iter.elemIndex_)
00173 {}
00174 
00175 
00176 template<class T, class Key, class Hash>
00177 template<class TRef, class TableRef>
00178 inline void
00179 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator=
00180 (
00181     const iterator& iter
00182 )
00183 {
00184     this->hashIndex_ = iter.hashIndex_;
00185     this->elemIndex_ = iter.elemIndex_;
00186 }
00187 
00188 
00189 template<class T, class Key, class Hash>
00190 template<class TRef, class TableRef>
00191 inline bool
00192 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator==
00193 (
00194     const iterator& iter
00195 ) const
00196 {
00197     return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_;
00198 }
00199 
00200 
00201 template<class T, class Key, class Hash>
00202 template<class TRef, class TableRef>
00203 inline bool
00204 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator==
00205 (
00206     const const_iterator& iter
00207 ) const
00208 {
00209     return hashIndex_ == iter.hashIndex_ && elemIndex_ == iter.elemIndex_;
00210 }
00211 
00212 
00213 template<class T, class Key, class Hash>
00214 template<class TRef, class TableRef>
00215 inline bool
00216 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator!=
00217 (
00218     const iterator& iter
00219 ) const
00220 {
00221     return !operator==(iter);
00222 }
00223 
00224 
00225 template<class T, class Key, class Hash>
00226 template<class TRef, class TableRef>
00227 inline bool
00228 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator!=
00229 (
00230     const const_iterator& iter
00231 ) const
00232 {
00233     return !operator==(iter);
00234 }
00235 
00236 
00237 template<class T, class Key, class Hash>
00238 template<class TRef, class TableRef>
00239 inline TRef
00240 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator*()
00241 {
00242     return hashTable_.objects_[hashIndex_][elemIndex_];
00243 }
00244 
00245 
00246 template<class T, class Key, class Hash>
00247 template<class TRef, class TableRef>
00248 inline TRef
00249 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::operator()()
00250 {
00251     return operator*();
00252 }
00253 
00254 
00255 template<class T, class Key, class Hash>
00256 template<class TRef, class TableRef>
00257 inline
00258 typename Foam::StaticHashTable<T, Key, Hash>::template Iterator
00259 <
00260     TRef,
00261     TableRef
00262 >&
00263 Foam::StaticHashTable<T, Key, Hash>::Iterator
00264 <
00265     TRef,
00266     TableRef
00267 >::operator++()
00268 {
00269     // Check for special value from erase. (sets hashIndex to -1)
00270     if (hashIndex_ >= 0)
00271     {
00272         // Try the next element on the local list
00273         elemIndex_++;
00274 
00275         if (elemIndex_ < hashTable_.objects_[hashIndex_].size())
00276         {
00277             return *this;
00278         }
00279     }
00280 
00281     // Step to the next table entry
00282     elemIndex_ = 0;
00283 
00284     while
00285     (
00286         ++hashIndex_ < hashTable_.objects_.size()
00287      && !hashTable_.objects_[hashIndex_].size()
00288     )
00289     {}
00290 
00291 
00292     if (hashIndex_ >= hashTable_.objects_.size())
00293     {
00294         // make end iterator
00295         hashIndex_ = hashTable_.keys_.size();
00296     }
00297 
00298     return *this;
00299 }
00300 
00301 
00302 template<class T, class Key, class Hash>
00303 template<class TRef, class TableRef>
00304 inline
00305 typename Foam::StaticHashTable<T, Key, Hash>::template Iterator
00306 <
00307     TRef,
00308     TableRef
00309 >
00310 Foam::StaticHashTable<T, Key, Hash>::Iterator
00311 <
00312     TRef,
00313     TableRef
00314 >::operator++
00315 (
00316     int
00317 )
00318 {
00319     iterator tmp = *this;
00320     ++*this;
00321     return tmp;
00322 }
00323 
00324 
00325 template<class T, class Key, class Hash>
00326 template<class TRef, class TableRef>
00327 inline const Key&
00328 Foam::StaticHashTable<T, Key, Hash>::Iterator<TRef, TableRef>::key() const
00329 {
00330     return hashTable_.keys_[hashIndex_][elemIndex_];
00331 }
00332 
00333 
00334 template<class T, class Key, class Hash>
00335 inline typename Foam::StaticHashTable<T, Key, Hash>::iterator
00336 Foam::StaticHashTable<T, Key, Hash>::begin()
00337 {
00338     // Find first non-empty entry
00339     forAll(keys_, hashIdx)
00340     {
00341         if (keys_[hashIdx].size())
00342         {
00343             return iterator(*this, hashIdx, 0);
00344         }
00345     }
00346 
00347 #   ifdef FULLDEBUG
00348     if (debug)
00349     {
00350         Info<< "StaticHashTable is empty\n";
00351     }
00352 #   endif
00353 
00354     return StaticHashTable<T, Key, Hash>::endIter_;
00355 }
00356 
00357 
00358 template<class T, class Key, class Hash>
00359 inline const typename Foam::StaticHashTable<T, Key, Hash>::iterator&
00360 Foam::StaticHashTable<T, Key, Hash>::end()
00361 {
00362     return StaticHashTable<T, Key, Hash>::endIter_;
00363 }
00364 
00365 
00366 template<class T, class Key, class Hash>
00367 inline typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
00368 Foam::StaticHashTable<T, Key, Hash>::cbegin() const
00369 {
00370     // Find first non-empty entry
00371     forAll(keys_, hashIdx)
00372     {
00373         if (keys_[hashIdx].size())
00374         {
00375             return const_iterator(*this, hashIdx, 0);
00376         }
00377     }
00378 
00379 #   ifdef FULLDEBUG
00380     if (debug)
00381     {
00382         Info<< "StaticHashTable is empty\n";
00383     }
00384 #   endif
00385 
00386     return StaticHashTable<T, Key, Hash>::endConstIter_;
00387 }
00388 
00389 
00390 template<class T, class Key, class Hash>
00391 inline const typename Foam::StaticHashTable<T, Key, Hash>::const_iterator&
00392 Foam::StaticHashTable<T, Key, Hash>::cend() const
00393 {
00394     return StaticHashTable<T, Key, Hash>::endConstIter_;
00395 }
00396 
00397 
00398 template<class T, class Key, class Hash>
00399 inline typename Foam::StaticHashTable<T, Key, Hash>::const_iterator
00400 Foam::StaticHashTable<T, Key, Hash>::begin() const
00401 {
00402     return this->cbegin();
00403 }
00404 
00405 
00406 template<class T, class Key, class Hash>
00407 inline const typename Foam::StaticHashTable<T, Key, Hash>::const_iterator&
00408 Foam::StaticHashTable<T, Key, Hash>::end() const
00409 {
00410     return StaticHashTable<T, Key, Hash>::endConstIter_;
00411 }
00412 
00413 
00414 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00415 
00416 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines