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 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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;
}
// ************************************************************************* //
#warning File removed - left for old dependency check only

View File

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

View File

@ -42,13 +42,6 @@ void Foam::DictionaryBase<IDLListType, T>::addEntries()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class IDLListType, class T>
Foam::DictionaryBase<IDLListType, T>::DictionaryBase(const label size)
:
hashedTs_(size)
{}
template<class IDLListType, class T>
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>
void Foam::DictionaryBase<IDLListType, T>::push_front
(
@ -191,9 +156,9 @@ void Foam::DictionaryBase<IDLListType, T>::push_front
T* ptr
)
{
IDLListType::push_front(ptr);
// NOTE: we should probably check that HashTable::insert actually worked
hashedTs_.insert(keyword, ptr);
IDLListType::push_front(ptr);
}
@ -213,16 +178,15 @@ void Foam::DictionaryBase<IDLListType, T>::push_back
template<class IDLListType, class T>
T* Foam::DictionaryBase<IDLListType, T>::remove(const word& keyword)
{
T* ptr = nullptr;
auto iter = hashedTs_.find(keyword);
if (iter.good())
{
T* ptr = IDLListType::remove(iter.val());
ptr = IDLListType::remove(iter.val());
hashedTs_.erase(iter);
return ptr;
}
return nullptr;
return ptr;
}
@ -269,8 +233,4 @@ void Foam::DictionaryBase<IDLListType, T>::operator=
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "DictionaryBaseIO.C"
// ************************************************************************* //

View File

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

View File

@ -35,9 +35,10 @@ template<class IDLListType, class T>
Foam::Ostream& Foam::operator<<
(
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;

View File

@ -56,31 +56,35 @@ class PtrDictionary
{
public:
//- The template instance used for the dictionary content
typedef DictionaryBase<DLPtrList<T>, T> dict_type;
// Constructors
//- Construct given initial table size
explicit PtrDictionary(const label size = 128)
//- Default construct, or with initial table capacity
explicit PtrDictionary(const label initialCapacity = 128)
:
DictionaryBase<DLPtrList<T>, T>(size)
dict_type(initialCapacity)
{}
//- Copy construct
PtrDictionary(const PtrDictionary& dict)
:
DictionaryBase<DLPtrList<T>, T>(dict)
dict_type(dict)
{}
//- Construct from Istream using given Istream constructor class
template<class INew>
PtrDictionary(Istream& is, const INew& inew)
:
DictionaryBase<DLPtrList<T>, T>(is, inew)
dict_type(is, inew)
{}
//- Construct from Istream
explicit PtrDictionary(Istream& is)
:
DictionaryBase<DLPtrList<T>, T>(is)
dict_type(is)
{}
@ -89,13 +93,13 @@ public:
//- Find and return entry
const T& operator[](const word& key) const
{
return *DictionaryBase<DLPtrList<T>, T>::operator[](key);
return *(dict_type::lookup(key));
}
//- Find and return entry
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>
Foam::PtrListDictionary<T>::PtrListDictionary(const label size)
:
DictionaryBase<PtrList<T>, T>(2*size)
dict_type(2*size)
{
PtrList<T>::resize(size);
}
@ -41,7 +41,7 @@ Foam::PtrListDictionary<T>::PtrListDictionary(const label size)
template<class T>
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>
Foam::PtrListDictionary<T>::PtrListDictionary(Istream& is, const INew& iNew)
:
DictionaryBase<PtrList<T>, T>(is, iNew)
dict_type(is, iNew)
{}
template<class T>
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
)
{
if (!DictionaryBase<PtrList<T>, T>::hashedTs_.insert(key, ptr))
autoPtr<T> old(PtrList<T>::set(i, ptr));
if (!dict_type::addHashEntry(key, ptr))
{
FatalErrorInFunction
<< "Cannot insert with key '" << key << "' into hash-table"
<< 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 word& key,
autoPtr<T>& aptr
autoPtr<T>& ptr
)
{
T* ptr = aptr.ptr();
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);
return this->set(i, key, ptr.release());
}
@ -104,17 +100,10 @@ inline Foam::autoPtr<T> Foam::PtrListDictionary<T>::set
(
const label i,
const word& key,
tmp<T>& t
tmp<T>& ptr
)
{
T* ptr = t.ptr();
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);
return this->set(i, key, ptr.ptr()); // release or clone
}

View File

