HashTbl - iterator/const_iterator implemented in terms of an iteratorBase

This commit is contained in:
Mark Olesen
2009-11-01 00:54:56 +01:00
parent 3a0c427c7b
commit a237b7ce6e
4 changed files with 171 additions and 463 deletions

View File

@ -65,9 +65,7 @@ Foam::HashTbl<T, Key, Hash>::HashTbl(const label size)
HashTblName(), HashTblName(),
nElmts_(0), nElmts_(0),
tableSize_(canonicalSize(size)), tableSize_(canonicalSize(size)),
table_(NULL), table_(NULL)
endIter_(),
endConstIter_()
{ {
if (tableSize_) if (tableSize_)
{ {
@ -87,9 +85,7 @@ Foam::HashTbl<T, Key, Hash>::HashTbl(const HashTbl<T, Key, Hash>& ht)
HashTblName(), HashTblName(),
nElmts_(0), nElmts_(0),
tableSize_(ht.tableSize_), tableSize_(ht.tableSize_),
table_(NULL), table_(NULL)
endIter_(),
endConstIter_()
{ {
if (tableSize_) if (tableSize_)
{ {
@ -116,9 +112,7 @@ Foam::HashTbl<T, Key, Hash>::HashTbl
HashTblName(), HashTblName(),
nElmts_(0), nElmts_(0),
tableSize_(0), tableSize_(0),
table_(NULL), table_(NULL)
endIter_(),
endConstIter_()
{ {
transfer(ht()); transfer(ht());
} }
@ -344,10 +338,10 @@ bool Foam::HashTbl<T, Key, Hash>::set
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
bool Foam::HashTbl<T, Key, Hash>::iteratorBase::erase() bool Foam::HashTbl<T, Key, Hash>::iteratorBase::erase()
{ {
// note: elmtPtr_ is NULL for end(), so this catches that too // note: entryPtr_ is NULL for end(), so this catches that too
if (elmtPtr_) if (entryPtr_)
{ {
// Search element before elmtPtr_ // Search element before entryPtr_
hashedEntry* prev = 0; hashedEntry* prev = 0;
for for
@ -357,7 +351,7 @@ bool Foam::HashTbl<T, Key, Hash>::iteratorBase::erase()
ep = ep->next_ ep = ep->next_
) )
{ {
if (ep == elmtPtr_) if (ep == entryPtr_)
{ {
break; break;
} }
@ -366,19 +360,20 @@ bool Foam::HashTbl<T, Key, Hash>::iteratorBase::erase()
if (prev) if (prev)
{ {
// has an element before elmtPtr - reposition to there // has an element before entryPtr - reposition to there
prev->next_ = elmtPtr_->next_; prev->next_ = entryPtr_->next_;
delete elmtPtr_; delete entryPtr_;
elmtPtr_ = prev; entryPtr_ = prev;
} }
else else
{ {
// elmtPtr was first element on SLList // entryPtr was first element on SLList
hashTable_->table_[hashIndex_] = elmtPtr_->next_; hashTable_->table_[hashIndex_] = entryPtr_->next_;
delete elmtPtr_; delete entryPtr_;
// assign any non-NULL value so it doesn't look like end()/cend() // assign any non-NULL pointer value so it doesn't look
elmtPtr_ = reinterpret_cast<hashedEntry*>(hashTable_); // like end()/cend()
entryPtr_ = reinterpret_cast<hashedEntry*>(this);
// Mark with special hashIndex value to signal it has been rewound. // Mark with special hashIndex value to signal it has been rewound.
// The next increment will bring it back to the present location. // The next increment will bring it back to the present location.
@ -411,92 +406,15 @@ bool Foam::HashTbl<T, Key, Hash>::iteratorBase::erase()
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit) bool Foam::HashTbl<T, Key, Hash>::erase(const iterator& cit)
{ {
// note: elmtPtr_ is NULL for end(), so this catches that too
if (cit.elmtPtr_)
{
// Search element before elmtPtr_
hashedEntry* prev = 0;
for (hashedEntry* ep = table_[cit.hashIndex_]; ep; ep = ep->next_)
{
if (ep == cit.elmtPtr_)
{
break;
}
prev = ep;
}
// adjust iterator after erase // adjust iterator after erase
iterator& iter = const_cast<iterator&>(cit); return const_cast<iterator&>(cit).erase();
if (prev)
{
// has an element before elmtPtr - reposition to there
prev->next_ = iter.elmtPtr_->next_;
delete iter.elmtPtr_;
iter.elmtPtr_ = prev;
}
else
{
// elmtPtr was first element on SLList
table_[iter.hashIndex_] = iter.elmtPtr_->next_;
delete iter.elmtPtr_;
// assign an non-NULL value so it doesn't look like end()/cend()
iter.elmtPtr_ = reinterpret_cast<hashedEntry*>(this);
// Mark with special hashIndex value to signal it has been rewound.
// The next increment will bring it back to the present location.
//
// For the current position 'X', mark it as '-(X+1)', which is
// written as '-X-1' to avoid overflow.
// The extra '-1' is needed to avoid ambiguity for position '0'.
// To retrieve the previous position 'X-1' we would later
// use '-(-X-1) - 2'
iter.hashIndex_ = -iter.hashIndex_ - 1;
}
nElmts_--;
# ifdef FULLDEBUG
if (debug)
{
Info<< "HashTbl<T, Key, Hash>::erase(const iterator&) : "
<< "hashedEntry " << iter.elmtPtr_->key_ << " removed.\n";
}
# endif
return true;
}
else
{
# ifdef FULLDEBUG
if (debug)
{
Info<< "HashTbl<T, Key, Hash>::erase(const iterator&) : "
<< "cannot remove hashedEntry from hash table\n";
}
# endif
return false;
}
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
bool Foam::HashTbl<T, Key, Hash>::erase(const Key& key) bool Foam::HashTbl<T, Key, Hash>::erase(const Key& key)
{ {
// we could also simply do: erase(find(key)); return erase(find(key));
iterator fnd = find(key);
if (fnd != end())
{
return erase(fnd);
}
else
{
return false;
}
} }
@ -560,22 +478,22 @@ void Foam::HashTbl<T, Key, Hash>::resize(const label sz)
return; return;
} }
HashTbl<T, Key, Hash>* newTable = new HashTbl<T, Key, Hash>(newSize); HashTbl<T, Key, Hash>* tmpTable = new HashTbl<T, Key, Hash>(newSize);
for (const_iterator iter = cbegin(); iter != cend(); ++iter) for (const_iterator iter = cbegin(); iter != cend(); ++iter)
{ {
newTable->insert(iter.key(), *iter); tmpTable->insert(iter.key(), *iter);
} }
label oldTableSize = tableSize_; label oldSize = tableSize_;
tableSize_ = newTable->tableSize_; tableSize_ = tmpTable->tableSize_;
newTable->tableSize_ = oldTableSize; tmpTable->tableSize_ = oldSize;
hashedEntry** oldTable = table_; hashedEntry** oldTable = table_;
table_ = newTable->table_; table_ = tmpTable->table_;
newTable->table_ = oldTable; tmpTable->table_ = oldTable;
delete newTable; delete tmpTable;
} }
@ -687,7 +605,7 @@ bool Foam::HashTbl<T, Key, Hash>::operator==
const HashTbl<T, Key, Hash>& rhs const HashTbl<T, Key, Hash>& rhs
) const ) const
{ {
// sizes (ie, number of keys) must match // sizes (number of keys) must match
if (size() != rhs.size()) if (size() != rhs.size())
{ {
return false; return false;

View File

@ -88,6 +88,7 @@ class HashTbl
{ {
// Private data type for table entries // Private data type for table entries
//- Structure to hold a hashed entry with SLList for collisions
struct hashedEntry struct hashedEntry
{ {
//- The lookup key //- The lookup key
@ -99,18 +100,15 @@ class HashTbl
//- The data object //- The data object
T obj_; 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 private:
inline hashedEntry //- Disallow default bitwise copy construct
(
const Key&,
hashedEntry* next,
const T& newEntry
);
//- Dissallow construction as copy
hashedEntry(const hashedEntry&); hashedEntry(const hashedEntry&);
//- Disallow default bitwise assignment
void operator=(const hashedEntry&);
}; };
@ -222,7 +220,7 @@ public:
inline bool set(const Key&, const T& newElmt); inline bool set(const Key&, const T& newElmt);
//- Erase a hashedEntry specified by given iterator //- Erase a hashedEntry specified by given iterator
// This invalidates the iterator until the operator++ // This invalidates the iterator until the next operator++
bool erase(const iterator&); bool erase(const iterator&);
//- Erase a hashedEntry specified by the given key //- Erase a hashedEntry specified by the given key
@ -235,7 +233,7 @@ public:
//- Remove entries given by the given keys from this HashTbl //- Remove entries given by the given keys from this HashTbl
// Return the number of elements removed. // Return the number of elements removed.
// The parameter HashTbl needs the same type of key, but the // The parameter HashTbl needs the same type of key, but the
// type of values held and the hashing function is arbitrary. // type of values held and the hashing function are arbitrary.
template<class AnyType, class AnyHash> template<class AnyType, class AnyHash>
label erase(const HashTbl<AnyType, Key, AnyHash>&); label erase(const HashTbl<AnyType, Key, AnyHash>&);
@ -306,24 +304,23 @@ public:
//- The iterator base for HashTbl //- The iterator base for HashTbl
// Note: data and functions are protected, to allow reuse by iterator // Note: data and functions are protected, to allow reuse by iterator
// and prevent most external usage. // and prevent most external usage.
// iterator and const_iterator have the same size, allowing
// us to reinterpret_cast between them (if desired)
class iteratorBase class iteratorBase
{ {
friend class HashTbl; // Private Data
public:
// Protected Data
//- Pointer to the HashTbl for which this is an iterator //- Pointer to the HashTbl for which this is an iterator
// This also lets us use the default bitwise copy/assignment // This also lets us use the default bitwise copy/assignment
HashTbl<T, Key, Hash>* hashTable_; HashTbl<T, Key, Hash>* hashTable_;
//- Current element //- Current element
hashedEntry* elmtPtr_; hashedEntry* entryPtr_;
//- Current hash index //- Current hash index
label hashIndex_; label hashIndex_;
protected:
// Protected Member Functions // Protected Member Functions
@ -333,22 +330,32 @@ public:
inline iteratorBase(); inline iteratorBase();
//- Construct from hash table, moving to its 'begin' position //- Construct from hash table, moving to its 'begin' position
inline iteratorBase inline explicit iteratorBase
( (
const HashTbl<T, Key, Hash>* curHashTbl const HashTbl<T, Key, Hash>* curHashTbl
); );
//- Construct from hash table, element and hash index //- Construct from hash table, element and hash index
inline iteratorBase inline explicit iteratorBase
( (
const HashTbl<T, Key, Hash>* curHashTbl, const HashTbl<T, Key, Hash>* curHashTbl,
const hashedEntry* elmt, const hashedEntry* elmt,
const label hashIndex const label hashIndex
); );
inline void incr();
//- Increment to the next position
inline void increment();
//- Erase the HashTbl element at the current position
bool erase(); bool erase();
//- Return non-const access to referenced object
inline T& object();
//- Return const access to referenced object
inline const T& cobject() const;
public: public:
// Member operators // Member operators
@ -358,9 +365,6 @@ public:
//- Return the Key corresponding to the iterator //- Return the Key corresponding to the iterator
inline const Key& key() const; inline const Key& key() const;
//- Return referenced object
inline const T& object() const;
//- Compare hashedEntry element pointers //- Compare hashedEntry element pointers
inline bool operator==(const iteratorBase&) const; inline bool operator==(const iteratorBase&) const;
inline bool operator!=(const iteratorBase&) const; inline bool operator!=(const iteratorBase&) const;
@ -369,26 +373,21 @@ public:
//- An STL-conforming iterator //- An STL-conforming iterator
class iterator class iterator
:
public iteratorBase
{ {
friend class HashTbl; friend class HashTbl;
friend class const_iterator;
// Private data
//- Pointer to the HashTbl for which this is an iterator
// This also lets us use the default bitwise copy/assignment
HashTbl<T, Key, Hash>* hashTable_;
//- Current element
hashedEntry* elmtPtr_;
//- Current hash index
label hashIndex_;
// Private Member Functions // Private Member Functions
//- Construct from hash table, moving to its 'begin' position
inline explicit iterator
(
HashTbl<T, Key, Hash>* curHashTbl
);
//- Construct from hash table, element and hash index //- Construct from hash table, element and hash index
inline iterator inline explicit iterator
( (
HashTbl<T, Key, Hash>* curHashTbl, HashTbl<T, Key, Hash>* curHashTbl,
hashedEntry* elmt, hashedEntry* elmt,
@ -404,19 +403,11 @@ public:
// Member operators // Member operators
//- Conversion to a const_iterator
inline operator const_iterator() const;
// Access // Access
//- Return the Key corresponding to the iterator
inline const Key& key() const;
//- Compare hashedEntry element pointers
inline bool operator==(const iterator&) const;
inline bool operator!=(const iterator&) const;
//- Compare hashedEntry element pointers
inline bool operator==(const const_iterator&) const;
inline bool operator!=(const const_iterator&) const;
//- Return referenced hash value //- Return referenced hash value
inline T& operator*(); inline T& operator*();
inline T& operator()(); inline T& operator()();
@ -429,9 +420,6 @@ public:
inline iterator operator++(int); inline iterator operator++(int);
}; };
//- iterator set to the begining of the HashTbl
inline iteratorBase beginBase();
//- iterator set to the begining of the HashTbl //- iterator set to the begining of the HashTbl
inline iterator begin(); inline iterator begin();
@ -443,26 +431,21 @@ public:
//- An STL-conforming const_iterator //- An STL-conforming const_iterator
class const_iterator class const_iterator
:
public iteratorBase
{ {
friend class HashTbl; friend class HashTbl;
friend class iterator;
// Private data
//- Pointer to the HashTbl for which this is an iterator
// This also lets us use the default bitwise copy/assignment
const HashTbl<T, Key, Hash>* hashTable_;
//- Current element
const hashedEntry* elmtPtr_;
//- Current hash index
label hashIndex_;
// Private Member Functions // Private Member Functions
//- Construct from hash table, moving to its 'begin' position
inline explicit const_iterator
(
const HashTbl<T, Key, Hash>* curHashTbl
);
//- Construct from hash table, element and hash index //- Construct from hash table, element and hash index
inline const_iterator inline explicit const_iterator
( (
const HashTbl<T, Key, Hash>* curHashTbl, const HashTbl<T, Key, Hash>* curHashTbl,
const hashedEntry* elmt, const hashedEntry* elmt,
@ -476,25 +459,10 @@ public:
//- Construct null (end iterator) //- Construct null (end iterator)
inline const_iterator(); inline const_iterator();
//- Construct from the non-const iterator
inline const_iterator(const iterator&);
// Member operators // Member operators
// Access // Access
//- Return the Key corresponding to the iterator
inline const Key& key() const;
//- Compare hashedEntry element pointers
inline bool operator==(const const_iterator&) const;
inline bool operator!=(const const_iterator&) const;
//- Compare hashedEntry element pointers
inline bool operator==(const iterator&) const;
inline bool operator!=(const iterator&) const;
//- Return referenced hash value //- Return referenced hash value
inline const T& operator*() const; inline const T& operator*() const;
inline const T& operator()() const; inline const T& operator()() const;

View File

@ -33,12 +33,12 @@ inline Foam::HashTbl<T, Key, Hash>::hashedEntry::hashedEntry
( (
const Key& key, const Key& key,
hashedEntry* next, hashedEntry* next,
const T& newEntry const T& obj
) )
: :
key_(key), key_(key),
next_(next), next_(next),
obj_(newEntry) obj_(obj)
{} {}
@ -159,13 +159,13 @@ inline T& Foam::HashTbl<T, Key, Hash>::operator()(const Key& key)
} }
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * //
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase() inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase()
: :
hashTable_(0), hashTable_(0),
elmtPtr_(0), entryPtr_(0),
hashIndex_(0) hashIndex_(0)
{} {}
@ -177,7 +177,7 @@ inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase
) )
: :
hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)), hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)),
elmtPtr_(0), entryPtr_(0),
hashIndex_(0) hashIndex_(0)
{ {
if (hashTable_->nElmts_ && hashTable_->table_) if (hashTable_->nElmts_ && hashTable_->table_)
@ -185,7 +185,7 @@ inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase
// find first non-NULL table entry // find first non-NULL table entry
while while
( (
!(elmtPtr_ = hashTable_->table_[hashIndex_]) !(entryPtr_ = hashTable_->table_[hashIndex_])
&& ++hashIndex_ < hashTable_->tableSize_ && ++hashIndex_ < hashTable_->tableSize_
) )
{} {}
@ -193,7 +193,7 @@ inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase
if (hashIndex_ >= hashTable_->tableSize_) if (hashIndex_ >= hashTable_->tableSize_)
{ {
// make into an end iterator // make into an end iterator
elmtPtr_ = 0; entryPtr_ = 0;
hashIndex_ = 0; hashIndex_ = 0;
} }
else else
@ -213,22 +213,14 @@ inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase
) )
: :
hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)), hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)),
elmtPtr_(const_cast<hashedEntry*>(elmt)), entryPtr_(const_cast<hashedEntry*>(elmt)),
hashIndex_(hashIndex) hashIndex_(hashIndex)
{} {}
template<class T, class Key, class Hash>
inline typename Foam::HashTbl<T, Key, Hash>::iteratorBase
Foam::HashTbl<T, Key, Hash>::beginBase()
{
return iteratorBase(this);
}
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline void inline void
Foam::HashTbl<T, Key, Hash>::iteratorBase::incr() Foam::HashTbl<T, Key, Hash>::iteratorBase::increment()
{ {
// A negative index is a special value from erase // A negative index is a special value from erase
if (hashIndex_ < 0) if (hashIndex_ < 0)
@ -237,10 +229,10 @@ Foam::HashTbl<T, Key, Hash>::iteratorBase::incr()
// but we wish to continue at 'X-1' // but we wish to continue at 'X-1'
hashIndex_ = -hashIndex_ - 2; hashIndex_ = -hashIndex_ - 2;
} }
else if (elmtPtr_ && elmtPtr_->next_) else if (entryPtr_ && entryPtr_->next_)
{ {
// Do we have additional elements on the SLList? // Move to next element on the SLList
elmtPtr_ = elmtPtr_->next_; entryPtr_ = entryPtr_->next_;
return; return;
} }
@ -248,14 +240,14 @@ Foam::HashTbl<T, Key, Hash>::iteratorBase::incr()
while while
( (
++hashIndex_ < hashTable_->tableSize_ ++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_]) && !(entryPtr_ = hashTable_->table_[hashIndex_])
) )
{} {}
if (hashIndex_ >= hashTable_->tableSize_) if (hashIndex_ >= hashTable_->tableSize_)
{ {
// make into an end iterator // make into an end iterator
elmtPtr_ = 0; entryPtr_ = 0;
hashIndex_ = 0; hashIndex_ = 0;
} }
} }
@ -265,15 +257,23 @@ template<class T, class Key, class Hash>
inline inline
const Key& Foam::HashTbl<T, Key, Hash>::iteratorBase::key() const const Key& Foam::HashTbl<T, Key, Hash>::iteratorBase::key() const
{ {
return elmtPtr_->key_; return entryPtr_->key_;
}
template<class T, class Key, class Hash>
inline T&
Foam::HashTbl<T, Key, Hash>::iteratorBase::object()
{
return entryPtr_->obj_;
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline const T& inline const T&
Foam::HashTbl<T, Key, Hash>::iteratorBase::object() const Foam::HashTbl<T, Key, Hash>::iteratorBase::cobject() const
{ {
return elmtPtr_->obj_; return entryPtr_->obj_;
} }
@ -283,7 +283,7 @@ inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator==
const iteratorBase& iter const iteratorBase& iter
) const ) const
{ {
return elmtPtr_ == iter.elmtPtr_; return entryPtr_ == iter.entryPtr_;
} }
@ -293,10 +293,29 @@ inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator!=
const iteratorBase& iter const iteratorBase& iter
) const ) const
{ {
return elmtPtr_ != iter.elmtPtr_; return entryPtr_ != iter.entryPtr_;
} }
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iterator::iterator()
:
iteratorBase()
{}
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iterator::iterator
(
HashTbl<T, Key, Hash>* hashTbl
)
:
iteratorBase(hashTbl)
{}
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iterator::iterator inline Foam::HashTbl<T, Key, Hash>::iterator::iterator
( (
@ -305,58 +324,18 @@ inline Foam::HashTbl<T, Key, Hash>::iterator::iterator
const label hashIndex const label hashIndex
) )
: :
hashTable_(hashTbl), iteratorBase(hashTbl, elmt, hashIndex)
elmtPtr_(elmt),
hashIndex_(hashIndex)
{} {}
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iterator::iterator() inline Foam::HashTbl<T, Key, Hash>::iterator::operator
: typename Foam::HashTbl<T, Key, Hash>::const_iterator() const
hashTable_(0),
elmtPtr_(0),
hashIndex_(0)
{}
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::iterator::operator==
(
const iterator& iter
) const
{ {
return elmtPtr_ == iter.elmtPtr_; return *reinterpret_cast
} <
const typename Foam::HashTbl<T, Key, Hash>::const_iterator*
>(this);
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::iterator::operator!=
(
const iterator& iter
) const
{
return elmtPtr_ != iter.elmtPtr_;
}
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::iterator::operator==
(
const const_iterator& iter
) const
{
return elmtPtr_ == iter.elmtPtr_;
}
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::iterator::operator!=
(
const const_iterator& iter
) const
{
return elmtPtr_ != iter.elmtPtr_;
} }
@ -364,7 +343,7 @@ template<class T, class Key, class Hash>
inline T& inline T&
Foam::HashTbl<T, Key, Hash>::iterator::operator*() Foam::HashTbl<T, Key, Hash>::iterator::operator*()
{ {
return elmtPtr_->obj_; return this->object();
} }
@ -372,7 +351,7 @@ template<class T, class Key, class Hash>
inline T& inline T&
Foam::HashTbl<T, Key, Hash>::iterator::operator()() Foam::HashTbl<T, Key, Hash>::iterator::operator()()
{ {
return elmtPtr_->obj_; return this->object();
} }
@ -380,7 +359,7 @@ template<class T, class Key, class Hash>
inline const T& inline const T&
Foam::HashTbl<T, Key, Hash>::iterator::operator*() const Foam::HashTbl<T, Key, Hash>::iterator::operator*() const
{ {
return elmtPtr_->obj_; return this->cobject();
} }
@ -388,7 +367,7 @@ template<class T, class Key, class Hash>
inline const T& inline const T&
Foam::HashTbl<T, Key, Hash>::iterator::operator()() const Foam::HashTbl<T, Key, Hash>::iterator::operator()() const
{ {
return elmtPtr_->obj_; return this->cobject();
} }
@ -397,56 +376,18 @@ inline
typename Foam::HashTbl<T, Key, Hash>::iterator& typename Foam::HashTbl<T, Key, Hash>::iterator&
Foam::HashTbl<T, Key, Hash>::iterator::operator++() Foam::HashTbl<T, Key, Hash>::iterator::operator++()
{ {
// A negative index is a special value from erase this->increment();
if (hashIndex_ < 0)
{
// old position 'X' was marked as '-(X+1)'
// but we wish to continue at 'X-1'
hashIndex_ = -hashIndex_ - 2;
}
else if (elmtPtr_ && elmtPtr_->next_)
{
// Do we have additional elements on the SLList?
elmtPtr_ = elmtPtr_->next_;
return *this;
}
// Step to the next table entry
while
(
++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_])
)
{}
if (hashIndex_ >= hashTable_->tableSize_)
{
// make an end iterator
elmtPtr_ = 0;
hashIndex_ = 0;
}
return *this; return *this;
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline typename Foam::HashTbl<T, Key, Hash>::iterator inline typename Foam::HashTbl<T, Key, Hash>::iterator
Foam::HashTbl<T, Key, Hash>::iterator::operator++ Foam::HashTbl<T, Key, Hash>::iterator::operator++(int)
(
int
)
{ {
iterator tmp = *this; iterator old = *this;
++*this; this->increment();
return tmp; return old;
}
template<class T, class Key, class Hash>
inline
const Key& Foam::HashTbl<T, Key, Hash>::iterator::key() const
{
return elmtPtr_->key_;
} }
@ -454,33 +395,7 @@ template<class T, class Key, class Hash>
inline typename Foam::HashTbl<T, Key, Hash>::iterator inline typename Foam::HashTbl<T, Key, Hash>::iterator
Foam::HashTbl<T, Key, Hash>::begin() Foam::HashTbl<T, Key, Hash>::begin()
{ {
label hashIdx = 0; return iterator(this);
if (nElmts_)
{
while (table_ && !table_[hashIdx] && ++hashIdx < tableSize_)
{}
}
else
{
hashIdx = tableSize_;
}
if (hashIdx >= tableSize_)
{
# ifdef FULLDEBUG
if (debug)
{
Info<< "HashTbl is empty\n";
}
# endif
return HashTbl<T, Key, Hash>::endIter_;
}
else
{
return iterator(this, table_[hashIdx], hashIdx);
}
} }
@ -497,9 +412,17 @@ Foam::HashTbl<T, Key, Hash>::end()
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator() inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator()
: :
hashTable_(0), iteratorBase()
elmtPtr_(0), {}
hashIndex_(0)
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator
(
const HashTbl<T, Key, Hash>* hashTbl
)
:
iteratorBase(hashTbl)
{} {}
@ -511,76 +434,23 @@ inline Foam::HashTbl<T, Key, Hash>::const_iterator::const_iterator
const label hashIndex const label hashIndex
) )
: :
hashTable_(hashTbl), iteratorBase(hashTbl, elmt, hashIndex)
elmtPtr_(elmt),
hashIndex_(hashIndex)
{} {}
template<class T, class Key, class Hash>
inline Foam::HashTbl<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 bool Foam::HashTbl<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::HashTbl<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::HashTbl<T, Key, Hash>::const_iterator::operator==
(
const iterator& iter
) const
{
return elmtPtr_ == iter.elmtPtr_;
}
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::const_iterator::operator!=
(
const iterator& iter
) const
{
return elmtPtr_ != iter.elmtPtr_;
}
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline const T& inline const T&
Foam::HashTbl<T, Key, Hash>::const_iterator::operator*() const Foam::HashTbl<T, Key, Hash>::const_iterator::operator*() const
{ {
return elmtPtr_->obj_; return this->cobject();
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline const T& inline const T&
Foam::HashTbl<T, Key, Hash>::const_iterator::operator()() const Foam::HashTbl<T, Key, Hash>::const_iterator::operator()() const
{ {
return elmtPtr_->obj_; return this->cobject();
} }
@ -589,43 +459,18 @@ inline
typename Foam::HashTbl<T, Key, Hash>::const_iterator& typename Foam::HashTbl<T, Key, Hash>::const_iterator&
Foam::HashTbl<T, Key, Hash>::const_iterator::operator++() Foam::HashTbl<T, Key, Hash>::const_iterator::operator++()
{ {
if this->increment();
(
!(elmtPtr_ = elmtPtr_->next_)
&& ++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_])
)
{
while
(
++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_])
)
{}
}
return *this; return *this;
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
inline typename Foam::HashTbl<T, Key, Hash>::const_iterator inline typename Foam::HashTbl<T, Key, Hash>::const_iterator
Foam::HashTbl<T, Key, Hash>::const_iterator::operator++ Foam::HashTbl<T, Key, Hash>::const_iterator::operator++(int)
(
int
)
{ {
const_iterator tmp = *this; const_iterator old = *this;
++*this; this->increment();
return tmp; return old;
}
template<class T, class Key, class Hash>
inline
const Key& Foam::HashTbl<T, Key, Hash>::const_iterator::key() const
{
return elmtPtr_->key_;
} }
@ -633,33 +478,7 @@ template<class T, class Key, class Hash>
inline typename Foam::HashTbl<T, Key, Hash>::const_iterator inline typename Foam::HashTbl<T, Key, Hash>::const_iterator
Foam::HashTbl<T, Key, Hash>::cbegin() const Foam::HashTbl<T, Key, Hash>::cbegin() const
{ {
label hashIdx = 0; return const_iterator(this);
if (nElmts_)
{
while (table_ && !table_[hashIdx] && ++hashIdx < tableSize_)
{}
}
else
{
hashIdx = tableSize_;
}
if (hashIdx >= tableSize_)
{
# ifdef FULLDEBUG
if (debug)
{
Info<< "HashTbl is empty\n";
}
# endif
return HashTbl<T, Key, Hash>::endConstIter_;
}
else
{
return const_iterator(this, table_[hashIdx], hashIdx);
}
} }
@ -683,7 +502,7 @@ template<class T, class Key, class Hash>
inline const typename Foam::HashTbl<T, Key, Hash>::const_iterator& inline const typename Foam::HashTbl<T, Key, Hash>::const_iterator&
Foam::HashTbl<T, Key, Hash>::end() const Foam::HashTbl<T, Key, Hash>::end() const
{ {
return HashTbl<T, Key, Hash>::endConstIter_; return this->cend();
} }

View File

@ -36,14 +36,17 @@ Foam::HashTbl<T, Key, Hash>::HashTbl(Istream& is, const label size)
HashTblName(), HashTblName(),
nElmts_(0), nElmts_(0),
tableSize_(canonicalSize(size)), tableSize_(canonicalSize(size)),
table_(new hashedEntry*[tableSize_]), table_(NULL)
endIter_(),
endConstIter_()
{ {
if (tableSize_)
{
table_ = new hashedEntry*[tableSize_];
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++) for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
{ {
table_[hashIdx] = 0; table_[hashIdx] = 0;
} }
}
operator>>(is, *this); operator>>(is, *this);
} }