ENH: improve overall consistency of the HashTable and its iterators

- previously had a mismash of const/non-const attributes on iterators
  that were confused with the attributes of the object being accessed.

- use the iterator keys() and object() methods consistently for all
  internal access of the HashTable iterators. This makes the intention
  clearer, the code easier to maintain, and protects against any
  possible changes in the definition of the operators.

- 'operator*': The standard form expected by STL libraries.
  However, for the std::map, this dereferences to a <key,value> pair,
  whereas OpenFOAM dereferences simply to <value>.

- 'operator()': OpenFOAM treats this like the 'operator*'

- adjusted the values of end() and cend() to reinterpret from nullObject
  instead of returning a static iteratorEnd() object.
  This means that C++ templates can now correctly deduce and match
  the return types from begin() and end() consistently.
  So that range-based now works.

  Eg,
      HashTable<label> table1 = ...;
      for (auto i : table1)
      {
          Info<< i << endl;
      }

  Since the 'operator*' returns hash table values, this prints all the
  values in the table.
This commit is contained in:
Mark Olesen
2017-05-02 00:15:12 +02:00
parent 0298c02b2d
commit c0a50dc621
11 changed files with 331 additions and 364 deletions

View File

@ -31,13 +31,13 @@ template<class T, class Key, class Hash>
inline Foam::HashTable<T, Key, Hash>::hashedEntry::hashedEntry
(
const Key& key,
hashedEntry* next,
const T& obj
const T& obj,
hashedEntry* next
)
:
key_(key),
next_(next),
obj_(obj)
obj_(obj),
next_(next)
{}
@ -112,7 +112,7 @@ inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
{
iterator iter = this->find(key);
if (iter == this->end())
if (!iter.found())
{
FatalErrorInFunction
<< key << " not found in table. Valid entries: "
@ -120,7 +120,7 @@ inline T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key)
<< exit(FatalError);
}
return *iter;
return iter.object();
}
@ -129,7 +129,7 @@ inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
{
const_iterator iter = this->find(key);
if (iter == this->cend())
if (!iter.found())
{
FatalErrorInFunction
<< key << " not found in table. Valid entries: "
@ -137,7 +137,7 @@ inline const T& Foam::HashTable<T, Key, Hash>::operator[](const Key& key) const
<< exit(FatalError);
}
return *iter;
return iter.object();
}
@ -146,15 +146,13 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
{
iterator iter = this->find(key);
if (iter == this->end())
if (iter.found())
{
this->insert(key, T());
return *find(key);
}
else
{
return *iter;
return iter.object();
}
this->insert(key, T());
return find(key).object();
}
@ -163,8 +161,8 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
template<class T, class Key, class Hash>
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase()
:
hashTable_(0),
entryPtr_(0),
entryPtr_(nullptr),
hashTable_(nullptr),
hashIndex_(0)
{}
@ -172,14 +170,28 @@ inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase()
template<class T, class Key, class Hash>
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
(
const HashTable<T, Key, Hash>* hashTbl
const table_type* hashTbl,
const entry_type* elmt,
const label hashIndex
)
:
hashTable_(const_cast<HashTable<T, Key, Hash>*>(hashTbl)),
entryPtr_(0),
entryPtr_(const_cast<entry_type*>(elmt)),
hashTable_(const_cast<table_type*>(hashTbl)),
hashIndex_(hashIndex)
{}
template<class T, class Key, class Hash>
inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
(
const table_type* hashTbl
)
:
entryPtr_(nullptr),
hashTable_(const_cast<table_type*>(hashTbl)),
hashIndex_(0)
{
if (hashTable_->nElmts_)
if (hashTable_ && hashTable_->nElmts_)
{
// find first non-nullptr table entry
while
@ -192,27 +204,13 @@ inline Foam::HashTable<T, Key, Hash>::iteratorBase::iteratorBase
if (hashIndex_ >= hashTable_->tableSize_)
{
// make into an end iterator
entryPtr_ = 0;
entryPtr_ = nullptr;
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>::iteratorBase::increment()
@ -251,7 +249,7 @@ Foam::HashTable<T, Key, Hash>::iteratorBase::increment()
if (hashIndex_ >= hashTable_->tableSize_)
{
// make into an end iterator
entryPtr_ = 0;
entryPtr_ = nullptr;
hashIndex_ = 0;
}
}
@ -266,24 +264,14 @@ Foam::HashTable<T, Key, Hash>::iteratorBase::found() const
template<class T, class Key, class Hash>
inline
const Key& Foam::HashTable<T, Key, Hash>::iteratorBase::key() const
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
inline T& Foam::HashTable<T, Key, Hash>::iteratorBase::element() const
{
return entryPtr_->obj_;
}
@ -309,26 +297,6 @@ inline bool Foam::HashTable<T, Key, Hash>::iteratorBase::operator!=
}
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>
@ -341,17 +309,7 @@ inline Foam::HashTable<T, Key, Hash>::iterator::iterator()
template<class T, class Key, class Hash>
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
(
const iteratorEnd&
)
:
iteratorBase()
{}
template<class T, class Key, class Hash>
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
(
HashTable<T, Key, Hash>* hashTbl
table_type* hashTbl
)
:
iteratorBase(hashTbl)
@ -361,8 +319,8 @@ inline Foam::HashTable<T, Key, Hash>::iterator::iterator
template<class T, class Key, class Hash>
inline Foam::HashTable<T, Key, Hash>::iterator::iterator
(
HashTable<T, Key, Hash>* hashTbl,
hashedEntry* elmt,
table_type* hashTbl,
entry_type* elmt,
const label hashIndex
)
:
@ -372,7 +330,15 @@ inline Foam::HashTable<T, Key, Hash>::iterator::iterator
template<class T, class Key, class Hash>
inline T&
Foam::HashTable<T, Key, Hash>::iterator::operator*()
Foam::HashTable<T, Key, Hash>::iterator::object() const
{
return this->element();
}
template<class T, class Key, class Hash>
inline T&
Foam::HashTable<T, Key, Hash>::iterator::operator*() const
{
return this->object();
}
@ -380,31 +346,14 @@ Foam::HashTable<T, Key, Hash>::iterator::operator*()
template<class T, class Key, class Hash>
inline T&
Foam::HashTable<T, Key, Hash>::iterator::operator()()
Foam::HashTable<T, Key, Hash>::iterator::operator()() const
{
return this->object();
}
template<class T, class Key, class Hash>
inline const T&
Foam::HashTable<T, Key, Hash>::iterator::operator*() const
{
return this->cobject();
}
template<class T, class Key, class Hash>
inline const T&
Foam::HashTable<T, Key, Hash>::iterator::operator()() const
{
return this->cobject();
}
template<class T, class Key, class Hash>
inline
typename Foam::HashTable<T, Key, Hash>::iterator&
inline typename Foam::HashTable<T, Key, Hash>::iterator&
Foam::HashTable<T, Key, Hash>::iterator::operator++()
{
this->increment();
@ -422,14 +371,6 @@ Foam::HashTable<T, Key, Hash>::iterator::operator++(int)
}
template<class T, class Key, class Hash>
inline typename Foam::HashTable<T, Key, Hash>::iterator
Foam::HashTable<T, Key, Hash>::begin()
{
return iterator(this);
}
// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
@ -452,17 +393,7 @@ inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
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
table_type* hashTbl
)
:
iteratorBase(hashTbl)
@ -472,8 +403,8 @@ inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
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,
table_type* hashTbl,
entry_type* elmt,
const label hashIndex
)
:
@ -481,11 +412,19 @@ inline Foam::HashTable<T, Key, Hash>::const_iterator::const_iterator
{}
template<class T, class Key, class Hash>
inline const T&
Foam::HashTable<T, Key, Hash>::const_iterator::object() const
{
return this->element();
}
template<class T, class Key, class Hash>
inline const T&
Foam::HashTable<T, Key, Hash>::const_iterator::operator*() const
{
return this->cobject();
return this->object();
}
@ -493,13 +432,12 @@ template<class T, class Key, class Hash>
inline const T&
Foam::HashTable<T, Key, Hash>::const_iterator::operator()() const
{
return this->cobject();
return this->object();
}
template<class T, class Key, class Hash>
inline
typename Foam::HashTable<T, Key, Hash>::const_iterator&
inline typename Foam::HashTable<T, Key, Hash>::const_iterator&
Foam::HashTable<T, Key, Hash>::const_iterator::operator++()
{
this->increment();
@ -517,6 +455,16 @@ Foam::HashTable<T, Key, Hash>::const_iterator::operator++(int)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline typename Foam::HashTable<T, Key, Hash>::iterator
Foam::HashTable<T, Key, Hash>::begin()
{
return iterator(this);
}
template<class T, class Key, class Hash>
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
Foam::HashTable<T, Key, Hash>::cbegin() const
@ -529,7 +477,37 @@ template<class T, class Key, class Hash>
inline typename Foam::HashTable<T, Key, Hash>::const_iterator
Foam::HashTable<T, Key, Hash>::begin() const
{
return this->cbegin();
return const_iterator(this);
}
template<class T, class Key, class Hash>
inline const typename Foam::HashTable<T, Key, Hash>::iterator&
Foam::HashTable<T, Key, Hash>::end()
{
using iter_type = typename HashTable<T, Key, Hash>::iterator;
return endIteratorRef<iter_type>();
}
template<class T, class Key, class Hash>
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
Foam::HashTable<T, Key, Hash>::cend() const
{
using iter_type = typename HashTable<T, Key, Hash>::const_iterator;
return endIteratorRef<iter_type>();
}
template<class T, class Key, class Hash>
inline const typename Foam::HashTable<T, Key, Hash>::const_iterator&
Foam::HashTable<T, Key, Hash>::end() const
{
using iter_type = typename HashTable<T, Key, Hash>::const_iterator;
return endIteratorRef<iter_type>();
}