ENH: HashPtrTable remove/erase now include safeguard against end-iterator

- This makes the following safe:

      auto iter = ptrTable.find(unknownKey);
      ptrTable.erase(iter);

- Unmask HashPtrTable::erase(const Key& key) method
This commit is contained in:
Mark Olesen
2017-05-15 09:57:25 +02:00
parent 4b0d1632b6
commit 6933bc3021
5 changed files with 80 additions and 27 deletions

View File

@ -36,14 +36,9 @@ void printTable(const HashPtrTable<T>& table)
{ {
Info<< table.size() << nl << "(" << nl; Info<< table.size() << nl << "(" << nl;
for forAllConstIters(table, iter)
(
typename HashPtrTable<T>::const_iterator iter = table.cbegin();
iter != table.cend();
++iter
)
{ {
const T* ptr = *iter; const T* ptr = iter.object();
Info<< iter.key() << " = "; Info<< iter.key() << " = ";
if (ptr) if (ptr)
{ {
@ -57,6 +52,22 @@ void printTable(const HashPtrTable<T>& table)
} }
Info<< ")" << endl; Info<< ")" << endl;
// Values only, with for-range
Info<< "values (";
for (auto val : table)
{
Info<< ' ';
if (val)
{
Info<< *val;
}
else
{
Info<< "nullptr";
}
}
Info<< " )" << nl;
} }
@ -68,7 +79,9 @@ int main()
HashPtrTable<double> myTable; HashPtrTable<double> myTable;
myTable.insert("abc", new double(42.1)); myTable.insert("abc", new double(42.1));
myTable.insert("def", nullptr); myTable.insert("def", nullptr);
myTable.insert("ghi", new double(3.14159)); myTable.insert("pi", new double(3.14159));
myTable.insert("natlog", new double(2.718282));
myTable.insert("sqrt2", new double(1.414214));
// Info<< myTable << endl; // Info<< myTable << endl;
printTable(myTable); printTable(myTable);
@ -79,8 +92,20 @@ int main()
printTable(copy); printTable(copy);
Info<< copy << endl; Info<< copy << endl;
Info<<"\nerase some existing and non-existing entries" << nl;
auto iter = myTable.find("pi");
myTable.erase(iter);
iter = myTable.find("unknownKey");
myTable.erase(iter);
myTable.erase("abc");
myTable.erase("unknownKey");
printTable(myTable);
return 0; return 0;
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -72,30 +72,44 @@ Foam::HashPtrTable<T, Key, Hash>::~HashPtrTable()
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& iter) T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& iter)
{ {
T* ptr = iter.object(); if (iter.found())
this->parent_type::erase(iter); {
return ptr; T* ptr = iter.object();
this->parent_type::erase(iter);
return ptr;
}
return nullptr;
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& iter) bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& iter)
{ {
T* ptr = iter.object(); if (iter.found())
if (this->parent_type::erase(iter))
{ {
if (ptr) T* ptr = iter.object();
if (this->parent_type::erase(iter))
{ {
delete ptr; if (ptr)
} {
delete ptr;
}
return true; return true;
} }
else
{
return false;
} }
return false;
}
template<class T, class Key, class Hash>
bool Foam::HashPtrTable<T, Key, Hash>::erase(const Key& key)
{
auto iter = this->find(key);
return this->erase(iter);
} }

View File

@ -116,12 +116,17 @@ public:
// Edit // Edit
//- Remove and return the pointer specified by given iterator //- Remove and return the pointer specified by given iterator.
// Includes a safeguard against the end-iterator.
T* remove(iterator& iter); T* remove(iterator& iter);
//- Erase an hashedEntry specified by given iterator //- Erase an entry specified by given iterator
// Includes a safeguard against the end-iterator.
bool erase(iterator& iter); bool erase(iterator& iter);
//- Erase an entry specified by the given key
bool erase(const Key& key);
//- Clear all entries from table //- Clear all entries from table
void clear(); void clear();

View File

@ -411,7 +411,8 @@ bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
bool Foam::HashTable<T, Key, Hash>::erase(const Key& key) bool Foam::HashTable<T, Key, Hash>::erase(const Key& key)
{ {
return erase(find(key)); auto iter = find(key);
return erase(iter);
} }

View File

@ -349,7 +349,15 @@ public:
inline bool set(const Key& key, const T& obj); inline bool set(const Key& key, const T& obj);
//- Erase an entry specified by given iterator //- Erase an entry specified by given iterator
// This invalidates the iterator until the next ++ operation // This invalidates the iterator until the next ++ operation.
//
// Includes a safeguard against the end-iterator such that the
// following is safe:
// \code
// auto iter = table.find(unknownKey);
// table.erase(iter);
// \endcode
// which is what \code table.erase(unknownKey) \endcode does anyhow
bool erase(const iterator& iter); bool erase(const iterator& iter);
//- Erase an entry specified by the given key //- Erase an entry specified by the given key