@ -59,6 +59,10 @@ class PtrListDictionary
{
public:
//- The template instance used for the dictionary content
typedef DictionaryBase<PtrList<T>, T> dict_type;
// Constructors
//- Construct given initial list size
@ -81,26 +85,26 @@ public:
autoPtr<T> set(const label i, const word& key, T* ptr);
//- 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
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[];
//- Find and return entry
const T& operator[](const word& key) const
{
return *DictionaryBase<PtrList<T>, T>::operator[](key);
return *(dict_type::lookup(key));
}
//- Find and return entry
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
form of intrusive doubly-linked list of \<T\>.
SourceFiles
UDictionary.C
\*---------------------------------------------------------------------------*/
#ifndef UDictionary_H
#define UDictionary_H
#ifndef Foam_UDictionary_H
#define Foam_UDictionary_H
#include "DictionaryBase.H"
#include "UIDLList.H"
@ -58,16 +55,25 @@ class UDictionary
:
public DictionaryBase<UIDLList<T>, T>
{
public:
//- The template instance used for the dictionary content
typedef DictionaryBase<UIDLList<T>, T> dict_type;
// Constructors
//- Null constructor
UDictionary();
//- Default construct, or with initial table capacity
explicit UDictionary(const label initialCapacity = 128)
:
dict_type(initialCapacity)
{}
//- Copy construct
UDictionary(const UDictionary&);
UDictionary(const UDictionary& dict)
:
dict_type(dict)
{}
};
@ -77,12 +83,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "UDictionary.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -57,18 +57,22 @@ class UPtrDictionary
{
public:
//- The template instance used for the dictionary content
typedef DictionaryBase<DLList<T*>, T> dict_type;
// Constructors
//- Construct given initial table size
explicit UPtrDictionary(const label size = 128)
//- Default construct, or with initial table capacity
explicit UPtrDictionary(const label initialCapacity = 128)
:
DictionaryBase<DLList<T*>, T>(size)
dict_type(initialCapacity)
{}
//- Copy construct
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
HashPtrTable() = default;
//- Construct with zero table capacity
explicit HashPtrTable(const Foam::zero) noexcept
:
parent_type(Foam::zero{})
{}
//- 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
HashPtrTable(const this_type& rhs);
//- 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
template<class INew>

View File

@ -29,25 +29,6 @@ License
#include "refPtr.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 * * * * * * * * * * * * * //
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>
bool Foam::HashSet<Key, Hash>::operator==(const HashSet<Key, Hash>& rhs) const
{
// Sizes (number of keys) must match
if (this->size() != rhs.size())
// Trivial checks first
if (this == &rhs)
{
return true;
}
else if (this->size() != rhs.size())
{
return false;
}
@ -316,10 +320,13 @@ template<class Key, class Hash>
Foam::HashSet<Key, Hash>&
Foam::HashSet<Key, Hash>::operator|=(const HashSet<Key, Hash>& rhs)
{
// Add rhs elements into lhs
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
// Add rhs elements into lhs - avoid no-ops
if (this != &rhs)
{
this->insert(iter.key());
for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
{
this->insert(iter.key());
}
}
return *this;

View File

@ -124,10 +124,19 @@ public:
// Constructors
//- Default construct with default (128) table capacity
HashSet()
//- Default construct with default (128) initial table capacity
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
@ -137,18 +146,12 @@ public:
{}
//- Move construct
HashSet(this_type&& rhs)
HashSet(this_type&& rhs) noexcept
:
parent_type(std::move(rhs))
{}
//- Construct given initial table capacity
explicit HashSet(const label size)
:
parent_type(size)
{}
//- Construct from Istream with default table capacity
//- Construct from Istream with default initial table capacity
explicit HashSet(Istream& is)
:
parent_type(is)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -113,8 +113,8 @@ public:
//- Default construct, an empty list without allocation.
inline constexpr DynamicList() noexcept;
//- Construct an empty list with given reserve size.
inline explicit DynamicList(const label len);
//- Construct an empty list with given initial capacity
inline explicit DynamicList(const label initialCapacity);
//- Construct with given size and value for all elements.
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>
inline Foam::DynamicList<T, SizeMin>::DynamicList(const label len)
inline Foam::DynamicList<T, SizeMin>::DynamicList(const label initialCapacity)
:
List<T>(),
capacity_(0)
{
reserve_nocopy(len);
reserve_nocopy(initialCapacity);
}

View File

@ -168,10 +168,13 @@ public:
// Constructors
//- 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
inline explicit IOobjectList(const label nObjects);
inline explicit IOobjectList(const label initialCapacity);
//- Copy construct
inline IOobjectList(const IOobjectList& list);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,15 +27,15 @@ License
// * * * * * * * * * * * * * * * * 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 * * * * * * * * * * * * * * //
Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
Foam::objectRegistry::objectRegistry
(
const Time& t,
const label initialCapacity
)
:
regIOobject
(
@ -94,7 +98,7 @@ Foam::objectRegistry::objectRegistry(const Time& t, const label nObjects)
),
true // to flag that this is the top-level regIOobject
),
HashTable<regIOobject*>(nObjects),
HashTable<regIOobject*>(initialCapacity),
time_(t),
parent_(t),
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),
HashTable<regIOobject*>(nObjects),
HashTable<regIOobject*>(initialCapacity),
time_(io.time()),
parent_(io.db()),
dbDir_(parent_.dbDir()/local()/name()),
@ -117,7 +125,7 @@ Foam::objectRegistry::objectRegistry(const IOobject& io, const label nObjects)
cacheTemporaryObjects_(0),
temporaryObjects_(0)
{
writeOpt(IOobject::AUTO_WRITE);
writeOpt(IOobjectOption::AUTO_WRITE);
}

View File

@ -177,11 +177,19 @@ public:
//- Construct the time objectRegistry,
//- 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,
//- 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

View File

@ -109,8 +109,8 @@ public:
//- Default construct, an empty field without allocation.
inline constexpr DynamicField() noexcept;
//- Construct empty field with given reserve size.
inline explicit DynamicField(const label len);
//- Construct empty field with given initial capacity
inline explicit DynamicField(const label initialCapacity);
//- Construct given size and initial value
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>
inline Foam::DynamicField<T, SizeMin>::DynamicField(const label len)
inline Foam::DynamicField<T, SizeMin>::DynamicField(const label initialCapacity)
:
Field<T>(),
capacity_(0)
{
reserve_nocopy(len);
reserve_nocopy(initialCapacity);
}