Merge in forgotten Fix
This commit is contained in:
commit
7aaa5958f6
16 changed files with 824 additions and 667 deletions
|
@ -81,8 +81,8 @@ coordinateSystems/coordinateRotation/axisCoordinateRotation.C
|
|||
|
||||
primitives/random/Random.C
|
||||
|
||||
containers/HashTables/HashTable/HashTableName.C
|
||||
containers/HashTables/StaticHashTable/StaticHashTableName.C
|
||||
containers/HashTables/HashTable/HashTableCore.C
|
||||
containers/HashTables/StaticHashTable/StaticHashTableCore.C
|
||||
containers/Lists/SortableList/ParSortableListName.C
|
||||
containers/Lists/PackedList/PackedListName.C
|
||||
containers/Lists/ListOps/ListOps.C
|
||||
|
|
|
@ -24,19 +24,13 @@ License
|
|||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "error.H"
|
||||
|
||||
#include "HashPtrTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct given initial table size
|
||||
template<class T, class Key, class Hash>
|
||||
HashPtrTable<T, Key, Hash>::HashPtrTable(label size)
|
||||
Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(const label size)
|
||||
:
|
||||
HashTable<T*, Key, Hash>(size)
|
||||
{}
|
||||
|
@ -44,14 +38,16 @@ HashPtrTable<T, Key, Hash>::HashPtrTable(label size)
|
|||
|
||||
// Construct as copy
|
||||
template<class T, class Key, class Hash>
|
||||
HashPtrTable<T, Key, Hash>::HashPtrTable(const HashPtrTable<T, Key, Hash>& ht)
|
||||
Foam::HashPtrTable<T, Key, Hash>::HashPtrTable
|
||||
(
|
||||
const HashPtrTable<T, Key, Hash>& ht
|
||||
)
|
||||
:
|
||||
HashTable<T*, Key, Hash>()
|
||||
{
|
||||
for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
|
||||
{
|
||||
// Bug fix, Microsoft port. HJ, 21/Mar/2011
|
||||
this->insert(iter.key(), iter()->clone().ptr());
|
||||
this->insert(iter.key(), new T(**iter));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +55,7 @@ HashPtrTable<T, Key, Hash>::HashPtrTable(const HashPtrTable<T, Key, Hash>& ht)
|
|||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
HashPtrTable<T, Key, Hash>::~HashPtrTable()
|
||||
Foam::HashPtrTable<T, Key, Hash>::~HashPtrTable()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
@ -68,7 +64,7 @@ HashPtrTable<T, Key, Hash>::~HashPtrTable()
|
|||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
T* HashPtrTable<T, Key, Hash>::remove(iterator& it)
|
||||
T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& it)
|
||||
{
|
||||
T* elemPtr = *it;
|
||||
HashTable<T*, Key, Hash>::erase(it);
|
||||
|
@ -77,7 +73,7 @@ T* HashPtrTable<T, Key, Hash>::remove(iterator& it)
|
|||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
bool HashPtrTable<T, Key, Hash>::erase(iterator& it)
|
||||
bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& it)
|
||||
{
|
||||
T* elemPtr = *it;
|
||||
|
||||
|
@ -98,7 +94,7 @@ bool HashPtrTable<T, Key, Hash>::erase(iterator& it)
|
|||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void HashPtrTable<T, Key, Hash>::clear()
|
||||
void Foam::HashPtrTable<T, Key, Hash>::clear()
|
||||
{
|
||||
for
|
||||
(
|
||||
|
@ -117,13 +113,13 @@ void HashPtrTable<T, Key, Hash>::clear()
|
|||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void HashPtrTable<T, Key, Hash>::operator=
|
||||
void Foam::HashPtrTable<T, Key, Hash>::operator=
|
||||
(
|
||||
const HashPtrTable<T, Key, Hash>& ht
|
||||
const HashPtrTable<T, Key, Hash>& rhs
|
||||
)
|
||||
{
|
||||
// Check for assignment to self
|
||||
if (this == &ht)
|
||||
if (this == &rhs)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
|
@ -133,20 +129,14 @@ void HashPtrTable<T, Key, Hash>::operator=
|
|||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
clear();
|
||||
this->clear();
|
||||
|
||||
for(const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
|
||||
for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter)
|
||||
{
|
||||
// Bug fix, Microsoft port. HJ, 21/Mar/2011
|
||||
insert(iter.key(), iter()->clone().ptr());
|
||||
this->insert(iter.key(), new T(**iter));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
#include "HashPtrTableIO.C"
|
||||
|
|
|
@ -50,34 +50,33 @@ class Ostream;
|
|||
|
||||
template<class T, class Key, class Hash> class HashPtrTable;
|
||||
|
||||
template<class T, class Key, class Hash> Istream& operator>>
|
||||
(
|
||||
Istream&,
|
||||
HashPtrTable<T, Key, Hash>&
|
||||
);
|
||||
template<class T, class Key, class Hash>
|
||||
Istream& operator>>(Istream&, HashPtrTable<T, Key, Hash>&);
|
||||
|
||||
template<class T, class Key, class Hash> Ostream& operator<<
|
||||
(
|
||||
Ostream&,
|
||||
const HashPtrTable<T, Key, Hash>&
|
||||
);
|
||||
template<class T, class Key, class Hash>
|
||||
Ostream& operator<<(Ostream&, const HashPtrTable<T, Key, Hash>&);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class HashPtrTable Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class T, class Key = word, class Hash = string::hash>
|
||||
template<class T, class Key=word, class Hash=string::hash>
|
||||
class HashPtrTable
|
||||
:
|
||||
public HashTable<T*, Key, Hash>
|
||||
{
|
||||
// Private member functions
|
||||
// Private Member Functions
|
||||
|
||||
//- Read from Istream using given Istream constructor class
|
||||
template<class INew>
|
||||
void read(Istream&, const INew& inewt);
|
||||
|
||||
//- Read from dictionary using given dictionary constructor class
|
||||
template<class INew>
|
||||
void read(const dictionary& dict, const INew& inewt);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
@ -97,13 +96,16 @@ public:
|
|||
//- Construct from Istream using default Istream constructor class
|
||||
HashPtrTable(Istream&);
|
||||
|
||||
//- Construct from dictionary using default dictionary constructor
|
||||
// class
|
||||
HashPtrTable(const dictionary&);
|
||||
|
||||
//- Construct as copy
|
||||
HashPtrTable(const HashPtrTable<T, Key, Hash>&);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
~HashPtrTable();
|
||||
//- Destructor
|
||||
~HashPtrTable();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
@ -119,6 +121,9 @@ public:
|
|||
//- Clear all entries from table
|
||||
void clear();
|
||||
|
||||
//- Write
|
||||
void write(Ostream& os) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
|
@ -127,7 +132,6 @@ public:
|
|||
|
||||
// IOstream Operators
|
||||
|
||||
#ifndef SWIG
|
||||
friend Istream& operator>> <T, Key, Hash>
|
||||
(
|
||||
Istream&,
|
||||
|
@ -139,7 +143,6 @@ public:
|
|||
Ostream&,
|
||||
const HashPtrTable<T, Key, Hash>&
|
||||
);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,17 +27,13 @@ License
|
|||
#include "Istream.H"
|
||||
#include "Ostream.H"
|
||||
#include "INew.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
#include "dictionary.H"
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
template<class INew>
|
||||
void HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
|
||||
void Foam::HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
|
||||
{
|
||||
is.fatalCheck("HashPtrTable<T, Key, Hash>::read(Istream&, const INew&)");
|
||||
|
||||
|
@ -54,7 +50,7 @@ void HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
|
|||
label s = firstToken.labelToken();
|
||||
|
||||
// Read beginning of contents
|
||||
char listDelimiter = is.readBeginList("HashPtrTable<T, Key, Hash>");
|
||||
char delimiter = is.readBeginList("HashPtrTable<T, Key, Hash>");
|
||||
|
||||
if (s)
|
||||
{
|
||||
|
@ -63,7 +59,7 @@ void HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
|
|||
this->resize(2*s);
|
||||
}
|
||||
|
||||
if (listDelimiter == token::BEGIN_LIST)
|
||||
if (delimiter == token::BEGIN_LIST)
|
||||
{
|
||||
for (label i=0; i<s; i++)
|
||||
{
|
||||
|
@ -142,27 +138,71 @@ void HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
|
|||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
template<class INew>
|
||||
HashPtrTable<T, Key, Hash>::HashPtrTable(Istream& is, const INew& inewt)
|
||||
void Foam::HashPtrTable<T, Key, Hash>::read
|
||||
(
|
||||
const dictionary& dict,
|
||||
const INew& inewt
|
||||
)
|
||||
{
|
||||
read(is, inewt);
|
||||
forAllConstIter(dictionary, dict, iter)
|
||||
{
|
||||
this->insert
|
||||
(
|
||||
iter().keyword(),
|
||||
inewt(dict.subDict(iter().keyword())).ptr()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
HashPtrTable<T, Key, Hash>::HashPtrTable(Istream& is)
|
||||
void Foam::HashPtrTable<T, Key, Hash>::write(Ostream& os) const
|
||||
{
|
||||
read(is, INew<T>());
|
||||
|
||||
for
|
||||
(
|
||||
typename HashPtrTable<T, Key, Hash>::const_iterator
|
||||
iter = this->begin();
|
||||
iter != this->end();
|
||||
++iter
|
||||
)
|
||||
{
|
||||
const T* ptr = iter();
|
||||
ptr->write(os);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
template<class INew>
|
||||
Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(Istream& is, const INew& inewt)
|
||||
{
|
||||
this->read(is, inewt);
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(Istream& is)
|
||||
{
|
||||
this->read(is, INew<T>());
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(const dictionary& dict)
|
||||
{
|
||||
this->read(dict, INew<T>());
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Istream& operator>>(Istream& is, HashPtrTable<T, Key, Hash>& L)
|
||||
Foam::Istream& Foam::operator>>(Istream& is, HashPtrTable<T, Key, Hash>& L)
|
||||
{
|
||||
L.clear();
|
||||
L.read(is, INew<T>());
|
||||
|
@ -172,15 +212,16 @@ Istream& operator>>(Istream& is, HashPtrTable<T, Key, Hash>& L)
|
|||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Ostream& operator<<(Ostream& os, const HashPtrTable<T, Key, Hash>& L)
|
||||
Foam::Ostream& Foam::operator<<
|
||||
(
|
||||
Ostream& os,
|
||||
const HashPtrTable<T, Key, Hash>& L
|
||||
)
|
||||
{
|
||||
// Write size of HashPtrTable
|
||||
os << nl << L.size();
|
||||
// Write size and start delimiter
|
||||
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
|
||||
|
||||
// Write beginning of contents
|
||||
os << nl << token::BEGIN_LIST << nl;
|
||||
|
||||
// Write HashPtrTable contents
|
||||
// Write contents
|
||||
for
|
||||
(
|
||||
typename HashPtrTable<T, Key, Hash>::const_iterator iter = L.begin();
|
||||
|
@ -191,7 +232,7 @@ Ostream& operator<<(Ostream& os, const HashPtrTable<T, Key, Hash>& L)
|
|||
os << iter.key() << token::SPACE << *iter() << nl;
|
||||
}
|
||||
|
||||
// Write end of contents
|
||||
// Write end delimiter
|
||||
os << token::END_LIST;
|
||||
|
||||
// Check state of IOstream
|
||||
|
@ -201,8 +242,4 @@ Ostream& operator<<(Ostream& os, const HashPtrTable<T, Key, Hash>& L)
|
|||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
|
|
|
@ -52,6 +52,24 @@ Foam::HashSet<Key, Hash>::HashSet
|
|||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Key, class Hash>
|
||||
Foam::label Foam::HashSet<Key, Hash>::insert(const UList<Key>& lst)
|
||||
{
|
||||
label count = 0;
|
||||
forAll(lst, elemI)
|
||||
{
|
||||
if (this->insert(lst[elemI]))
|
||||
{
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
template<class Key, class Hash>
|
||||
|
@ -89,7 +107,7 @@ bool Foam::HashSet<Key, Hash>::operator==(const HashSet<Key, Hash>& rhs) const
|
|||
template<class Key, class Hash>
|
||||
bool Foam::HashSet<Key, Hash>::operator!=(const HashSet<Key, Hash>& rhs) const
|
||||
{
|
||||
return !(this->operator==(rhs));
|
||||
return !(operator==(rhs));
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,7 +142,7 @@ void Foam::HashSet<Key, Hash>::operator^=(const HashSet<Key, Hash>& rhs)
|
|||
// Add missed rhs elements, remove duplicate elements
|
||||
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
|
||||
{
|
||||
if (found(iter.key()))
|
||||
if (this->found(iter.key()))
|
||||
{
|
||||
this->erase(iter.key());
|
||||
}
|
||||
|
|
|
@ -128,10 +128,26 @@ public:
|
|||
return HashTable<nil, Key, Hash>::insert(key, nil());
|
||||
}
|
||||
|
||||
//- Insert keys from a UList of Key
|
||||
// Return the number of new elements inserted
|
||||
label insert(const UList<Key>&);
|
||||
|
||||
//- Same as insert (cannot overwrite nil content)
|
||||
bool set(const Key& key)
|
||||
{
|
||||
return HashTable<nil, Key, Hash>::insert(key, nil());
|
||||
return insert(key);
|
||||
}
|
||||
|
||||
//- Same as insert (cannot overwrite nil content)
|
||||
label set(const UList<Key>& lst)
|
||||
{
|
||||
return insert(lst);
|
||||
}
|
||||
|
||||
//- Unset the specified key - same as erase
|
||||
bool unset(const Key& key)
|
||||
{
|
||||
return HashTable<nil, Key, Hash>::erase(key);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,44 +29,15 @@ License
|
|||
#include "HashTable.H"
|
||||
#include "List.H"
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::label Foam::HashTable<T, Key, Hash>::canonicalSize(const label size)
|
||||
{
|
||||
if (size < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// enforce power of two
|
||||
unsigned int goodSize = size;
|
||||
|
||||
if (goodSize & (goodSize - 1))
|
||||
{
|
||||
// brute-force is fast enough
|
||||
goodSize = 1;
|
||||
while (goodSize < unsigned(size))
|
||||
{
|
||||
goodSize <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return goodSize;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::HashTable<T, Key, Hash>::HashTable(const label size)
|
||||
:
|
||||
HashTableName(),
|
||||
HashTableCore(),
|
||||
nElmts_(0),
|
||||
tableSize_(canonicalSize(size)),
|
||||
table_(NULL),
|
||||
endIter_(*this, NULL, 0),
|
||||
endConstIter_(*this, NULL, 0)
|
||||
tableSize_(HashTableCore::canonicalSize(size)),
|
||||
table_(NULL)
|
||||
{
|
||||
if (tableSize_)
|
||||
{
|
||||
|
@ -83,12 +54,10 @@ Foam::HashTable<T, Key, Hash>::HashTable(const label size)
|
|||
template<class T, class Key, class Hash>
|
||||
Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
|
||||
:
|
||||
HashTableName(),
|
||||
HashTableCore(),
|
||||
nElmts_(0),
|
||||
tableSize_(ht.tableSize_),
|
||||
table_(NULL),
|
||||
endIter_(*this, NULL, 0),
|
||||
endConstIter_(*this, NULL, 0)
|
||||
table_(NULL)
|
||||
{
|
||||
if (tableSize_)
|
||||
{
|
||||
|
@ -112,12 +81,10 @@ Foam::HashTable<T, Key, Hash>::HashTable
|
|||
const Xfer<HashTable<T, Key, Hash> >& ht
|
||||
)
|
||||
:
|
||||
HashTableName(),
|
||||
HashTableCore(),
|
||||
nElmts_(0),
|
||||
tableSize_(0),
|
||||
table_(NULL),
|
||||
endIter_(*this, NULL, 0),
|
||||
endConstIter_(*this, NULL, 0)
|
||||
table_(NULL)
|
||||
{
|
||||
transfer(ht());
|
||||
}
|
||||
|
@ -181,7 +148,7 @@ Foam::HashTable<T, Key, Hash>::find
|
|||
{
|
||||
if (key == ep->key_)
|
||||
{
|
||||
return iterator(*this, ep, hashIdx);
|
||||
return iterator(this, ep, hashIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +161,7 @@ Foam::HashTable<T, Key, Hash>::find
|
|||
}
|
||||
# endif
|
||||
|
||||
return end();
|
||||
return iterator();
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,7 +180,7 @@ Foam::HashTable<T, Key, Hash>::find
|
|||
{
|
||||
if (key == ep->key_)
|
||||
{
|
||||
return const_iterator(*this, ep, hashIdx);
|
||||
return const_iterator(this, ep, hashIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,23 +193,32 @@ Foam::HashTable<T, Key, Hash>::find
|
|||
}
|
||||
# endif
|
||||
|
||||
return cend();
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
|
||||
// Return the table of contents
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::List<Key> Foam::HashTable<T, Key, Hash>::toc() const
|
||||
{
|
||||
List<Key> tofc(nElmts_);
|
||||
label i = 0;
|
||||
List<Key> keys(nElmts_);
|
||||
label keyI = 0;
|
||||
|
||||
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
||||
{
|
||||
tofc[i++] = iter.key();
|
||||
keys[keyI++] = iter.key();
|
||||
}
|
||||
|
||||
return tofc;
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::List<Key> Foam::HashTable<T, Key, Hash>::sortedToc() const
|
||||
{
|
||||
List<Key> sortedLst = this->toc();
|
||||
sort(sortedLst);
|
||||
|
||||
return sortedLst;
|
||||
}
|
||||
|
||||
|
||||
|
@ -280,7 +256,7 @@ bool Foam::HashTable<T, Key, Hash>::set
|
|||
table_[hashIdx] = new hashedEntry(key, table_[hashIdx], newEntry);
|
||||
nElmts_++;
|
||||
|
||||
if (double(nElmts_)/tableSize_ > 0.8)
|
||||
if (double(nElmts_)/tableSize_ > 0.8 && tableSize_ < maxTableSize)
|
||||
{
|
||||
# ifdef FULLDEBUG
|
||||
if (debug)
|
||||
|
@ -332,18 +308,22 @@ bool Foam::HashTable<T, Key, Hash>::set
|
|||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::HashTable<T, Key, Hash>::erase(const iterator& cit)
|
||||
bool Foam::HashTable<T, Key, Hash>::iteratorBase::erase()
|
||||
{
|
||||
if (cit.elmtPtr_) // note: endIter_ also has 0 elmtPtr_
|
||||
// note: entryPtr_ is NULL for end(), so this catches that too
|
||||
if (entryPtr_)
|
||||
{
|
||||
iterator& it = const_cast<iterator&>(cit);
|
||||
|
||||
// Search element before elmtPtr_
|
||||
// Search element before entryPtr_
|
||||
hashedEntry* prev = 0;
|
||||
|
||||
for (hashedEntry* ep = table_[it.hashIndex_]; ep; ep = ep->next_)
|
||||
for
|
||||
(
|
||||
hashedEntry* ep = hashTable_->table_[hashIndex_];
|
||||
ep;
|
||||
ep = ep->next_
|
||||
)
|
||||
{
|
||||
if (ep == it.elmtPtr_)
|
||||
if (ep == entryPtr_)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -352,98 +332,76 @@ bool Foam::HashTable<T, Key, Hash>::erase(const iterator& cit)
|
|||
|
||||
if (prev)
|
||||
{
|
||||
// Have element before elmtPtr
|
||||
prev->next_ = it.elmtPtr_->next_;
|
||||
delete it.elmtPtr_;
|
||||
it.elmtPtr_ = prev;
|
||||
// has an element before entryPtr - reposition to there
|
||||
prev->next_ = entryPtr_->next_;
|
||||
delete entryPtr_;
|
||||
entryPtr_ = prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
// elmtPtr is first element on SLList
|
||||
table_[it.hashIndex_] = it.elmtPtr_->next_;
|
||||
delete it.elmtPtr_;
|
||||
// entryPtr was first element on SLList
|
||||
hashTable_->table_[hashIndex_] = entryPtr_->next_;
|
||||
delete entryPtr_;
|
||||
|
||||
// Search back for previous non-zero table entry
|
||||
while (--it.hashIndex_ >= 0 && !table_[it.hashIndex_])
|
||||
{}
|
||||
// assign any non-NULL pointer value so it doesn't look
|
||||
// like end()/cend()
|
||||
entryPtr_ = reinterpret_cast<hashedEntry*>(this);
|
||||
|
||||
if (it.hashIndex_ >= 0)
|
||||
{
|
||||
// In table entry search for last element
|
||||
it.elmtPtr_ = table_[it.hashIndex_];
|
||||
|
||||
while (it.elmtPtr_ && it.elmtPtr_->next_)
|
||||
{
|
||||
it.elmtPtr_ = it.elmtPtr_->next_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No previous found. Mark with special value which is
|
||||
// - not end()/cend()
|
||||
// - handled by operator++
|
||||
it.elmtPtr_ = reinterpret_cast<hashedEntry*>(this);
|
||||
it.hashIndex_ = -1;
|
||||
}
|
||||
// Mark with special hashIndex value to signal it has been rewound.
|
||||
// The next increment will bring it back to the present location.
|
||||
//
|
||||
// From the current position 'curPos', we wish to continue at
|
||||
// prevPos='curPos-1', which we mark as markPos='-curPos-1'.
|
||||
// The negative lets us notice it is special, the extra '-1'
|
||||
// is needed to avoid ambiguity for position '0'.
|
||||
// To retrieve prevPos, we would later use '-(markPos+1) - 1'
|
||||
hashIndex_ = -hashIndex_ - 1;
|
||||
}
|
||||
|
||||
nElmts_--;
|
||||
|
||||
# ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
Info<< "HashTable<T, Key, Hash>::erase(iterator&) : "
|
||||
<< "hashedEntry " << it.elmtPtr_->key_ << " removed.\n";
|
||||
}
|
||||
# endif
|
||||
hashTable_->nElmts_--;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
# ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
Info<< "HashTable<T, Key, Hash>::erase(iterator&) : "
|
||||
<< "cannot remove hashedEntry from hash table\n";
|
||||
}
|
||||
# endif
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// NOTE:
|
||||
// We use (const iterator&) here, but manipulate its contents anyhow.
|
||||
// The parameter should be (iterator&), but then the compiler doesn't find
|
||||
// it correctly and tries to call as (iterator) instead.
|
||||
//
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
|
||||
{
|
||||
// adjust iterator after erase
|
||||
return const_cast<iterator&>(iter).erase();
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
bool Foam::HashTable<T, Key, Hash>::erase(const Key& key)
|
||||
{
|
||||
iterator fnd = find(key);
|
||||
|
||||
if (fnd != end())
|
||||
{
|
||||
return erase(fnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return erase(find(key));
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::label Foam::HashTable<T, Key, Hash>::erase(const UList<Key>& keys)
|
||||
{
|
||||
const label nTotal = nElmts_;
|
||||
label count = 0;
|
||||
|
||||
// Remove listed keys from this table
|
||||
if (this->size())
|
||||
// Remove listed keys from this table - terminates early if possible
|
||||
for (label keyI = 0; count < nTotal && keyI < keys.size(); ++keyI)
|
||||
{
|
||||
forAll(keys, keyI)
|
||||
if (erase(keys[keyI]))
|
||||
{
|
||||
if (erase(keys[keyI]))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +435,7 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase
|
|||
template<class T, class Key, class Hash>
|
||||
void Foam::HashTable<T, Key, Hash>::resize(const label sz)
|
||||
{
|
||||
label newSize = canonicalSize(sz);
|
||||
label newSize = HashTableCore::canonicalSize(sz);
|
||||
|
||||
if (newSize == tableSize_)
|
||||
{
|
||||
|
@ -492,22 +450,22 @@ void Foam::HashTable<T, Key, Hash>::resize(const label sz)
|
|||
return;
|
||||
}
|
||||
|
||||
HashTable<T, Key, Hash>* newTable = new HashTable<T, Key, Hash>(newSize);
|
||||
HashTable<T, Key, Hash>* tmpTable = new HashTable<T, Key, Hash>(newSize);
|
||||
|
||||
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
||||
{
|
||||
newTable->insert(iter.key(), *iter);
|
||||
tmpTable->insert(iter.key(), *iter);
|
||||
}
|
||||
|
||||
label oldTableSize = tableSize_;
|
||||
tableSize_ = newTable->tableSize_;
|
||||
newTable->tableSize_ = oldTableSize;
|
||||
label oldSize = tableSize_;
|
||||
tableSize_ = tmpTable->tableSize_;
|
||||
tmpTable->tableSize_ = oldSize;
|
||||
|
||||
hashedEntry** oldTable = table_;
|
||||
table_ = newTable->table_;
|
||||
newTable->table_ = oldTable;
|
||||
table_ = tmpTable->table_;
|
||||
tmpTable->table_ = oldTable;
|
||||
|
||||
delete newTable;
|
||||
delete tmpTable;
|
||||
}
|
||||
|
||||
|
||||
|
@ -543,6 +501,19 @@ void Foam::HashTable<T, Key, Hash>::clearStorage()
|
|||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::HashTable<T, Key, Hash>::shrink()
|
||||
{
|
||||
const label newSize = HashTableCore::canonicalSize(nElmts_);
|
||||
|
||||
if (newSize < tableSize_)
|
||||
{
|
||||
// avoid having the table disappear on us
|
||||
resize(newSize ? newSize : 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::HashTable<T, Key, Hash>::transfer(HashTable<T, Key, Hash>& ht)
|
||||
{
|
||||
|
@ -606,18 +577,12 @@ bool Foam::HashTable<T, Key, Hash>::operator==
|
|||
const HashTable<T, Key, Hash>& rhs
|
||||
) const
|
||||
{
|
||||
// Are all my elements in rhs?
|
||||
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
||||
// sizes (number of keys) must match
|
||||
if (size() != rhs.size())
|
||||
{
|
||||
const_iterator fnd = rhs.find(iter.key());
|
||||
|
||||
if (fnd == rhs.cend() || fnd() != iter())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Are all rhs elements in me?
|
||||
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
|
||||
{
|
||||
const_iterator fnd = find(iter.key());
|
||||
|
@ -627,6 +592,7 @@ bool Foam::HashTable<T, Key, Hash>::operator==
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,23 +70,59 @@ Ostream& operator<<(Ostream&, const HashTable<T, Key, Hash>&);
|
|||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class HashTableName Declaration
|
||||
Class HashTableCore Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
TemplateName(HashTable);
|
||||
//- Template-invariant bits for HashTable
|
||||
struct HashTableCore
|
||||
{
|
||||
//- Return a canonical (power-of-two) size
|
||||
static label canonicalSize(const label);
|
||||
|
||||
//- Maximum allowable table size
|
||||
static const label maxTableSize;
|
||||
|
||||
//- Construct null
|
||||
HashTableCore()
|
||||
{}
|
||||
|
||||
//- Define template name and debug
|
||||
ClassName("HashTable");
|
||||
|
||||
//- A zero-sized end iterator
|
||||
struct iteratorEnd
|
||||
{
|
||||
//- Construct null
|
||||
iteratorEnd()
|
||||
{}
|
||||
};
|
||||
|
||||
//- iteratorEnd set to beyond the end of any HashTable
|
||||
inline static iteratorEnd cend()
|
||||
{
|
||||
return iteratorEnd();
|
||||
}
|
||||
|
||||
//- iteratorEnd set to beyond the end of any HashTable
|
||||
inline static iteratorEnd end()
|
||||
{
|
||||
return iteratorEnd();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class HashTable Declaration
|
||||
Class HashTable Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class T, class Key=word, class Hash=string::hash>
|
||||
class HashTable
|
||||
:
|
||||
public HashTableName
|
||||
public HashTableCore
|
||||
{
|
||||
// Private data type for table entries
|
||||
|
||||
//- Structure to hold a hashed entry with SLList for collisions
|
||||
struct hashedEntry
|
||||
{
|
||||
//- The lookup key
|
||||
|
@ -98,18 +134,17 @@ class HashTable
|
|||
//- The data object
|
||||
T obj_;
|
||||
|
||||
//- Constructors
|
||||
//- Construct from key, next pointer and object
|
||||
inline hashedEntry(const Key&, hashedEntry* next, const T&);
|
||||
|
||||
//- Construct given key, next pointer and object
|
||||
inline hashedEntry
|
||||
(
|
||||
const Key&,
|
||||
hashedEntry* next,
|
||||
const T& newEntry
|
||||
);
|
||||
|
||||
//- Dissallow construction as copy
|
||||
hashedEntry(const hashedEntry&);
|
||||
private:
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
hashedEntry(const hashedEntry&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const hashedEntry&);
|
||||
};
|
||||
|
||||
|
||||
|
@ -118,7 +153,7 @@ class HashTable
|
|||
//- The current number of elements in table
|
||||
label nElmts_;
|
||||
|
||||
//- Number of primary entries allocated in table (not necessarily used)
|
||||
//- Number of primary entries allocated in table
|
||||
label tableSize_;
|
||||
|
||||
//- The table of primary entries
|
||||
|
@ -137,27 +172,32 @@ class HashTable
|
|||
//- Assign a new hashedEntry to a possibly already existing key
|
||||
bool set(const Key&, const T& newElmt, bool protect);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Forward declaration of iterators
|
||||
|
||||
class iteratorBase;
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
|
||||
//- Declare friendship with the HashPtrTable class
|
||||
template<class T2, class Key2, class Hash2>
|
||||
friend class HashPtrTable;
|
||||
|
||||
//- Declare friendship with the iteratorBase
|
||||
friend class iteratorBase;
|
||||
|
||||
// Forward declaration of STL iterators
|
||||
|
||||
class iterator;
|
||||
//- Declare friendship with the iterator
|
||||
friend class iterator;
|
||||
|
||||
class const_iterator;
|
||||
//- Declare friendship with the const_iterator
|
||||
friend class const_iterator;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct given initial table size
|
||||
HashTable(const label size = 128);
|
||||
explicit HashTable(const label size = 128);
|
||||
|
||||
//- Construct from Istream
|
||||
HashTable(Istream&, const label size = 128);
|
||||
|
@ -169,16 +209,18 @@ public:
|
|||
HashTable(const Xfer<HashTable<T, Key, Hash> >&);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
~HashTable();
|
||||
//- Destructor
|
||||
~HashTable();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return number of elements in table.
|
||||
//- The size of the underlying table
|
||||
inline label capacity() const;
|
||||
|
||||
//- Return number of elements in table
|
||||
inline label size() const;
|
||||
|
||||
//- Return true if the hash table is empty
|
||||
|
@ -198,9 +240,13 @@ public:
|
|||
//- Return the table of contents
|
||||
List<Key> toc() const;
|
||||
|
||||
//- Return the table of contents as a sorted list
|
||||
List<Key> sortedToc() const;
|
||||
|
||||
//- Print information
|
||||
Ostream& printInfo(Ostream&) const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Insert a new hashedEntry
|
||||
|
@ -209,10 +255,11 @@ public:
|
|||
//- Assign a new hashedEntry, overwriting existing entries
|
||||
inline bool set(const Key&, const T& newElmt);
|
||||
|
||||
//- Erase an hashedEntry specified by given iterator
|
||||
//- Erase a hashedEntry specified by given iterator
|
||||
// This invalidates the iterator until the next operator++
|
||||
bool erase(const iterator&);
|
||||
|
||||
//- Erase an hashedEntry specified by given key if in table
|
||||
//- Erase a hashedEntry specified by the given key
|
||||
bool erase(const Key&);
|
||||
|
||||
//- Remove entries given by the listed keys from this HashTable
|
||||
|
@ -236,8 +283,11 @@ public:
|
|||
// Equivalent to clear() followed by resize(0)
|
||||
void clearStorage();
|
||||
|
||||
//- Shrink the allocated table to approx. twice number of elements
|
||||
void shrink();
|
||||
|
||||
//- Transfer the contents of the argument table into this table
|
||||
// and annull the argument table.
|
||||
// and annul the argument table.
|
||||
void transfer(HashTable<T, Key, Hash>&);
|
||||
|
||||
//- Transfer contents to the Xfer container
|
||||
|
@ -246,27 +296,27 @@ public:
|
|||
|
||||
// Member Operators
|
||||
|
||||
//- Find and return an hashedEntry
|
||||
//- Find and return a hashedEntry
|
||||
inline T& operator[](const Key&);
|
||||
|
||||
//- Find and return an hashedEntry
|
||||
//- Find and return a hashedEntry
|
||||
inline const T& operator[](const Key&) const;
|
||||
|
||||
//- Find and return an hashedEntry, create it null if not present.
|
||||
//- Find and return a hashedEntry, create it null if not present
|
||||
inline T& operator()(const Key&);
|
||||
|
||||
//- Assignment
|
||||
void operator=(const HashTable<T, Key, Hash>&);
|
||||
|
||||
//- Equality. Two hash tables are equal if all contents of first are
|
||||
// also in second and vice versa. So does not depend on table size or
|
||||
// order!
|
||||
//- Equality. Hash tables are equal if the keys and values are equal.
|
||||
// Independent of table storage size and table order.
|
||||
bool operator==(const HashTable<T, Key, Hash>&) const;
|
||||
|
||||
//- The opposite of the equality operation. Takes linear time.
|
||||
bool operator!=(const HashTable<T, Key, Hash>&) const;
|
||||
|
||||
|
||||
|
||||
// STL type definitions
|
||||
|
||||
//- Type of values the HashTable contains.
|
||||
|
@ -285,138 +335,198 @@ public:
|
|||
typedef label size_type;
|
||||
|
||||
|
||||
// STL iterator
|
||||
// Iterators and helpers
|
||||
|
||||
//- An STL-conforming iterator
|
||||
class iterator
|
||||
//- The iterator base for HashTable
|
||||
// Note: data and functions are protected, to allow reuse by iterator
|
||||
// and prevent most external usage.
|
||||
// iterator and const_iterator have the same size, allowing
|
||||
// us to reinterpret_cast between them (if desired)
|
||||
class iteratorBase
|
||||
{
|
||||
friend class HashTable;
|
||||
friend class const_iterator;
|
||||
// Private Data
|
||||
|
||||
// Private data
|
||||
|
||||
//- Reference to the HashTable this is an iterator for
|
||||
HashTable<T, Key, Hash>& hashTable_;
|
||||
//- Pointer to the HashTable for which this is an iterator
|
||||
// This also lets us use the default bitwise copy/assignment
|
||||
HashTable<T, Key, Hash>* hashTable_;
|
||||
|
||||
//- Current element
|
||||
hashedEntry* elmtPtr_;
|
||||
hashedEntry* entryPtr_;
|
||||
|
||||
//- Current hash index
|
||||
label hashIndex_;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null - equivalent to an 'end' position
|
||||
inline iteratorBase();
|
||||
|
||||
//- Construct from hash table, moving to its 'begin' position
|
||||
inline explicit iteratorBase
|
||||
(
|
||||
const HashTable<T, Key, Hash>* curHashTable
|
||||
);
|
||||
|
||||
//- Construct from hash table, element and hash index
|
||||
inline explicit iteratorBase
|
||||
(
|
||||
const HashTable<T, Key, Hash>* curHashTable,
|
||||
const hashedEntry* elmt,
|
||||
const label hashIndex
|
||||
);
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Increment to the next position
|
||||
inline void increment();
|
||||
|
||||
//- Erase the HashTable element at the current position
|
||||
bool erase();
|
||||
|
||||
//- Return non-const access to referenced object
|
||||
inline T& object();
|
||||
|
||||
//- Return const access to referenced object
|
||||
inline const T& cobject() const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Member operators
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the Key corresponding to the iterator
|
||||
inline const Key& key() const;
|
||||
|
||||
//- Compare hashedEntry element pointers
|
||||
inline bool operator==(const iteratorBase&) const;
|
||||
inline bool operator!=(const iteratorBase&) const;
|
||||
|
||||
//- Compare hashedEntry to iteratorEnd pointers
|
||||
inline bool operator==(const iteratorEnd& unused) const;
|
||||
inline bool operator!=(const iteratorEnd& unused) const;
|
||||
};
|
||||
|
||||
|
||||
//- An STL-conforming iterator
|
||||
class iterator
|
||||
:
|
||||
public iteratorBase
|
||||
{
|
||||
friend class HashTable;
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Construct from hash table, moving to its 'begin' position
|
||||
inline explicit iterator
|
||||
(
|
||||
HashTable<T, Key, Hash>* curHashTable
|
||||
);
|
||||
|
||||
//- Construct from hash table, element and hash index
|
||||
inline explicit iterator
|
||||
(
|
||||
HashTable<T, Key, Hash>* curHashTable,
|
||||
hashedEntry* elmt,
|
||||
const label hashIndex
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from hash table, element and hash index
|
||||
inline iterator
|
||||
(
|
||||
HashTable<T, Key, Hash>& curHashTable,
|
||||
hashedEntry* elmt,
|
||||
label hashIndex
|
||||
);
|
||||
//- Construct null (end iterator)
|
||||
inline iterator();
|
||||
|
||||
//- Construct end iterator
|
||||
inline iterator(const iteratorEnd& unused);
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
inline void operator=(const iterator&);
|
||||
|
||||
inline bool operator==(const iterator&) const;
|
||||
inline bool operator!=(const iterator&) const;
|
||||
|
||||
inline bool operator==(const const_iterator&) const;
|
||||
inline bool operator!=(const const_iterator&) const;
|
||||
|
||||
//- Return referenced hash value
|
||||
inline T& operator*();
|
||||
inline T& operator()();
|
||||
|
||||
//- Return referenced hash value
|
||||
inline const T& operator*() const;
|
||||
inline const T& operator()() const;
|
||||
|
||||
inline iterator& operator++();
|
||||
inline iterator operator++(int);
|
||||
|
||||
inline const Key& key() const;
|
||||
};
|
||||
|
||||
|
||||
//- iterator set to the begining of the HashTable
|
||||
//- iterator set to the beginning of the HashTable
|
||||
inline iterator begin();
|
||||
|
||||
//- iterator set to beyond the end of the HashTable
|
||||
inline const iterator& end();
|
||||
|
||||
|
||||
// STL const_iterator
|
||||
|
||||
//- An STL-conforming const_iterator
|
||||
class const_iterator
|
||||
:
|
||||
public iteratorBase
|
||||
{
|
||||
friend class iterator;
|
||||
friend class HashTable;
|
||||
|
||||
// Private data
|
||||
// Private Member Functions
|
||||
|
||||
//- Reference to the HashTable this is an iterator for
|
||||
const HashTable<T, Key, Hash>& hashTable_;
|
||||
//- Construct from hash table, moving to its 'begin' position
|
||||
inline explicit const_iterator
|
||||
(
|
||||
const HashTable<T, Key, Hash>* curHashTable
|
||||
);
|
||||
|
||||
//- Current element
|
||||
const hashedEntry* elmtPtr_;
|
||||
|
||||
//- Current hash index
|
||||
label hashIndex_;
|
||||
//- Construct from hash table, element and hash index
|
||||
inline explicit const_iterator
|
||||
(
|
||||
const HashTable<T, Key, Hash>* curHashTable,
|
||||
const hashedEntry* elmt,
|
||||
const label hashIndex
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from hash table, element and hash index
|
||||
inline const_iterator
|
||||
(
|
||||
const HashTable<T, Key, Hash>& curHashTable,
|
||||
const hashedEntry* elmt,
|
||||
label hashIndex
|
||||
);
|
||||
//- Construct null (end iterator)
|
||||
inline const_iterator();
|
||||
|
||||
//- Construct from the non-const iterator
|
||||
//- Construct from iterator
|
||||
inline const_iterator(const iterator&);
|
||||
|
||||
//- Construct end iterator
|
||||
inline const_iterator(const iteratorEnd& unused);
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
inline void operator=(const const_iterator&);
|
||||
|
||||
inline bool operator==(const const_iterator&) const;
|
||||
inline bool operator!=(const const_iterator&) const;
|
||||
|
||||
inline bool operator==(const iterator&) const;
|
||||
inline bool operator!=(const iterator&) const;
|
||||
|
||||
//- Return referenced hash value
|
||||
inline const T& operator*() const;
|
||||
inline const T& operator()() const;
|
||||
|
||||
inline const_iterator& operator++();
|
||||
inline const_iterator operator++(int);
|
||||
|
||||
inline const Key& key() const;
|
||||
};
|
||||
|
||||
|
||||
//- const_iterator set to the beginning of the HashTable
|
||||
inline const_iterator cbegin() const;
|
||||
|
||||
//- const_iterator set to beyond the end of the HashTable
|
||||
inline const const_iterator& cend() const;
|
||||
|
||||
//- const_iterator set to the beginning of the HashTable
|
||||
inline const_iterator begin() const;
|
||||
|
||||
//- const_iterator set to beyond the end of the HashTable
|
||||
inline const const_iterator& end() const;
|
||||
|
||||
|
||||
// IOstream Operator
|
||||
|
||||
#ifndef SWIG
|
||||
friend Istream& operator>> <T, Key, Hash>
|
||||
(
|
||||
Istream&,
|
||||
|
@ -428,16 +538,6 @@ public:
|
|||
Ostream&,
|
||||
const HashTable<T, Key, Hash>&
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//- iterator returned by end()
|
||||
iterator endIter_;
|
||||
|
||||
//- const_iterator returned by end()
|
||||
const_iterator endConstIter_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -24,9 +24,48 @@ License
|
|||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "HashTable.H"
|
||||
#include "uLabel.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(Foam::HashTableName, 0);
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(HashTableCore, 0);
|
||||
}
|
||||
|
||||
const Foam::label Foam::HashTableCore::maxTableSize
|
||||
(
|
||||
Foam::HashTableCore::canonicalSize
|
||||
(
|
||||
Foam::labelMax/2
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::HashTableCore::canonicalSize(const label size)
|
||||
{
|
||||
if (size < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// enforce power of two
|
||||
uLabel goodSize = size;
|
||||
|
||||
if (goodSize & (goodSize - 1))
|
||||
{
|
||||
// brute-force is fast enough
|
||||
goodSize = 1;
|
||||
while (goodSize < unsigned(size))
|
||||
{
|
||||
goodSize <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return goodSize;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -32,12 +32,12 @@ inline Foam::HashTable<T, Key, Hash>::hashedEntry::hashedEntry
|
|||
(
|
||||
const Key& key,
|
||||
hashedEntry* next,
|
||||
const T& newEntry
|
||||
const T& obj
|
||||
)
|
||||
:
|
||||
key_(key),
|
||||
next_(next),
|
||||
obj_(newEntry)
|
||||
obj_(obj)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -54,6 +54,13 @@ Foam::HashTable<T, Key, Hash>::hashKeyIndex(const Key& key) const
|
|||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::label Foam::HashTable<T, Key, Hash>::capacity() const
|
||||
{
|
||||
return tableSize_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::label Foam::HashTable<T, Key, Hash>::size() const
|
||||
{
|
||||
|
@ -75,7 +82,7 @@ inline bool Foam::HashTable<T, Key, Hash>::insert
|
|||
const T& newEntry
|
||||
)
|
||||
{
|
||||
return set(key, newEntry, true);
|
||||
return this->set(key, newEntry, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,7 +93,7 @@ inline bool Foam::HashTable<T, Key, Hash>::set
|
|||
const T& newEntry
|
||||
)
|
||||
{
|
||||
return set(key, newEntry, false);
|
||||
return this->set(key, newEntry, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,9 +110,9 @@ Foam::HashTable<T, Key, Hash>::xfer()
|
|||
template<class T, class Key, class Hash>
|
||||
inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
|
||||
{
|
||||
iterator iter = find(key);
|
||||
iterator iter = this->find(key);
|
||||
|
||||
if (iter == end())
|
||||
if (iter == this->end())
|
||||
{
|
||||
FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&)")
|
||||
<< key << " not found in table. Valid entries: "
|
||||
|
@ -120,9 +127,9 @@ inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
|
|||
template<class T, class Key, class Hash>
|
||||
inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
|
||||
{
|
||||
const_iterator iter = find(key);
|
||||
const_iterator iter = this->find(key);
|
||||
|
||||
if (iter == cend())
|
||||
if (iter == this->cend())
|
||||
{
|
||||
FatalErrorIn("HashTable<T, Key, Hash>::operator[](const Key&) const")
|
||||
<< key << " not found in table. Valid entries: "
|
||||
|
@ -137,11 +144,11 @@ inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
|
|||
template<class T, class Key, class Hash>
|
||||
inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
|
||||
{
|
||||
iterator iter = find(key);
|
||||
iterator iter = this->find(key);
|
||||
|
||||
if (iter == end())
|
||||
if (iter == this->end())
|
||||
{
|
||||
insert(key, T());
|
||||
this->insert(key, T());
|
||||
return *find(key);
|
||||
}
|
||||
else
|
||||
|
@ -151,78 +158,215 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
|
|||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
|
||||
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase()
|
||||
:
|
||||
hashTable_(0),
|
||||
entryPtr_(0),
|
||||
hashIndex_(0)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
|
||||
(
|
||||
HashTable<T, Key, Hash>& hashTbl,
|
||||
hashedEntry* elmt,
|
||||
label hashIndex
|
||||
const HashTable<T, Key, Hash>* hashTbl
|
||||
)
|
||||
:
|
||||
hashTable_(hashTbl),
|
||||
elmtPtr_(elmt),
|
||||
hashTable_(const_cast<HashTable<T, Key, Hash>*>(hashTbl)),
|
||||
entryPtr_(0),
|
||||
hashIndex_(0)
|
||||
{
|
||||
if (hashTable_->nElmts_)
|
||||
{
|
||||
// find first non-NULL table entry
|
||||
while
|
||||
(
|
||||
!(entryPtr_ = hashTable_->table_[hashIndex_])
|
||||
&& ++hashIndex_ < hashTable_->tableSize_
|
||||
)
|
||||
{}
|
||||
|
||||
if (hashIndex_ >= hashTable_->tableSize_)
|
||||
{
|
||||
// make into an end iterator
|
||||
entryPtr_ = 0;
|
||||
hashIndex_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
|
||||
(
|
||||
const HashTable<T, Key, Hash>* hashTbl,
|
||||
const hashedEntry* elmt,
|
||||
const label hashIndex
|
||||
)
|
||||
:
|
||||
hashTable_(const_cast<HashTable<T, Key, Hash>*>(hashTbl)),
|
||||
entryPtr_(const_cast<hashedEntry*>(elmt)),
|
||||
hashIndex_(hashIndex)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline void Foam::HashTable<T, Key, Hash>::iterator::operator=
|
||||
inline void
|
||||
Foam::HashTable<T, Key, Hash>::iteratorBase::increment()
|
||||
{
|
||||
// A negative index is a special value from erase
|
||||
if (hashIndex_ < 0)
|
||||
{
|
||||
// the markPos='-curPos-1', but we wish to continue at 'curPos-1'
|
||||
// thus use '-(markPos+1) -1'
|
||||
hashIndex_ = -(hashIndex_+1) - 1;
|
||||
}
|
||||
else if (entryPtr_)
|
||||
{
|
||||
if (entryPtr_->next_)
|
||||
{
|
||||
// Move to next element on the SLList
|
||||
entryPtr_ = entryPtr_->next_;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// // if we reach here (entryPtr_ is NULL) it is already at the end()
|
||||
// // we should probably stop
|
||||
// }
|
||||
|
||||
|
||||
// Step to the next table entry
|
||||
while
|
||||
(
|
||||
++hashIndex_ < hashTable_->tableSize_
|
||||
&& !(entryPtr_ = hashTable_->table_[hashIndex_])
|
||||
)
|
||||
{}
|
||||
|
||||
if (hashIndex_ >= hashTable_->tableSize_)
|
||||
{
|
||||
// make into an end iterator
|
||||
entryPtr_ = 0;
|
||||
hashIndex_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline
|
||||
const Key& Foam::HashTable<T, Key, Hash>::iteratorBase::key() const
|
||||
{
|
||||
return entryPtr_->key_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline T&
|
||||
Foam::HashTable<T, Key, Hash>::iteratorBase::object()
|
||||
{
|
||||
return entryPtr_->obj_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline const T&
|
||||
Foam::HashTable<T, Key, Hash>::iteratorBase::cobject() const
|
||||
{
|
||||
return entryPtr_->obj_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator==
|
||||
(
|
||||
const iterator& iter
|
||||
const iteratorBase& iter
|
||||
) const
|
||||
{
|
||||
return entryPtr_ == iter.entryPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator!=
|
||||
(
|
||||
const iteratorBase& iter
|
||||
) const
|
||||
{
|
||||
return entryPtr_ != iter.entryPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator==
|
||||
(
|
||||
const iteratorEnd&
|
||||
) const
|
||||
{
|
||||
return !entryPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator!=
|
||||
(
|
||||
const iteratorEnd&
|
||||
) const
|
||||
{
|
||||
return entryPtr_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::iterator::iterator()
|
||||
:
|
||||
iteratorBase()
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
|
||||
(
|
||||
const iteratorEnd&
|
||||
)
|
||||
{
|
||||
elmtPtr_ = iter.elmtPtr_;
|
||||
hashIndex_ = iter.hashIndex_;
|
||||
}
|
||||
:
|
||||
iteratorBase()
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
|
||||
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
|
||||
(
|
||||
const iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ == iter.elmtPtr_;
|
||||
}
|
||||
HashTable<T, Key, Hash>* hashTbl
|
||||
)
|
||||
:
|
||||
iteratorBase(hashTbl)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
|
||||
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
|
||||
(
|
||||
const iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ != iter.elmtPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator==
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ == iter.elmtPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::iterator::operator!=
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ != iter.elmtPtr_;
|
||||
}
|
||||
HashTable<T, Key, Hash>* hashTbl,
|
||||
hashedEntry* elmt,
|
||||
const label hashIndex
|
||||
)
|
||||
:
|
||||
iteratorBase(hashTbl, elmt, hashIndex)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline T&
|
||||
Foam::HashTable<T, Key, Hash>::iterator::operator*()
|
||||
{
|
||||
return elmtPtr_->obj_;
|
||||
return this->object();
|
||||
}
|
||||
|
||||
|
||||
|
@ -230,7 +374,7 @@ template<class T, class Key, class Hash>
|
|||
inline T&
|
||||
Foam::HashTable<T, Key, Hash>::iterator::operator()()
|
||||
{
|
||||
return elmtPtr_->obj_;
|
||||
return this->object();
|
||||
}
|
||||
|
||||
|
||||
|
@ -238,7 +382,7 @@ template<class T, class Key, class Hash>
|
|||
inline const T&
|
||||
Foam::HashTable<T, Key, Hash>::iterator::operator*() const
|
||||
{
|
||||
return elmtPtr_->obj_;
|
||||
return this->cobject();
|
||||
}
|
||||
|
||||
|
||||
|
@ -246,7 +390,7 @@ template<class T, class Key, class Hash>
|
|||
inline const T&
|
||||
Foam::HashTable<T, Key, Hash>::iterator::operator()() const
|
||||
{
|
||||
return elmtPtr_->obj_;
|
||||
return this->cobject();
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,53 +399,18 @@ inline
|
|||
typename Foam::HashTable<T, Key, Hash>::iterator&
|
||||
Foam::HashTable<T, Key, Hash>::iterator::operator++()
|
||||
{
|
||||
// Check for special value from erase. (sets hashIndex to -1)
|
||||
if (hashIndex_ >= 0)
|
||||
{
|
||||
// Do we have additional elements on the SLList?
|
||||
if (elmtPtr_ && elmtPtr_->next_)
|
||||
{
|
||||
elmtPtr_ = elmtPtr_->next_;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
// Step to the next table entry
|
||||
while
|
||||
(
|
||||
++hashIndex_ < hashTable_.tableSize_
|
||||
&& !(elmtPtr_ = hashTable_.table_[hashIndex_])
|
||||
)
|
||||
{}
|
||||
|
||||
if (hashIndex_ == hashTable_.tableSize_)
|
||||
{
|
||||
// make end iterator
|
||||
elmtPtr_ = 0;
|
||||
hashIndex_ = 0;
|
||||
}
|
||||
this->increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline typename Foam::HashTable<T, Key, Hash>::iterator
|
||||
Foam::HashTable<T, Key, Hash>::iterator::operator++
|
||||
(
|
||||
int
|
||||
)
|
||||
Foam::HashTable<T, Key, Hash>::iterator::operator++(int)
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline
|
||||
const Key& Foam::HashTable<T, Key, Hash>::iterator::key() const
|
||||
{
|
||||
return elmtPtr_->key_;
|
||||
iterator old = *this;
|
||||
this->increment();
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
|
@ -309,135 +418,74 @@ template<class T, class Key, class Hash>
|
|||
inline typename Foam::HashTable<T, Key, Hash>::iterator
|
||||
Foam::HashTable<T, Key, Hash>::begin()
|
||||
{
|
||||
label i = 0;
|
||||
|
||||
if (nElmts_)
|
||||
{
|
||||
while (table_ && !table_[i] && ++i < tableSize_)
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = tableSize_;
|
||||
}
|
||||
|
||||
if (i == tableSize_)
|
||||
{
|
||||
# ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
Info<< "HashTable is empty\n";
|
||||
}
|
||||
# endif
|
||||
|
||||
return HashTable<T, Key, Hash>::endIter_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return iterator(*this, table_[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline const typename Foam::HashTable<T, Key, Hash>::iterator&
|
||||
Foam::HashTable<T, Key, Hash>::end()
|
||||
{
|
||||
return HashTable<T, Key, Hash>::endIter_;
|
||||
return iterator(this);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator()
|
||||
:
|
||||
iteratorBase()
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
||||
(
|
||||
const HashTable<T, Key, Hash>& hashTbl,
|
||||
const HashTable<T, Key, Hash>::iterator& iter
|
||||
)
|
||||
:
|
||||
iteratorBase(iter)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
||||
(
|
||||
const iteratorEnd&
|
||||
)
|
||||
:
|
||||
iteratorBase()
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
||||
(
|
||||
const HashTable<T, Key, Hash>* hashTbl
|
||||
)
|
||||
:
|
||||
iteratorBase(hashTbl)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
||||
(
|
||||
const HashTable<T, Key, Hash>* hashTbl,
|
||||
const hashedEntry* elmt,
|
||||
label hashIndex
|
||||
const label hashIndex
|
||||
)
|
||||
:
|
||||
hashTable_(hashTbl),
|
||||
elmtPtr_(elmt),
|
||||
hashIndex_(hashIndex)
|
||||
iteratorBase(hashTbl, elmt, hashIndex)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
|
||||
(
|
||||
const iterator& iter
|
||||
)
|
||||
:
|
||||
hashTable_(iter.hashTable_),
|
||||
elmtPtr_(iter.elmtPtr_),
|
||||
hashIndex_(iter.hashIndex_)
|
||||
{}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline void Foam::HashTable<T, Key, Hash>::const_iterator::operator=
|
||||
(
|
||||
const const_iterator& iter
|
||||
)
|
||||
{
|
||||
elmtPtr_ = iter.elmtPtr_;
|
||||
hashIndex_ = iter.hashIndex_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ == iter.elmtPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ != iter.elmtPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator==
|
||||
(
|
||||
const iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ == iter.elmtPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline bool Foam::HashTable<T, Key, Hash>::const_iterator::operator!=
|
||||
(
|
||||
const iterator& iter
|
||||
) const
|
||||
{
|
||||
return elmtPtr_ != iter.elmtPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline const T&
|
||||
Foam::HashTable<T, Key, Hash>::const_iterator::operator*() const
|
||||
{
|
||||
return elmtPtr_->obj_;
|
||||
return this->cobject();
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline const T&
|
||||
Foam::HashTable<T, Key, Hash>::const_iterator::operator()() const
|
||||
{
|
||||
return elmtPtr_->obj_;
|
||||
return this->cobject();
|
||||
}
|
||||
|
||||
|
||||
|
@ -446,43 +494,18 @@ inline
|
|||
typename Foam::HashTable<T, Key, Hash>::const_iterator&
|
||||
Foam::HashTable<T, Key, Hash>::const_iterator::operator++()
|
||||
{
|
||||
if
|
||||
(
|
||||
!(elmtPtr_ = elmtPtr_->next_)
|
||||
&& ++hashIndex_ < hashTable_.tableSize_
|
||||
&& !(elmtPtr_ = hashTable_.table_[hashIndex_])
|
||||
)
|
||||
{
|
||||
while
|
||||
(
|
||||
++hashIndex_ < hashTable_.tableSize_
|
||||
&& !(elmtPtr_ = hashTable_.table_[hashIndex_])
|
||||
)
|
||||
{}
|
||||
}
|
||||
|
||||
this->increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
|
||||
Foam::HashTable<T, Key, Hash>::const_iterator::operator++
|
||||
(
|
||||
int
|
||||
)
|
||||
Foam::HashTable<T, Key, Hash>::const_iterator::operator++(int)
|
||||
{
|
||||
const_iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline
|
||||
const Key& Foam::HashTable<T, Key, Hash>::const_iterator::key() const
|
||||
{
|
||||
return elmtPtr_->key_;
|
||||
const_iterator old = *this;
|
||||
this->increment();
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
|
@ -490,41 +513,7 @@ template<class T, class Key, class Hash>
|
|||
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
|
||||
Foam::HashTable<T, Key, Hash>::cbegin() const
|
||||
{
|
||||
label i = 0;
|
||||
|
||||
if (nElmts_)
|
||||
{
|
||||
while (table_ && !table_[i] && ++i < tableSize_)
|
||||
{}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = tableSize_;
|
||||
}
|
||||
|
||||
if (i == tableSize_)
|
||||
{
|
||||
# ifdef FULLDEBUG
|
||||
if (debug)
|
||||
{
|
||||
Info<< "HashTable is empty\n";
|
||||
}
|
||||
# endif
|
||||
|
||||
return HashTable<T, Key, Hash>::endConstIter_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return const_iterator(*this, table_[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
|
||||
Foam::HashTable<T, Key, Hash>::cend() const
|
||||
{
|
||||
return HashTable<T, Key, Hash>::endConstIter_;
|
||||
return const_iterator(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -536,12 +525,4 @@ Foam::HashTable<T, Key, Hash>::begin() const
|
|||
}
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
|
||||
Foam::HashTable<T, Key, Hash>::end() const
|
||||
{
|
||||
return HashTable<T, Key, Hash>::endConstIter_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
|
|
@ -32,16 +32,19 @@ License
|
|||
template<class T, class Key, class Hash>
|
||||
Foam::HashTable<T, Key, Hash>::HashTable(Istream& is, const label size)
|
||||
:
|
||||
HashTableName(),
|
||||
HashTableCore(),
|
||||
nElmts_(0),
|
||||
tableSize_(canonicalSize(size)),
|
||||
table_(new hashedEntry*[tableSize_]),
|
||||
endIter_(*this, NULL, 0),
|
||||
endConstIter_(*this, NULL, 0)
|
||||
tableSize_(HashTableCore::canonicalSize(size)),
|
||||
table_(NULL)
|
||||
{
|
||||
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
|
||||
if (tableSize_)
|
||||
{
|
||||
table_[hashIdx] = 0;
|
||||
table_ = new hashedEntry*[tableSize_];
|
||||
|
||||
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
|
||||
{
|
||||
table_[hashIdx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
operator>>(is, *this);
|
||||
|
|
|
@ -32,8 +32,7 @@ License
|
|||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::label Foam::StaticHashTable<T, Key, Hash>::canonicalSize(const label size)
|
||||
Foam::label Foam::StaticHashTableCore::canonicalSize(const label size)
|
||||
{
|
||||
if (size < 1)
|
||||
{
|
||||
|
@ -63,8 +62,8 @@ Foam::label Foam::StaticHashTable<T, Key, Hash>::canonicalSize(const label size)
|
|||
template<class T, class Key, class Hash>
|
||||
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable(const label size)
|
||||
:
|
||||
StaticHashTableName(),
|
||||
keys_(canonicalSize(size)),
|
||||
StaticHashTableCore(),
|
||||
keys_(StaticHashTableCore::canonicalSize(size)),
|
||||
objects_(keys_.size()),
|
||||
nElmts_(0),
|
||||
endIter_(*this, keys_.size(), 0),
|
||||
|
@ -88,7 +87,7 @@ Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
|
|||
const StaticHashTable<T, Key, Hash>& ht
|
||||
)
|
||||
:
|
||||
StaticHashTableName(),
|
||||
StaticHashTableCore(),
|
||||
keys_(ht.keys_),
|
||||
objects_(ht.objects_),
|
||||
nElmts_(ht.nElmts_),
|
||||
|
@ -97,14 +96,13 @@ Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
|
|||
{}
|
||||
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
|
||||
(
|
||||
const Xfer< StaticHashTable<T, Key, Hash> >& ht
|
||||
const Xfer<StaticHashTable<T, Key, Hash> >& ht
|
||||
)
|
||||
:
|
||||
StaticHashTableName(),
|
||||
StaticHashTableCore(),
|
||||
keys_(0),
|
||||
objects_(0),
|
||||
nElmts_(0),
|
||||
|
@ -223,15 +221,15 @@ Foam::StaticHashTable<T, Key, Hash>::find
|
|||
template<class T, class Key, class Hash>
|
||||
Foam::List<Key> Foam::StaticHashTable<T, Key, Hash>::toc() const
|
||||
{
|
||||
List<Key> tofc(nElmts_);
|
||||
label i = 0;
|
||||
List<Key> keys(nElmts_);
|
||||
label keyI = 0;
|
||||
|
||||
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
||||
{
|
||||
tofc[i++] = iter.key();
|
||||
keys[keyI++] = iter.key();
|
||||
}
|
||||
|
||||
return tofc;
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,24 +316,9 @@ bool Foam::StaticHashTable<T, Key, Hash>::erase(const iterator& cit)
|
|||
if (it.elemIndex_ < 0)
|
||||
{
|
||||
// No previous element in the local list
|
||||
|
||||
// Search back for previous non-zero table entry
|
||||
while (--it.hashIndex_ >= 0 && !objects_[it.hashIndex_].size())
|
||||
{}
|
||||
|
||||
if (it.hashIndex_ >= 0)
|
||||
{
|
||||
// The last element in the local list
|
||||
it.elemIndex_ = objects_[it.hashIndex_].size() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No previous found. Mark with special value which is
|
||||
// - not end()
|
||||
// - handled by operator++
|
||||
it.hashIndex_ = -1;
|
||||
it.elemIndex_ = 0;
|
||||
}
|
||||
// Mark with as special value (see notes in HashTable)
|
||||
it.hashIndex_ = -it.hashIndex_ - 1;
|
||||
it.elemIndex_ = 0;
|
||||
}
|
||||
|
||||
nElmts_--;
|
||||
|
@ -406,7 +389,7 @@ Foam::label Foam::StaticHashTable<T, Key, Hash>::erase
|
|||
template<class T, class Key, class Hash>
|
||||
void Foam::StaticHashTable<T, Key, Hash>::resize(const label sz)
|
||||
{
|
||||
label newSize = canonicalSize(sz);
|
||||
label newSize = StaticHashTableCore::canonicalSize(sz);
|
||||
|
||||
if (newSize == keys_.size())
|
||||
{
|
||||
|
@ -467,7 +450,6 @@ void Foam::StaticHashTable<T, Key, Hash>::clearStorage()
|
|||
}
|
||||
|
||||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
void Foam::StaticHashTable<T, Key, Hash>::transfer
|
||||
(
|
||||
|
@ -542,18 +524,8 @@ bool Foam::StaticHashTable<T, Key, Hash>::operator==
|
|||
const StaticHashTable<T, Key, Hash>& rhs
|
||||
) const
|
||||
{
|
||||
// Are all my elements in rhs?
|
||||
for (const_iterator iter = cbegin(); iter != cend(); ++iter)
|
||||
{
|
||||
const_iterator fnd = rhs.find(iter.key());
|
||||
// sizes (number of keys) must match
|
||||
|
||||
if (fnd == rhs.cend() || fnd() != iter())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Are all rhs elements in me?
|
||||
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
|
||||
{
|
||||
const_iterator fnd = find(iter.key());
|
||||
|
@ -563,6 +535,7 @@ bool Foam::StaticHashTable<T, Key, Hash>::operator==
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,10 +72,31 @@ template<class T, class Key, class Hash> Ostream& operator<<
|
|||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class StaticHashTableName Declaration
|
||||
Class StaticHashTableCore Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
TemplateName(StaticHashTable);
|
||||
//- Template-invariant bits for StaticHashTable
|
||||
struct StaticHashTableCore
|
||||
{
|
||||
//- Return a canonical (power-of-two) size
|
||||
static label canonicalSize(const label);
|
||||
|
||||
//- Construct null
|
||||
StaticHashTableCore()
|
||||
{}
|
||||
|
||||
//- Define template name and debug
|
||||
ClassName("StaticHashTable");
|
||||
|
||||
//- A zero-sized end iterator
|
||||
struct iteratorEnd
|
||||
{
|
||||
//- Construct null
|
||||
iteratorEnd()
|
||||
{}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
|
@ -85,7 +106,7 @@ TemplateName(StaticHashTable);
|
|||
template<class T, class Key=word, class Hash=string::hash>
|
||||
class StaticHashTable
|
||||
:
|
||||
public StaticHashTableName
|
||||
public StaticHashTableCore
|
||||
{
|
||||
// Private data type for table entries
|
||||
|
||||
|
@ -108,6 +129,7 @@ class StaticHashTable
|
|||
//- Assign a new hashed entry to a possibly already existing key
|
||||
bool set(const Key&, const T& newElmt, bool protect);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
@ -156,11 +178,11 @@ public:
|
|||
StaticHashTable(const StaticHashTable<T, Key, Hash>&);
|
||||
|
||||
//- Construct by transferring the parameter contents
|
||||
StaticHashTable(const Xfer< StaticHashTable<T, Key, Hash> >&);
|
||||
StaticHashTable(const Xfer<StaticHashTable<T, Key, Hash> >&);
|
||||
|
||||
// Destructor
|
||||
|
||||
~StaticHashTable();
|
||||
//- Destructor
|
||||
~StaticHashTable();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
@ -220,11 +242,11 @@ public:
|
|||
void clearStorage();
|
||||
|
||||
//- Transfer the contents of the argument table into this table
|
||||
// and annull the argument table.
|
||||
// and annul the argument table.
|
||||
void transfer(StaticHashTable<T, Key, Hash>&);
|
||||
|
||||
//- Transfer contents to the Xfer container
|
||||
inline Xfer< StaticHashTable<T, Key, Hash> > xfer();
|
||||
inline Xfer<StaticHashTable<T, Key, Hash> > xfer();
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
@ -248,6 +270,7 @@ public:
|
|||
//- The opposite of the equality operation.
|
||||
bool operator!=(const StaticHashTable<T, Key, Hash>&) const;
|
||||
|
||||
|
||||
// STL type definitions
|
||||
|
||||
//- Type of values the StaticHashTable contains.
|
||||
|
@ -290,6 +313,7 @@ public:
|
|||
//- Index of current element at hashIndex
|
||||
label elemIndex_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
|
|
@ -27,6 +27,10 @@ License
|
|||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
defineTypeNameAndDebug(Foam::StaticHashTableName, 0);
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(StaticHashTableCore, 0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -78,7 +78,7 @@ inline bool Foam::StaticHashTable<T, Key, Hash>::set
|
|||
|
||||
|
||||
template<class T, class Key, class Hash>
|
||||
inline Foam::Xfer< Foam::StaticHashTable<T, Key, Hash> >
|
||||
inline Foam::Xfer<Foam::StaticHashTable<T, Key, Hash> >
|
||||
Foam::StaticHashTable<T, Key, Hash>::xfer()
|
||||
{
|
||||
return xferMove(*this);
|
||||
|
@ -266,8 +266,13 @@ Foam::StaticHashTable<T, Key, Hash>::Iterator
|
|||
TableRef
|
||||
>::operator++()
|
||||
{
|
||||
// Check for special value from erase. (sets hashIndex to -1)
|
||||
if (hashIndex_ >= 0)
|
||||
// A negative index is a special value from erase
|
||||
// (see notes in HashTable)
|
||||
if (hashIndex_ < 0)
|
||||
{
|
||||
hashIndex_ = -(hashIndex_+1) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try the next element on the local list
|
||||
elemIndex_++;
|
||||
|
@ -411,6 +416,4 @@ Foam::StaticHashTable<T, Key, Hash>::end() const
|
|||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
|
|
|
@ -36,9 +36,9 @@ Foam::StaticHashTable<T, Key, Hash>::StaticHashTable
|
|||
const label size
|
||||
)
|
||||
:
|
||||
StaticHashTableName(),
|
||||
keys_(size),
|
||||
objects_(size),
|
||||
StaticHashTableCore(),
|
||||
keys_(StaticHashTableCore::canonicalSize(size)),
|
||||
objects_(StaticHashTableCore::canonicalSize(size)),
|
||||
nElmts_(0),
|
||||
endIter_(*this, keys_.size(), 0),
|
||||
endConstIter_(*this, keys_.size(), 0)
|
||||
|
|
Reference in a new issue