ENH: add HashTable zero-size construct, move construct is noexcept

BUG: HashTable::operator+= self-assignment check was being ignored

STYLE: minor code cleanup for templated Dictionary types
This commit is contained in:
Mark Olesen
2023-07-20 10:23:23 +02:00
parent 8117cde596
commit 7cae3b9660
28 changed files with 298 additions and 393 deletions

View File

@ -1,64 +1 @@
/*---------------------------------------------------------------------------*\ #warning File removed - left for old dependency check only
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "Dictionary.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
Foam::Dictionary<T>::Dictionary(const label size)
:
DictionaryBase<IDLList<T>, T>(size)
{}
template<class T>
Foam::Dictionary<T>::Dictionary(const Dictionary& dict)
:
DictionaryBase<IDLList<T>, T>(dict)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
bool Foam::Dictionary<T>::erase(const word& keyword)
{
T* ptr = this->remove(keyword);
if (ptr)
{
delete ptr;
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -34,13 +34,10 @@ Description
It is derived from DictionaryBase instantiated on a memory managed form It is derived from DictionaryBase instantiated on a memory managed form
of intrusive doubly-linked list of \<T\>. of intrusive doubly-linked list of \<T\>.
SourceFiles
Dictionary.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Dictionary_H #ifndef Foam_Dictionary_H
#define Dictionary_H #define Foam_Dictionary_H
#include "DictionaryBase.H" #include "DictionaryBase.H"
#include "IDLList.H" #include "IDLList.H"
@ -61,35 +58,43 @@ class Dictionary
{ {
public: public:
//- The template instance used for the dictionary content
typedef DictionaryBase<IDLList<T>, T> dict_type;
// Constructors // Constructors
//- Construct with given or default (128) table capacity //- Default construct, or with initial table capacity
explicit Dictionary(const label size = 128); explicit Dictionary(const label initialCapacity = 128)
:
dict_type(initialCapacity)
{}
//- Copy construct //- Copy construct
Dictionary(const Dictionary& dict); Dictionary(const Dictionary& dict)
:
dict_type(dict)
{}
// Member Functions // Member Functions
//- Remove an entry specified by keyword and delete the pointer. //- Remove an entry specified by keyword and delete the pointer.
// \return true if the keyword was found // \return true if the keyword was found
bool erase(const word& keyword); bool erase(const word& keyword)
{
T* ptr = this->remove(keyword);
delete ptr;
return bool(ptr);
}
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "Dictionary.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -42,13 +42,6 @@ void Foam::DictionaryBase<IDLListType, T>::addEntries()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class IDLListType, class T>
Foam::DictionaryBase<IDLListType, T>::DictionaryBase(const label size)
:
hashedTs_(size)
{}
template<class IDLListType, class T> template<class IDLListType, class T>
Foam::DictionaryBase<IDLListType, T>::DictionaryBase Foam::DictionaryBase<IDLListType, T>::DictionaryBase
( (
@ -156,34 +149,6 @@ T* Foam::DictionaryBase<IDLListType, T>::lookup(const word& keyword)
} }
template<class IDLListType, class T>
Foam::wordList Foam::DictionaryBase<IDLListType, T>::toc() const
{
// Cannot rely on the items themselves having a keyword() method
// so simply return the toc() from the hashed entries
// Make it sorted, since anything else would have no meaning.
return hashedTs_.sortedToc();
}
template<class IDLListType, class T>
Foam::wordList Foam::DictionaryBase<IDLListType, T>::sortedToc() const
{
return hashedTs_.sortedToc();
}
template<class IDLListType, class T>
template<class Compare>
Foam::wordList Foam::DictionaryBase<IDLListType, T>::sortedToc
(
const Compare& comp
) const
{
return hashedTs_.sortedToc(comp);
}
template<class IDLListType, class T> template<class IDLListType, class T>
void Foam::DictionaryBase<IDLListType, T>::push_front void Foam::DictionaryBase<IDLListType, T>::push_front
( (
@ -191,9 +156,9 @@ void Foam::DictionaryBase<IDLListType, T>::push_front
T* ptr T* ptr
) )
{ {
IDLListType::push_front(ptr);
// NOTE: we should probably check that HashTable::insert actually worked // NOTE: we should probably check that HashTable::insert actually worked
hashedTs_.insert(keyword, ptr); hashedTs_.insert(keyword, ptr);
IDLListType::push_front(ptr);
} }
@ -213,16 +178,15 @@ void Foam::DictionaryBase<IDLListType, T>::push_back
template<class IDLListType, class T> template<class IDLListType, class T>
T* Foam::DictionaryBase<IDLListType, T>::remove(const word& keyword) T* Foam::DictionaryBase<IDLListType, T>::remove(const word& keyword)
{ {
T* ptr = nullptr;
auto iter = hashedTs_.find(keyword); auto iter = hashedTs_.find(keyword);
if (iter.good()) if (iter.good())
{ {
T* ptr = IDLListType::remove(iter.val()); ptr = IDLListType::remove(iter.val());
hashedTs_.erase(iter); hashedTs_.erase(iter);
return ptr;
} }
return ptr;
return nullptr;
} }
@ -269,8 +233,4 @@ void Foam::DictionaryBase<IDLListType, T>::operator=
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "DictionaryBaseIO.C"
// ************************************************************************* // // ************************************************************************* //

View File

@ -87,7 +87,13 @@ protected:
// Protected Member Functions // Protected Member Functions
// Add the IDLListType entries into the HashTable //- Add an entry to the HashTable
bool addHashEntry(const word& key, T* ptr)
{
return hashedTs_.insert(key, ptr);
}
//- Add the IDLListType entries into the HashTable
void addEntries(); void addEntries();
@ -96,7 +102,10 @@ public:
// Constructors // Constructors
//- Construct with given or default (128) table capacity //- Construct with given or default (128) table capacity
explicit DictionaryBase(const label size = 128); explicit DictionaryBase(const label initialCapacity = 128)
:
hashedTs_(initialCapacity)
{}
//- Copy construct //- Copy construct
DictionaryBase(const DictionaryBase& dict); DictionaryBase(const DictionaryBase& dict);
@ -128,15 +137,24 @@ public:
//- Find and return entry, FatalError on failure. //- Find and return entry, FatalError on failure.
T* lookup(const word& keyword); T* lookup(const word& keyword);
//- Return the table of contents (as a sorted list) //- The table of contents (as a sorted list)
wordList toc() const; wordList toc() const
{
return hashedTs_.sortedToc();
}
//- Return the table of contents as a sorted list //- The table of contents as a sorted list
wordList sortedToc() const; wordList sortedToc() const
{
return hashedTs_.sortedToc();
}
//- Return table of contents sorted using the specified comparator //- The table of contents sorted using the specified comparator
template<class Compare> template<class Compare>
wordList sortedToc(const Compare& comp) const; wordList sortedToc(const Compare& comp) const
{
return hashedTs_.sortedToc(comp);
}
// Editing // Editing
@ -194,39 +212,24 @@ public:
//- Deprecated(2020-03) use cfind() //- Deprecated(2020-03) use cfind()
// \deprecated(2020-03) - use cfind() method // \deprecated(2020-03) - use cfind() method
FOAM_DEPRECATED_FOR(2020-03, "cfind() method") FOAM_DEPRECATED_FOR(2020-03, "cfind() method")
const T* lookupPtr(const word& keyword) const const T* lookupPtr(const word& k) const { return this->cfind(k); }
{
return this->cfind(keyword);
}
//- Deprecated(2020-03) use find() //- Deprecated(2020-03) use find()
// \deprecated(2020-03) - use find() method // \deprecated(2020-03) - use find() method
FOAM_DEPRECATED_FOR(2020-03, "find() method") FOAM_DEPRECATED_FOR(2020-03, "find() method")
T* lookupPtr(const word& keyword) T* lookupPtr(const word& k) { return this->find(k); }
{
return this->find(keyword);
}
//- Add to front of dictionary //- Add to front of dictionary
//FOAM_DEPRECATED_FOR(2022-10, "push_front()") //FOAM_DEPRECATED_FOR(2022-10, "push_front()")
void insert(const word& keyword, T* ptr) void insert(const word& k, T* ptr) { this->push_front(k, ptr); }
{
this->push_front(keyword, ptr);
}
//- Add to front of dictionary //- Add to front of dictionary
//FOAM_DEPRECATED_FOR(2022-10, "push_front()") //FOAM_DEPRECATED_FOR(2022-10, "push_front()")
void prepend(const word& keyword, T* ptr) void prepend(const word& k, T* ptr) { this->push_front(k, ptr); }
{
this->push_front(keyword, ptr);
}
//- Add to back of dictionary //- Add to back of dictionary
//FOAM_DEPRECATED_FOR(2022-10, "push_back()") //FOAM_DEPRECATED_FOR(2022-10, "push_back()")
void append(const word& keyword, T* ptr) void append(const word& k, T* ptr) { this->push_back(k, ptr); }
{
this->push_back(keyword, ptr);
}
}; };
@ -238,6 +241,7 @@ public:
#ifdef NoRepository #ifdef NoRepository
#include "DictionaryBase.C" #include "DictionaryBase.C"
#include "DictionaryBaseIO.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -35,9 +35,10 @@ template<class IDLListType, class T>
Foam::Ostream& Foam::operator<< Foam::Ostream& Foam::operator<<
( (
Ostream& os, Ostream& os,
const DictionaryBase<IDLListType, T>& dict) const DictionaryBase<IDLListType, T>& dict
)
{ {
for (auto iter = dict.begin(); iter != dict.end(); ++iter) for (auto iter = dict.cbegin(); iter != dict.cend(); ++iter)
{ {
os << *iter; os << *iter;

View File

@ -56,31 +56,35 @@ class PtrDictionary
{ {
public: public:
//- The template instance used for the dictionary content
typedef DictionaryBase<DLPtrList<T>, T> dict_type;
// Constructors // Constructors
//- Construct given initial table size //- Default construct, or with initial table capacity
explicit PtrDictionary(const label size = 128) explicit PtrDictionary(const label initialCapacity = 128)
: :
DictionaryBase<DLPtrList<T>, T>(size) dict_type(initialCapacity)
{} {}
//- Copy construct //- Copy construct
PtrDictionary(const PtrDictionary& dict) PtrDictionary(const PtrDictionary& dict)
: :
DictionaryBase<DLPtrList<T>, T>(dict) dict_type(dict)
{} {}
//- Construct from Istream using given Istream constructor class //- Construct from Istream using given Istream constructor class
template<class INew> template<class INew>
PtrDictionary(Istream& is, const INew& inew) PtrDictionary(Istream& is, const INew& inew)
: :
DictionaryBase<DLPtrList<T>, T>(is, inew) dict_type(is, inew)
{} {}
//- Construct from Istream //- Construct from Istream
explicit PtrDictionary(Istream& is) explicit PtrDictionary(Istream& is)
: :
DictionaryBase<DLPtrList<T>, T>(is) dict_type(is)
{} {}
@ -89,13 +93,13 @@ public:
//- Find and return entry //- Find and return entry
const T& operator[](const word& key) const const T& operator[](const word& key) const
{ {
return *DictionaryBase<DLPtrList<T>, T>::operator[](key); return *(dict_type::lookup(key));
} }
//- Find and return entry //- Find and return entry
T& operator[](const word& key) T& operator[](const word& key)
{ {
return *DictionaryBase<DLPtrList<T>, T>::operator[](key); return *(dict_type::lookup(key));
} }
}; };

View File

@ -32,7 +32,7 @@ License
template<class T> template<class T>
Foam::PtrListDictionary<T>::PtrListDictionary(const label size) Foam::PtrListDictionary<T>::PtrListDictionary(const label size)
: :
DictionaryBase<PtrList<T>, T>(2*size) dict_type(2*size)
{ {
PtrList<T>::resize(size); PtrList<T>::resize(size);
} }
@ -41,7 +41,7 @@ Foam::PtrListDictionary<T>::PtrListDictionary(const label size)
template<class T> template<class T>
Foam::PtrListDictionary<T>::PtrListDictionary(const PtrListDictionary& dict) Foam::PtrListDictionary<T>::PtrListDictionary(const PtrListDictionary& dict)
: :
DictionaryBase<PtrList<T>, T>(dict) dict_type(dict)
{} {}
@ -49,14 +49,14 @@ template<class T>
template<class INew> template<class INew>
Foam::PtrListDictionary<T>::PtrListDictionary(Istream& is, const INew& iNew) Foam::PtrListDictionary<T>::PtrListDictionary(Istream& is, const INew& iNew)
: :
DictionaryBase<PtrList<T>, T>(is, iNew) dict_type(is, iNew)
{} {}
template<class T> template<class T>
Foam::PtrListDictionary<T>::PtrListDictionary(Istream& is) Foam::PtrListDictionary<T>::PtrListDictionary(Istream& is)
: :
DictionaryBase<PtrList<T>, T>(is) dict_type(is)
{} {}
@ -70,13 +70,16 @@ inline Foam::autoPtr<T> Foam::PtrListDictionary<T>::set
T* ptr T* ptr
) )
{ {
if (!DictionaryBase<PtrList<T>, T>::hashedTs_.insert(key, ptr)) autoPtr<T> old(PtrList<T>::set(i, ptr));
if (!dict_type::addHashEntry(key, ptr))
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cannot insert with key '" << key << "' into hash-table" << "Cannot insert with key '" << key << "' into hash-table"
<< abort(FatalError); << abort(FatalError);
} }
return PtrList<T>::set(i, ptr);
return old;
} }
@ -85,17 +88,10 @@ inline Foam::autoPtr<T> Foam::PtrListDictionary<T>::set
( (
const label i, const label i,
const word& key, const word& key,
autoPtr<T>& aptr autoPtr<T>& ptr
) )
{ {
T* ptr = aptr.ptr(); return this->set(i, key, ptr.release());
if (!DictionaryBase<PtrList<T>, T>::hashedTs_.insert(key, ptr))
{
FatalErrorInFunction
<< "Cannot insert with key '" << key << "' into hash-table"
<< abort(FatalError);
}
return PtrList<T>::set(i, ptr);
} }
@ -104,17 +100,10 @@ inline Foam::autoPtr<T> Foam::PtrListDictionary<T>::set
( (
const label i, const label i,
const word& key, const word& key,
tmp<T>& t tmp<T>& ptr
) )
{ {
T* ptr = t.ptr(); return this->set(i, key, ptr.ptr()); // release or clone
if (!DictionaryBase<PtrList<T>, T>::hashedTs_.insert(key, ptr))
{
FatalErrorInFunction
<< "Cannot insert with key '" << key << "' into hash-table"
<< abort(FatalError);
}
return PtrList<T>::set(i, ptr);
} }

View File

@ -59,6 +59,10 @@ class PtrListDictionary
{ {
public: public:
//- The template instance used for the dictionary content
typedef DictionaryBase<PtrList<T>, T> dict_type;
// Constructors // Constructors
//- Construct given initial list size //- Construct given initial list size
@ -81,26 +85,26 @@ public:
autoPtr<T> set(const label i, const word& key, T* ptr); autoPtr<T> set(const label i, const word& key, T* ptr);
//- Set element to autoPtr value provided and return old element //- Set element to autoPtr value provided and return old element
autoPtr<T> set(const label i, const word& key, autoPtr<T>& aptr); autoPtr<T> set(const label i, const word& key, autoPtr<T>& ptr);
//- Set element to tmp value provided and return old element //- Set element to tmp value provided and return old element
autoPtr<T> set(const label i, const word& key, tmp<T>& t); autoPtr<T> set(const label i, const word& key, tmp<T>& ptr);
// Member operators // Member Operators
using PtrList<T>::operator[]; using PtrList<T>::operator[];
//- Find and return entry //- Find and return entry
const T& operator[](const word& key) const const T& operator[](const word& key) const
{ {
return *DictionaryBase<PtrList<T>, T>::operator[](key); return *(dict_type::lookup(key));
} }
//- Find and return entry //- Find and return entry
T& operator[](const word& key) T& operator[](const word& key)
{ {
return *DictionaryBase<PtrList<T>, T>::operator[](key); return *(dict_type::lookup(key));
} }
}; };

View File

@ -1,46 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "UDictionary.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
Foam::UDictionary<T>::UDictionary()
{}
template<class T>
Foam::UDictionary<T>::UDictionary(const UDictionary& dict)
:
DictionaryBase<UIDLList<T>, T>(dict)
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -33,13 +33,10 @@ Description
It is derived from DictionaryBase instantiated on a non-memory managed It is derived from DictionaryBase instantiated on a non-memory managed
form of intrusive doubly-linked list of \<T\>. form of intrusive doubly-linked list of \<T\>.
SourceFiles
UDictionary.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef UDictionary_H #ifndef Foam_UDictionary_H
#define UDictionary_H #define Foam_UDictionary_H
#include "DictionaryBase.H" #include "DictionaryBase.H"
#include "UIDLList.H" #include "UIDLList.H"
@ -58,16 +55,25 @@ class UDictionary
: :
public DictionaryBase<UIDLList<T>, T> public DictionaryBase<UIDLList<T>, T>
{ {
public: public:
//- The template instance used for the dictionary content
typedef DictionaryBase<UIDLList<T>, T> dict_type;
// Constructors // Constructors
//- Null constructor //- Default construct, or with initial table capacity
UDictionary(); explicit UDictionary(const label initialCapacity = 128)
:
dict_type(initialCapacity)
{}
//- Copy construct //- Copy construct
UDictionary(const UDictionary&); UDictionary(const UDictionary& dict)
:
dict_type(dict)
{}
}; };
@ -77,12 +83,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "UDictionary.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -57,18 +57,22 @@ class UPtrDictionary
{ {
public: public:
//- The template instance used for the dictionary content
typedef DictionaryBase<DLList<T*>, T> dict_type;
// Constructors // Constructors
//- Construct given initial table size //- Default construct, or with initial table capacity
explicit UPtrDictionary(const label size = 128) explicit UPtrDictionary(const label initialCapacity = 128)
: :
DictionaryBase<DLList<T*>, T>(size) dict_type(initialCapacity)
{} {}
//- Copy construct //- Copy construct
UPtrDictionary(const UPtrDictionary& dict) UPtrDictionary(const UPtrDictionary& dict)
: :
DictionaryBase<DLList<T*>, T>(dict) dict_type(dict)
{} {}
}; };

View File

@ -96,14 +96,26 @@ public:
//- Default construct with default table capacity //- Default construct with default table capacity
HashPtrTable() = default; HashPtrTable() = default;
//- Construct with zero table capacity
explicit HashPtrTable(const Foam::zero) noexcept
:
parent_type(Foam::zero{})
{}
//- Construct given initial table capacity //- Construct given initial table capacity
inline explicit HashPtrTable(const label size); explicit HashPtrTable(const label initialCapacity)
:
parent_type(initialCapacity)
{}
//- Copy construct, making a copy of each element //- Copy construct, making a copy of each element
HashPtrTable(const this_type& rhs); HashPtrTable(const this_type& rhs);
//- Move construct //- Move construct
inline HashPtrTable(this_type&& rhs); HashPtrTable(this_type&& rhs) noexcept
:
parent_type(std::move(rhs))
{}
//- Construct from Istream using given Istream constructor class //- Construct from Istream using given Istream constructor class
template<class INew> template<class INew>

View File

@ -29,25 +29,6 @@ License
#include "refPtr.H" #include "refPtr.H"
#include "tmp.H" #include "tmp.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
inline Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(const label size)
:
parent_type(size)
{}
template<class T, class Key, class Hash>
inline Foam::HashPtrTable<T, Key, Hash>::HashPtrTable
(
HashPtrTable<T, Key, Hash>&& rhs
)
:
parent_type(std::move(rhs))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class Key, class Hash> template<class T, class Key, class Hash>

View File

@ -287,8 +287,12 @@ void Foam::HashSet<Key, Hash>::operator=(std::initializer_list<Key> rhs)
template<class Key, class Hash> template<class Key, class Hash>
bool Foam::HashSet<Key, Hash>::operator==(const HashSet<Key, Hash>& rhs) const bool Foam::HashSet<Key, Hash>::operator==(const HashSet<Key, Hash>& rhs) const
{ {
// Sizes (number of keys) must match // Trivial checks first
if (this->size() != rhs.size()) if (this == &rhs)
{
return true;
}
else if (this->size() != rhs.size())
{ {
return false; return false;
} }
@ -316,10 +320,13 @@ template<class Key, class Hash>
Foam::HashSet<Key, Hash>& Foam::HashSet<Key, Hash>&
Foam::HashSet<Key, Hash>::operator|=(const HashSet<Key, Hash>& rhs) Foam::HashSet<Key, Hash>::operator|=(const HashSet<Key, Hash>& rhs)
{ {
// Add rhs elements into lhs // Add rhs elements into lhs - avoid no-ops
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter) if (this != &rhs)
{ {
this->insert(iter.key()); for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
{
this->insert(iter.key());
}
} }
return *this; return *this;

View File

@ -124,10 +124,19 @@ public:
// Constructors // Constructors
//- Default construct with default (128) table capacity //- Default construct with default (128) initial table capacity
HashSet() HashSet() = default;
//- Construct empty with zero table capacity
explicit HashSet(const Foam::zero) noexcept
: :
parent_type() parent_type(Foam::zero{})
{}
//- Construct empty with initial table capacity
explicit HashSet(const label initialCapacity)
:
parent_type(initialCapacity)
{} {}
//- Copy construct //- Copy construct
@ -137,18 +146,12 @@ public:
{} {}
//- Move construct //- Move construct
HashSet(this_type&& rhs) HashSet(this_type&& rhs) noexcept
: :
parent_type(std::move(rhs)) parent_type(std::move(rhs))
{} {}
//- Construct given initial table capacity //- Construct from Istream with default initial table capacity
explicit HashSet(const label size)
:
parent_type(size)
{}
//- Construct from Istream with default table capacity
explicit HashSet(Istream& is) explicit HashSet(Istream& is)
: :
parent_type(is) parent_type(is)

View File

@ -36,6 +36,16 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
Foam::HashTable<T, Key, Hash>::HashTable(const Foam::zero) noexcept
:
HashTableCore(),
size_(0),
capacity_(0),
table_(nullptr)
{}
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
Foam::HashTable<T, Key, Hash>::HashTable() Foam::HashTable<T, Key, Hash>::HashTable()
: :
@ -44,16 +54,19 @@ Foam::HashTable<T, Key, Hash>::HashTable()
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
Foam::HashTable<T, Key, Hash>::HashTable(const label size) Foam::HashTable<T, Key, Hash>::HashTable(const label initialCapacity)
: :
HashTableCore(), HashTableCore(),
size_(0), size_(0),
capacity_(HashTableCore::canonicalSize(size)), capacity_(0),
table_(nullptr) table_(nullptr)
{ {
if (capacity_) if (initialCapacity > 0)
{ {
// Like resize() but no initial content to transfer
capacity_ = HashTableCore::canonicalSize(initialCapacity);
table_ = new node_type*[capacity_]; table_ = new node_type*[capacity_];
for (label i=0; i < capacity_; ++i) for (label i=0; i < capacity_; ++i)
{ {
table_[i] = nullptr; table_[i] = nullptr;
@ -75,13 +88,14 @@ Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht)
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
Foam::HashTable<T, Key, Hash>::HashTable(HashTable<T, Key, Hash>&& rhs) Foam::HashTable<T, Key, Hash>::HashTable(HashTable<T, Key, Hash>&& rhs) noexcept
: :
HashTableCore(), HashTableCore(),
size_(rhs.size_), size_(rhs.size_),
capacity_(rhs.capacity_), capacity_(rhs.capacity_),
table_(rhs.table_) table_(rhs.table_)
{ {
// Stole all contents
rhs.size_ = 0; rhs.size_ = 0;
rhs.capacity_ = 0; rhs.capacity_ = 0;
rhs.table_ = nullptr; rhs.table_ = nullptr;
@ -108,11 +122,13 @@ Foam::HashTable<T, Key, Hash>::HashTable
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
Foam::HashTable<T, Key, Hash>::~HashTable() Foam::HashTable<T, Key, Hash>::~HashTable()
{ {
if (table_) // Remove all entries from table
{ clear();
clear();
delete[] table_; // Remove the table itself
} capacity_ = 0;
delete[] table_;
table_ = nullptr;
} }
@ -636,9 +652,9 @@ Foam::label Foam::HashTable<T, Key, Hash>::retain
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
void Foam::HashTable<T, Key, Hash>::resize(const label sz) void Foam::HashTable<T, Key, Hash>::resize(const label requestedCapacity)
{ {
const label newCapacity = HashTableCore::canonicalSize(sz); const label newCapacity = HashTableCore::canonicalSize(requestedCapacity);
const label oldCapacity = capacity_; const label oldCapacity = capacity_;
if (newCapacity == oldCapacity) if (newCapacity == oldCapacity)
@ -656,12 +672,8 @@ void Foam::HashTable<T, Key, Hash>::resize(const label sz)
} }
else else
{ {
if (table_) capacity_ = 0;
{ delete[] table_;
delete[] table_;
capacity_ = 0;
}
table_ = nullptr; table_ = nullptr;
} }
@ -679,9 +691,14 @@ void Foam::HashTable<T, Key, Hash>::resize(const label sz)
table_[i] = nullptr; table_[i] = nullptr;
} }
if (!oldTable)
{
return;
}
// Move to new table[] but with new chaining. // Move to new table[] but with new chaining.
for (label i = 0, nPending = size_; nPending && i < oldCapacity; ++i) for (label i = 0, pending = size_; pending && i < oldCapacity; ++i)
{ {
for (node_type* ep = oldTable[i]; ep; /*nil*/) for (node_type* ep = oldTable[i]; ep; /*nil*/)
{ {
@ -696,22 +713,24 @@ void Foam::HashTable<T, Key, Hash>::resize(const label sz)
} }
ep = next; // continue in the linked-list ep = next; // continue in the linked-list
--nPending; // note any early completion --pending; // note any early completion
} }
oldTable[i] = nullptr; oldTable[i] = nullptr;
} }
if (oldTable) delete[] oldTable;
{
delete[] oldTable;
}
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
void Foam::HashTable<T, Key, Hash>::clear() void Foam::HashTable<T, Key, Hash>::clear()
{ {
for (label i=0; size_ && i<capacity_; ++i) if (!table_)
{
capacity_ = 0; // Paranoid
}
for (label i = 0, pending = size_; pending && i < capacity_; ++i)
{ {
for (node_type* ep = table_[i]; ep; /*nil*/) for (node_type* ep = table_[i]; ep; /*nil*/)
{ {
@ -720,23 +739,29 @@ void Foam::HashTable<T, Key, Hash>::clear()
delete ep; delete ep;
ep = next; // continue in the linked-list ep = next; // continue in the linked-list
--size_; // note any early completion --pending; // note any early completion
} }
table_[i] = nullptr; table_[i] = nullptr;
} }
size_ = 0;
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
void Foam::HashTable<T, Key, Hash>::clearStorage() void Foam::HashTable<T, Key, Hash>::clearStorage()
{ {
// Remove all entries from table
clear(); clear();
resize(0);
// Remove the table itself
capacity_ = 0;
delete[] table_;
table_ = nullptr;
} }
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
void Foam::HashTable<T, Key, Hash>::swap(HashTable<T, Key, Hash>& rhs) void Foam::HashTable<T, Key, Hash>::swap(HashTable<T, Key, Hash>& rhs) noexcept
{ {
if (this == &rhs) if (this == &rhs)
{ {
@ -942,12 +967,7 @@ void Foam::HashTable<T, Key, Hash>::operator=
HashTable<T, Key, Hash>&& rhs HashTable<T, Key, Hash>&& rhs
) )
{ {
if (this == &rhs) transfer(rhs); // Includes self-assignment check
{
return; // Self-assignment is a no-op
}
transfer(rhs);
} }
@ -994,7 +1014,7 @@ Foam::HashTable<T, Key, Hash>& Foam::HashTable<T, Key, Hash>::operator+=
) )
{ {
// Avoid no-ops: // Avoid no-ops:
if (rhs.size() || this != &rhs) if (rhs.size() && (this != &rhs))
{ {
if (this->size()) if (this->size())
{ {

View File

@ -228,20 +228,24 @@ public:
// Constructors // Constructors
//- Default construct with default (128) table capacity //- Default construct with default (128) initial table capacity
HashTable(); HashTable();
//- Construct given initial table capacity //- Construct empty with zero initial table capacity
explicit HashTable(const label size); explicit HashTable(const Foam::zero) noexcept;
//- Construct from Istream with default table capacity //- Construct empty with initial table capacity
HashTable(Istream& is, const label size = 128); explicit HashTable(const label initialCapacity);
//- Construct from Istream,
//- with default or specified initial table capacity.
HashTable(Istream& is, const label initialCapacity = 128);
//- Copy construct //- Copy construct
HashTable(const this_type& ht); HashTable(const this_type& ht);
//- Move construct //- Move construct
HashTable(this_type&& rhs); HashTable(this_type&& rhs) noexcept;
//- Construct from an initializer list //- Construct from an initializer list
// Duplicate entries are handled by overwriting // Duplicate entries are handled by overwriting
@ -528,17 +532,17 @@ public:
//- Resize the hash table for efficiency //- Resize the hash table for efficiency
void resize(const label sz); void resize(const label requestedCapacity);
//- Clear all entries from table //- Remove all entries from table
void clear(); void clear();
//- Clear the table entries and the table itself. //- Remove all entries from table and the table itself.
// Equivalent to clear() followed by resize(0) // Equivalent to clear() followed by resize(0)
void clearStorage(); void clearStorage();
//- Swap contents into this table //- Swap contents into this table
void swap(HashTable<T, Key, Hash>& rhs); void swap(HashTable<T, Key, Hash>& rhs) noexcept;
//- Transfer contents into this table. //- Transfer contents into this table.
void transfer(HashTable<T, Key, Hash>& rhs); void transfer(HashTable<T, Key, Hash>& rhs);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -33,23 +33,14 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
Foam::HashTable<T, Key, Hash>::HashTable(Istream& is, const label size) Foam::HashTable<T, Key, Hash>::HashTable
(
Istream& is,
const label initialCapacity
)
: :
HashTableCore(), HashTable(initialCapacity)
size_(0),
capacity_(HashTableCore::canonicalSize(size)),
table_(nullptr)
{ {
if (capacity_)
{
table_ = new node_type*[capacity_];
for (label i=0; i < capacity_; ++i)
{
table_[i] = nullptr;
}
}
operator>>(is, *this); operator>>(is, *this);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -73,19 +73,22 @@ public:
// Constructors // Constructors
//- Default construct with default table capacity //- Default construct with default (128) initial table capacity
Map() Map() = default;
//- Construct empty with zero initial table capacity
explicit Map(const Foam::zero) noexcept
: :
parent_type() parent_type(Foam::zero{})
{} {}
//- Construct with given initial table capacity //- Construct empty with given initial table capacity
explicit Map(const label size) explicit Map(const label initialCapacity)
: :
parent_type(size) parent_type(initialCapacity)
{} {}
//- Construct from Istream with default table capacity //- Construct from Istream (with default initial table capacity)
Map(Istream& is) Map(Istream& is)
: :
parent_type(is) parent_type(is)
@ -98,7 +101,7 @@ public:
{} {}
//- Move construct //- Move construct
Map(this_type&& map) Map(this_type&& map) noexcept
: :
parent_type(std::move(map)) parent_type(std::move(map))
{} {}

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2018 OpenCFD Ltd. Copyright (C) 2017-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -65,19 +65,22 @@ public:
// Constructors // Constructors
//- Default construct with default table capacity //- Default construct with default (128) initial table capacity
PtrMap() PtrMap() = default;
//- Construct empty with zero initial table capacity
explicit PtrMap(const Foam::zero) noexcept
: :
parent_type() parent_type(Foam::zero{})
{} {}
//- Construct with given initial table capacity //- Construct empty with given initial table capacity
explicit PtrMap(const label size) explicit PtrMap(const label initialCapacity)
: :
parent_type(size) parent_type(initialCapacity)
{} {}
//- Construct from Istream //- Construct from Istream (with default initial table capacity)
PtrMap(Istream& is) PtrMap(Istream& is)
: :
parent_type(is) parent_type(is)
@ -90,7 +93,7 @@ public:
{} {}
//- Move construct //- Move construct
PtrMap(this_type&& map) PtrMap(this_type&& map) noexcept
: :
parent_type(std::move(map)) parent_type(std::move(map))
{} {}

View File

@ -113,8 +113,8 @@ public:
//- Default construct, an empty list without allocation. //- Default construct, an empty list without allocation.
inline constexpr DynamicList() noexcept; inline constexpr DynamicList() noexcept;
//- Construct an empty list with given reserve size. //- Construct an empty list with given initial capacity
inline explicit DynamicList(const label len); inline explicit DynamicList(const label initialCapacity);
//- Construct with given size and value for all elements. //- Construct with given size and value for all elements.
inline DynamicList(const label len, const T& val); inline DynamicList(const label len, const T& val);

View File

@ -143,12 +143,12 @@ inline constexpr Foam::DynamicList<T, SizeMin>::DynamicList() noexcept
template<class T, int SizeMin> template<class T, int SizeMin>
inline Foam::DynamicList<T, SizeMin>::DynamicList(const label len) inline Foam::DynamicList<T, SizeMin>::DynamicList(const label initialCapacity)
: :
List<T>(), List<T>(),
capacity_(0) capacity_(0)
{ {
reserve_nocopy(len); reserve_nocopy(initialCapacity);
} }

View File

@ -168,10 +168,13 @@ public:
// Constructors // Constructors
//- Default construct (empty) with default (128) table capacity //- Default construct (empty) with default (128) table capacity
inline IOobjectList(); IOobjectList() = default;
//- Construct with zero table capacity
inline explicit IOobjectList(const Foam::zero) noexcept;
//- Construct given initial table capacity //- Construct given initial table capacity
inline explicit IOobjectList(const label nObjects); inline explicit IOobjectList(const label initialCapacity);
//- Copy construct //- Copy construct
inline IOobjectList(const IOobjectList& list); inline IOobjectList(const IOobjectList& list);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd. Copyright (C) 2022-2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,15 +27,15 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::IOobjectList::IOobjectList() inline Foam::IOobjectList::IOobjectList(const Foam::zero) noexcept
: :
HashPtrTable<IOobject>() HashPtrTable<IOobject>(Foam::zero{})
{} {}
inline Foam::IOobjectList::IOobjectList(const label nObjects) inline Foam::IOobjectList::IOobjectList(const label initialCapacity)
: :
HashPtrTable<IOobject>(nObjects) // Could also use 2*nObjects instead HashPtrTable<IOobject>(initialCapacity)
{} {}

View File

@ -79,7 +79,11 @@ bool Foam::objectRegistry::parentNotTime() const noexcept
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects) Foam::objectRegistry::objectRegistry
(
const Time& t,
const label initialCapacity
)
: :
regIOobject regIOobject
( (
@ -94,7 +98,7 @@ Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
), ),
true // to flag that this is the top-level regIOobject true // to flag that this is the top-level regIOobject
), ),
HashTable<regIOobject*>(nObjects), HashTable<regIOobject*>(initialCapacity),
time_(t), time_(t),
parent_(t), parent_(t),
dbDir_(name()), dbDir_(name()),
@ -105,10 +109,14 @@ Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
{} {}
Foam::objectRegistry::objectRegistry(const IOobject& io, const label nObjects) Foam::objectRegistry::objectRegistry
(
const IOobject& io,
const label initialCapacity
)
: :
regIOobject(io), regIOobject(io),
HashTable<regIOobject*>(nObjects), HashTable<regIOobject*>(initialCapacity),
time_(io.time()), time_(io.time()),
parent_(io.db()), parent_(io.db()),
dbDir_(parent_.dbDir()/local()/name()), dbDir_(parent_.dbDir()/local()/name()),
@ -117,7 +125,7 @@ Foam::objectRegistry::objectRegistry(const IOobject& io, const label nObjects)
cacheTemporaryObjects_(0), cacheTemporaryObjects_(0),
temporaryObjects_(0) temporaryObjects_(0)
{ {
writeOpt(IOobject::AUTO_WRITE); writeOpt(IOobjectOption::AUTO_WRITE);
} }

View File

@ -177,11 +177,19 @@ public:
//- Construct the time objectRegistry, //- Construct the time objectRegistry,
//- with estimated table capacity (default: 128) //- with estimated table capacity (default: 128)
explicit objectRegistry(const Time& db, const label nObjects=128); explicit objectRegistry
(
const Time& db,
const label initialCapacity = 128
);
//- Construct sub-registry given an IObject to describe the registry, //- Construct sub-registry given an IObject to describe the registry,
//- with estimated table capacity (default: 128) //- with estimated table capacity (default: 128)
explicit objectRegistry(const IOobject& io, const label nObjects=128); explicit objectRegistry
(
const IOobject& io,
const label initialCapacity = 128
);
//- Destructor, with checkOut() for all objects that are ownedByRegistry //- Destructor, with checkOut() for all objects that are ownedByRegistry

View File

@ -109,8 +109,8 @@ public:
//- Default construct, an empty field without allocation. //- Default construct, an empty field without allocation.
inline constexpr DynamicField() noexcept; inline constexpr DynamicField() noexcept;
//- Construct empty field with given reserve size. //- Construct empty field with given initial capacity
inline explicit DynamicField(const label len); inline explicit DynamicField(const label initialCapacity);
//- Construct given size and initial value //- Construct given size and initial value
inline DynamicField(const label len, const T& val); inline DynamicField(const label len, const T& val);

View File

@ -137,12 +137,12 @@ inline constexpr Foam::DynamicField<T, SizeMin>::DynamicField() noexcept
template<class T, int SizeMin> template<class T, int SizeMin>
inline Foam::DynamicField<T, SizeMin>::DynamicField(const label len) inline Foam::DynamicField<T, SizeMin>::DynamicField(const label initialCapacity)
: :
Field<T>(), Field<T>(),
capacity_(0) capacity_(0)
{ {
reserve_nocopy(len); reserve_nocopy(initialCapacity);
} }