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

@ -177,6 +177,12 @@ int main()
Info<< "\ntable1" << table1 << nl;
Info<< "\nrange-for(table1)" << nl;
for (auto const& it : table1)
{
Info<< " " << it << nl;
}
Info<< "\nDone\n";
return 0;

View File

@ -45,7 +45,7 @@ Foam::HashPtrTable<T, Key, Hash>::HashPtrTable
{
for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
{
const T* ptr = *iter;
const T* ptr = iter.object();
if (ptr)
{
this->insert(iter.key(), new T(*ptr));
@ -72,7 +72,7 @@ Foam::HashPtrTable<T, Key, Hash>::~HashPtrTable()
template<class T, class Key, class Hash>
T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& iter)
{
T* ptr = *iter;
T* ptr = iter.object();
HashTable<T*, Key, Hash>::erase(iter);
return ptr;
}
@ -81,7 +81,7 @@ T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& iter)
template<class T, class Key, class Hash>
bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& iter)
{
T* ptr = *iter;
T* ptr = iter.object();
if (HashTable<T*, Key, Hash>::erase(iter))
{
@ -102,14 +102,9 @@ bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& iter)
template<class T, class Key, class Hash>
void Foam::HashPtrTable<T, Key, Hash>::clear()
{
for
(
iterator iter = this->begin();
iter != this->end();
++iter
)
for (iterator iter = this->begin(); iter != this->end(); ++iter)
{
delete *iter;
delete iter.object();
}
HashTable<T*, Key, Hash>::clear();
@ -136,7 +131,7 @@ void Foam::HashPtrTable<T, Key, Hash>::operator=
for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter)
{
const T* ptr = *iter;
const T* ptr = iter.object();
if (ptr)
{
this->insert(iter.key(), new T(*ptr));

View File

@ -54,7 +54,7 @@ template<class T, class Key, class Hash>
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);
Ostream& operator<<(Ostream& os, const HashPtrTable<T, Key, Hash>& tbl);
/*---------------------------------------------------------------------------*\
@ -80,8 +80,8 @@ class HashPtrTable
public:
typedef typename HashTable<T*, Key, Hash>::iterator iterator;
typedef typename HashTable<T*, Key, Hash>::const_iterator const_iterator;
using iterator = typename HashTable<T*, Key, Hash>::iterator;
using const_iterator = typename HashTable<T*, Key, Hash>::const_iterator;
// Constructors
@ -141,7 +141,7 @@ public:
friend Ostream& operator<< <T, Key, Hash>
(
Ostream& os,
const HashPtrTable<T, Key, Hash>& L
const HashPtrTable<T, Key, Hash>& tbl
);
};

View File

@ -157,16 +157,9 @@ void Foam::HashPtrTable<T, Key, Hash>::read
template<class T, class Key, class Hash>
void Foam::HashPtrTable<T, Key, Hash>::write(Ostream& os) const
{
for
(
typename HashPtrTable<T, Key, Hash>::const_iterator
iter = this->begin();
iter != this->end();
++iter
)
for (const_iterator iter = this->begin(); iter != this->end(); ++iter)
{
const T* ptr = *iter;
const T* ptr = iter.object();
if (ptr)
{
ptr->write(os);
@ -215,21 +208,18 @@ template<class T, class Key, class Hash>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const HashPtrTable<T, Key, Hash>& L
const HashPtrTable<T, Key, Hash>& tbl
)
{
using const_iterator = typename HashPtrTable<T, Key, Hash>::const_iterator;
// Write size and start delimiter
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
os << nl << tbl.size() << nl << token::BEGIN_LIST << nl;
// Write contents
for
(
typename HashPtrTable<T, Key, Hash>::const_iterator iter = L.begin();
iter != L.end();
++iter
)
for (const_iterator iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
{
const T* ptr = *iter;
const T* ptr = iter.object();
os << iter.key();
if (ptr)

View File

@ -117,20 +117,17 @@ template<class Key, class Hash>
template<class AnyType, class AnyHash>
Foam::HashSet<Key, Hash>::HashSet
(
const HashTable<AnyType, Key, AnyHash>& h
const HashTable<AnyType, Key, AnyHash>& tbl
)
:
HashTable<nil, Key, Hash>(h.size())
HashTable<nil, Key, Hash>(tbl.size())
{
for
(
typename HashTable<AnyType, Key, AnyHash>::const_iterator
cit = h.cbegin();
cit != h.cend();
++cit
)
using other_iter =
typename HashTable<AnyType, Key, AnyHash>::const_iterator;
for (other_iter iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
{
this->insert(cit.key());
this->insert(iter.key());
}
}

View File

@ -132,12 +132,12 @@ public:
//- Construct from the keys of another HashTable,
// the type of values held is arbitrary.
template<class AnyType, class AnyHash>
explicit HashSet(const HashTable<AnyType, Key, AnyHash>& h);
explicit HashSet(const HashTable<AnyType, Key, AnyHash>& tbl);
// Member Functions
// Edit
// Edit
//- Insert a new entry
bool insert(const Key& key)

View File

@ -76,7 +76,7 @@ Foam::HashTable<T, Key, Hash>::HashTable(const label size)
for (label hashIdx = 0; hashIdx < tableSize_; hashIdx++)
{
table_[hashIdx] = 0;
table_[hashIdx] = nullptr;
}
}
}
@ -89,7 +89,7 @@ Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
{
for (const_iterator iter = ht.cbegin(); iter != ht.cend(); ++iter)
{
insert(iter.key(), *iter);
insert(iter.key(), iter.object());
}
}
@ -268,8 +268,8 @@ bool Foam::HashTable<T, Key, Hash>::set
const label hashIdx = hashKeyIndex(key);
hashedEntry* existing = 0;
hashedEntry* prev = 0;
hashedEntry* existing = nullptr;
hashedEntry* prev = nullptr;
for (hashedEntry* ep = table_[hashIdx]; ep; ep = ep->next_)
{
@ -281,10 +281,10 @@ bool Foam::HashTable<T, Key, Hash>::set
prev = ep;
}
// Not found, insert it at the head
if (!existing)
{
table_[hashIdx] = new hashedEntry(key, table_[hashIdx], newEntry);
// Not found, insert it at the head
table_[hashIdx] = new hashedEntry(key, newEntry, table_[hashIdx]);
nElmts_++;
if (double(nElmts_)/tableSize_ > 0.8 && tableSize_ < maxTableSize)
@ -316,7 +316,7 @@ bool Foam::HashTable<T, Key, Hash>::set
{
// Found - overwrite existing entry
// this corresponds to the Perl convention
hashedEntry* ep = new hashedEntry(key, existing->next_, newEntry);
hashedEntry* ep = new hashedEntry(key, newEntry, existing->next_);
// Replace existing element - within list or insert at the head
if (prev)
@ -342,11 +342,11 @@ bool Foam::HashTable<T, Key, Hash>::iteratorBase::erase()
if (entryPtr_)
{
// Search element before entryPtr_
hashedEntry* prev = 0;
entry_type* prev = nullptr;
for
(
hashedEntry* ep = hashTable_->table_[hashIndex_];
entry_type* ep = hashTable_->table_[hashIndex_];
ep;
ep = ep->next_
)
@ -371,8 +371,7 @@ bool Foam::HashTable<T, Key, Hash>::iteratorBase::erase()
hashTable_->table_[hashIndex_] = entryPtr_->next_;
delete entryPtr_;
// Assign any non-nullptr value so it doesn't look
// like end()/cend()
// Assign any non-nullptr value so it doesn't look like end()
entryPtr_ = reinterpret_cast<hashedEntry*>(this);
// Mark with special hashIndex value to signal it has been rewound.
@ -547,7 +546,7 @@ void Foam::HashTable<T, Key, Hash>::clear()
ep = next;
}
delete ep;
table_[hashIdx] = 0;
table_[hashIdx] = nullptr;
}
}
nElmts_ = 0;
@ -625,7 +624,7 @@ void Foam::HashTable<T, Key, Hash>::operator=
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
{
insert(iter.key(), *iter);
insert(iter.key(), iter.object());
}
}
@ -667,9 +666,9 @@ bool Foam::HashTable<T, Key, Hash>::operator==
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
{
const_iterator fnd = find(iter.key());
const_iterator other = find(iter.key());
if (fnd == cend() || fnd() != iter())
if (!other.found() || other.object() != iter.object())
{
return false;
}

View File

@ -37,6 +37,7 @@ Note
SourceFiles
HashTableI.H
HashTable.C
HashTableCore.C
HashTableIO.C
\*---------------------------------------------------------------------------*/
@ -49,6 +50,8 @@ SourceFiles
#include "word.H"
#include "Xfer.H"
#include "className.H"
#include "nullObject.H"
#include <initializer_list>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -71,16 +74,26 @@ template<class T, class Key, class Hash>
Istream& operator>>(Istream& is, HashTable<T, Key, Hash>& L);
template<class T, class Key, class Hash>
Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& L);
Ostream& operator<<(Ostream& os, const HashTable<T, Key, Hash>& tbl);
/*---------------------------------------------------------------------------*\
Class HashTableCore Declaration
Class HashTableCore Declaration
\*---------------------------------------------------------------------------*/
//- Template-invariant bits for HashTable
struct HashTableCore
//- Template-invariant bits for HashTable.
// This also includes a global end-iterator.
//
// The end iterator of all hash-tables has a nullptr to the hash entry.
// Thus avoid separate allocation for each table and use a single one with
// a nullptr.
// The hash-table iterators always have this as its first member data,
// so we can reinterpret_cast from anything else that has a nullptr for its
// first data member. This is now also the case for the NullObject.
class HashTableCore
{
public:
//- Return a canonical (power-of-two) size
static label canonicalSize(const label size);
@ -94,24 +107,20 @@ struct 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();
}
protected:
//- iteratorEnd set to beyond the end of any HashTable
inline static iteratorEnd end()
static_assert
(
sizeof(NullObject) >= sizeof(void*),
"NullObject is too small to reinterpret_cast as HashTable::iterator"
);
//- Reinterpret a NullObject as a hash-table iterator.
template<class Iterator>
inline static const Iterator& endIteratorRef()
{
return iteratorEnd();
return *reinterpret_cast<const Iterator*>(nullObjectPtr);
}
};
@ -133,14 +142,14 @@ class HashTable
//- The lookup key
Key key_;
//- Pointer to next hashedEntry in sub-list
hashedEntry* next_;
//- The data object
T obj_;
//- Pointer to next hashedEntry in sub-list
hashedEntry* next_;
//- Construct from key, next pointer and object
inline hashedEntry(const Key& key, hashedEntry* next, const T& obj);
inline hashedEntry(const Key& key, const T& obj, hashedEntry* next);
private:
@ -170,7 +179,7 @@ class HashTable
// No checks for zero-sized tables.
inline label hashKeyIndex(const Key& key) const;
//- Assign a new hashedEntry to a possibly already existing key.
//- Assign a new hash-entry to a possibly already existing key.
// Return true if the new entry was set.
bool set(const Key& key, const T& newEntry, const bool protect);
@ -187,6 +196,7 @@ protected:
const InputIter endIter
);
public:
// Forward declaration of iterators
@ -195,19 +205,9 @@ public:
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;
//- Declare friendship with the iterator
friend class iterator;
//- Declare friendship with the const_iterator
friend class const_iterator;
// Constructors
@ -351,10 +351,12 @@ public:
bool operator!=(const HashTable<T, Key, Hash>& rhs) const;
// STL type definitions
//- Type of values the HashTable contains.
//- Type of keys that the HashTable uses.
typedef Key key_type;
//- Type of values that the HashTable contains.
typedef T value_type;
//- Type that can be used for storing into HashTable::value_type
@ -370,6 +372,27 @@ public:
typedef label size_type;
// Iterator access
//- Iterator set to the beginning of the HashTable
inline iterator begin();
//- const_iterator set to the beginning of the HashTable
inline const_iterator begin() const;
//- const_iterator set to the beginning of the HashTable
inline const_iterator cbegin() const;
//- iterator to signal the end for any HashTable
inline const iterator& end();
//- const_iterator to signal the end for any HashTable
inline const const_iterator& end() const;
//- const_iterator to signal the end for any HashTable
inline const const_iterator& cend() const;
// Iterators and helpers
//- The iterator base for HashTable
@ -379,133 +402,125 @@ public:
// us to reinterpret_cast between them (if desired)
class iteratorBase
{
// Private Data
using entry_type = hashedEntry;
//- Pointer to the HashTable for which this is an iterator
// This allows use of the default bitwise copy/assignment
HashTable<T, Key, Hash>* hashTable_;
public:
// Public typedefs
using table_type = HashTable<T, Key, Hash>;
using key_type = HashTable<T, Key, Hash>::key_type;
//- Current element
hashedEntry* entryPtr_;
private:
//- Current hash index
label hashIndex_;
// Private Data
//- Currently selected entry.
// MUST be the first member for easy comparison between iterators
// and for reinterpret_cast from nullObject
entry_type* entryPtr_;
//- Pointer to the hash-table for which this is an iterator
// This allows use of the default bitwise copy/assignment
table_type* hashTable_;
//- Current hash index within the hash-table data.
// A signed value, since erase() uses a negative value to signal
// the erasure state.
label hashIndex_;
protected:
// Constructors
// Protected Member Functions
//- Construct null - equivalent to an 'end' position
inline iteratorBase();
//- Increment to the next position
inline void increment();
//- Construct from hash table, moving to its 'begin' position
inline explicit iteratorBase
(
const HashTable<T, Key, Hash>* hashTbl
);
//- Erase the entry at the current position
bool erase();
//- Construct from hash table, element and hash index
inline iteratorBase
(
const HashTable<T, Key, Hash>* hashTbl,
const hashedEntry* elmt,
const label hashIndex
);
//- The referenced object/value element
inline T& element() const;
// 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();
public:
// Member operators
// Constructors
// Access
//- Construct null (end iterator)
inline iteratorBase();
//- True if iterator points to a hashedEntry.
// This can be used instead of a comparison to end()
inline bool found() const;
//- Construct from begin of hash-table
inline explicit iteratorBase(const table_type* hashTbl);
//- Return the Key corresponding to the iterator
inline const Key& key() const;
//- Construct from hash table, element and hash index
inline iteratorBase
(
const table_type* hashTbl,
const entry_type* elmt,
const label hashIndex
);
//- Return const access to referenced object
inline const T& cobject() const;
// Member functions/operators
//- Compare hashedEntry element pointers
inline bool operator==(const iteratorBase& iter) const;
inline bool operator!=(const iteratorBase& iter) const;
//- True if iterator points to an entry
// This can be used directly instead of comparing to end()
inline bool found() const;
//- Compare hashedEntry to iteratorEnd pointers
inline bool operator==(const iteratorEnd& unused) const;
inline bool operator!=(const iteratorEnd& unused) const;
//- Return the Key corresponding to the iterator
inline const Key& key() const;
//- Compare hash-entry element pointers
inline bool operator==(const iteratorBase& iter) const;
inline bool operator!=(const iteratorBase& iter) const;
};
// STL iterator
//- 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>* hashTbl
);
//- Construct from hash table, element and hash index
inline iterator
(
HashTable<T, Key, Hash>* hashTbl,
hashedEntry* elmt,
const label hashIndex
);
friend class HashTable; // uses iterator::erase() method
using entry_type = hashedEntry;
public:
// Constructors
// Public typedefs
using table_type = HashTable<T, Key, Hash>;
using key_type = HashTable<T, Key, Hash>::key_type;
using reference = HashTable<T, Key, Hash>::reference;
//- Construct null (end iterator)
inline iterator();
// Constructors
//- Construct end iterator
inline iterator(const iteratorEnd& unused);
//- Construct null (end iterator)
inline iterator();
//- Construct from begin of hash-table
inline explicit iterator(table_type* hashTbl);
// Member operators
//- Construct from hash table, element and hash index
// Used by the hash-table find() method.
inline iterator
(
table_type* hashTbl,
entry_type* elmt,
const label hashIndex
);
//- Return non-const access to referenced object
using iteratorBase::object;
// Member functions/operators
//- Return non-const access to referenced object
inline T& operator*();
inline T& operator()();
//- Return non-const access to referenced object
inline reference object() const;
//- Return const access to referenced object
inline const T& operator*() const;
inline const T& operator()() const;
//- Return non-const access to referenced object
inline reference operator*() const;
inline reference operator()() const;
inline iterator& operator++();
inline iterator operator++(int);
inline iterator& operator++();
inline iterator operator++(int);
};
//- Iterator set to the beginning of the HashTable
inline iterator begin();
// STL const_iterator
@ -514,56 +529,49 @@ public:
:
public iteratorBase
{
friend class HashTable;
// Private Member Functions
//- Construct from hash table, moving to its 'begin' position
inline explicit const_iterator
(
const HashTable<T, Key, Hash>* hashTbl
);
//- Construct from hash table, element and hash index
inline const_iterator
(
const HashTable<T, Key, Hash>* hashTbl,
const hashedEntry* elmt,
const label hashIndex
);
using entry_type = const hashedEntry;
public:
// Constructors
// Public typedefs
using table_type = const HashTable<T, Key, Hash>;
using key_type = HashTable<T, Key, Hash>::key_type;
using reference = HashTable<T, Key, Hash>::const_reference;
//- Construct null (end iterator)
inline const_iterator();
// Constructors
//- Construct from iterator
inline const_iterator(const iterator& iter);
//- Construct null (end iterator)
inline const_iterator();
//- Construct end iterator
inline const_iterator(const iteratorEnd& unused);
//- Construct from begin of hash-table
inline explicit const_iterator(table_type* hashTbl);
//- Construct from hash table, element and hash index.
// Used by the hash-table find() method.
inline const_iterator
(
table_type* hashTbl,
entry_type* elmt,
const label hashIndex
);
// Member operators
//- Copy construct from iterator
inline const_iterator(const iterator& iter);
//- Return const access to referenced object
inline const T& operator*() const;
inline const T& operator()() const;
// Member functions/operators
inline const_iterator& operator++();
inline const_iterator operator++(int);
//- Return const access to referenced object
inline reference object() const;
//- Return const access to referenced object
inline reference operator*() const;
inline reference operator()() const;
inline const_iterator& operator++();
inline const_iterator operator++(int);
};
//- const_iterator set to the beginning of the HashTable
inline const_iterator cbegin() const;
//- const_iterator set to the beginning of the HashTable
inline const_iterator begin() const;
// IOstream Operator
@ -576,7 +584,7 @@ public:
friend Ostream& operator<< <T, Key, Hash>
(
Ostream& os,
const HashTable<T, Key, Hash>& L
const HashTable<T, Key, Hash>& tbl
);
};
@ -587,7 +595,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "HashTableI.H"
#include "HashTableI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

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>();
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -43,7 +43,7 @@ Foam::HashTable<T, Key, Hash>::HashTable(Istream& is, const label size)
for (label hashIdx = 0; hashIdx < tableSize_; ++hashIdx)
{
table_[hashIdx] = 0;
table_[hashIdx] = nullptr;
}
}
@ -215,21 +215,18 @@ template<class T, class Key, class Hash>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const HashTable<T, Key, Hash>& L
const HashTable<T, Key, Hash>& tbl
)
{
using const_iterator = typename HashTable<T, Key, Hash>::const_iterator;
// Write size and start delimiter
os << nl << L.size() << nl << token::BEGIN_LIST << nl;
os << nl << tbl.size() << nl << token::BEGIN_LIST << nl;
// Write contents
for
(
typename HashTable<T, Key, Hash>::const_iterator iter = L.cbegin();
iter != L.cend();
++iter
)
for (const_iterator iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
{
os << iter.key() << token::SPACE << iter() << nl;
os << iter.key() << token::SPACE << iter.object() << nl;
}
// Write end delimiter

View File

@ -119,9 +119,6 @@ class StaticHashTable
//- The current number of elements in table
label nElmts_;
//- Return a canonical (power-of-two) size
static label canonicalSize(const label);
//- Return the hash index of the Key within the current table size.
// No checks for zero-sized tables.
inline label hashKeyIndex(const Key&) const;
@ -397,7 +394,7 @@ private:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "StaticHashTableI.H"
#include "StaticHashTableI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //