Commit 3a0c427c authored by Mark Olesen's avatar Mark Olesen
Browse files

HashTbl - preparation for using interatorBase

parent a61c03a6
......@@ -341,6 +341,68 @@ bool Foam::HashTbl<T, Key, Hash>::set
}
template<class T, class Key, class Hash>
bool Foam::HashTbl<T, Key, Hash>::iteratorBase::erase()
{
// note: elmtPtr_ is NULL for end(), so this catches that too
if (elmtPtr_)
{
// Search element before elmtPtr_
hashedEntry* prev = 0;
for
(
hashedEntry* ep = hashTable_->table_[hashIndex_];
ep;
ep = ep->next_
)
{
if (ep == elmtPtr_)
{
break;
}
prev = ep;
}
if (prev)
{
// has an element before elmtPtr - reposition to there
prev->next_ = elmtPtr_->next_;
delete elmtPtr_;
elmtPtr_ = prev;
}
else
{
// elmtPtr was first element on SLList
hashTable_->table_[hashIndex_] = elmtPtr_->next_;
delete elmtPtr_;
// assign any non-NULL value so it doesn't look like end()/cend()
elmtPtr_ = reinterpret_cast<hashedEntry*>(hashTable_);
// 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'
hashIndex_ = -hashIndex_ - 1;
}
hashTable_->nElmts_--;
return true;
}
else
{
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
......
......@@ -140,7 +140,9 @@ class HashTbl
public:
// Forward declaration of STL iterators
// Forward declaration of iterators
class iteratorBase;
class iterator;
class const_iterator;
......@@ -148,6 +150,9 @@ public:
template<class T2, class Key2, class Hash2>
friend class HashPtrTable;
//- Declare friendship with the iteratorBase
friend class iteratorBase;
//- Declare friendship with the iterator
friend class iterator;
......@@ -298,6 +303,70 @@ public:
// Iterators and helpers
//- The iterator base for HashTbl
// Note: data and functions are protected, to allow reuse by iterator
// and prevent most external usage.
class iteratorBase
{
friend class HashTbl;
public:
// Protected 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_;
// Protected Member Functions
// Constructors
//- Construct null - equivalent to an 'end' position
inline iteratorBase();
//- Construct from hash table, moving to its 'begin' position
inline iteratorBase
(
const HashTbl<T, Key, Hash>* curHashTbl
);
//- Construct from hash table, element and hash index
inline iteratorBase
(
const HashTbl<T, Key, Hash>* curHashTbl,
const hashedEntry* elmt,
const label hashIndex
);
inline void incr();
bool erase();
public:
// Member operators
// Access
//- Return the Key corresponding to the iterator
inline const Key& key() const;
//- Return referenced object
inline const T& object() const;
//- Compare hashedEntry element pointers
inline bool operator==(const iteratorBase&) const;
inline bool operator!=(const iteratorBase&) const;
};
//- An STL-conforming iterator
class iterator
{
......@@ -316,12 +385,7 @@ public:
//- Current hash index
label hashIndex_;
public:
// Constructors
//- Construct null (end iterator)
inline iterator();
// Private Member Functions
//- Construct from hash table, element and hash index
inline iterator
......@@ -331,6 +395,12 @@ public:
const label hashIndex
);
public:
// Constructors
//- Construct null (end iterator)
inline iterator();
// Member operators
......@@ -359,6 +429,8 @@ public:
inline iterator operator++(int);
};
//- iterator set to the begining of the HashTbl
inline iteratorBase beginBase();
//- iterator set to the begining of the HashTbl
inline iterator begin();
......@@ -372,6 +444,7 @@ public:
//- An STL-conforming const_iterator
class const_iterator
{
friend class HashTbl;
friend class iterator;
// Private data
......@@ -386,12 +459,7 @@ public:
//- Current hash index
label hashIndex_;
public:
// Constructors
//- Construct null (end iterator)
inline const_iterator();
// Private Member Functions
//- Construct from hash table, element and hash index
inline const_iterator
......@@ -401,6 +469,13 @@ public:
const label hashIndex
);
public:
// Constructors
//- Construct null (end iterator)
inline const_iterator();
//- Construct from the non-const iterator
inline const_iterator(const iterator&);
......
......@@ -161,6 +161,142 @@ inline T& Foam::HashTbl<T, Key, Hash>::operator()(const Key& key)
// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase()
:
hashTable_(0),
elmtPtr_(0),
hashIndex_(0)
{}
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase
(
const HashTbl<T, Key, Hash>* hashTbl
)
:
hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)),
elmtPtr_(0),
hashIndex_(0)
{
if (hashTable_->nElmts_ && hashTable_->table_)
{
// find first non-NULL table entry
while
(
!(elmtPtr_ = hashTable_->table_[hashIndex_])
&& ++hashIndex_ < hashTable_->tableSize_
)
{}
if (hashIndex_ >= hashTable_->tableSize_)
{
// make into an end iterator
elmtPtr_ = 0;
hashIndex_ = 0;
}
else
{
Info<<"OK key is " << this->key() << endl;
}
}
}
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iteratorBase::iteratorBase
(
const HashTbl<T, Key, Hash>* hashTbl,
const hashedEntry* elmt,
const label hashIndex
)
:
hashTable_(const_cast<HashTbl<T, Key, Hash>*>(hashTbl)),
elmtPtr_(const_cast<hashedEntry*>(elmt)),
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>
inline void
Foam::HashTbl<T, Key, Hash>::iteratorBase::incr()
{
// A negative index is a special value from erase
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;
}
// Step to the next table entry
while
(
++hashIndex_ < hashTable_->tableSize_
&& !(elmtPtr_ = hashTable_->table_[hashIndex_])
)
{}
if (hashIndex_ >= hashTable_->tableSize_)
{
// make into an end iterator
elmtPtr_ = 0;
hashIndex_ = 0;
}
}
template<class T, class Key, class Hash>
inline
const Key& Foam::HashTbl<T, Key, Hash>::iteratorBase::key() const
{
return elmtPtr_->key_;
}
template<class T, class Key, class Hash>
inline const T&
Foam::HashTbl<T, Key, Hash>::iteratorBase::object() const
{
return elmtPtr_->obj_;
}
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator==
(
const iteratorBase& iter
) const
{
return elmtPtr_ == iter.elmtPtr_;
}
template<class T, class Key, class Hash>
inline bool Foam::HashTbl<T, Key, Hash>::iteratorBase::operator!=
(
const iteratorBase& iter
) const
{
return elmtPtr_ != iter.elmtPtr_;
}
template<class T, class Key, class Hash>
inline Foam::HashTbl<T, Key, Hash>::iterator::iterator
(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment