ENH: free/nullify of PtrList and UPtrList

- Allows clearing or freeing pointers without touching the underlying
  list size. Was previously only for PtrDynList, but now available on
  UPtrList, PtrList as well.

- add transfer() method to PtrDynList to avoid potential slicing.
This commit is contained in:
Mark Olesen
2023-05-10 14:02:13 +02:00
parent 139a8fc6ff
commit 62a68eeea0
15 changed files with 131 additions and 55 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2022 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -126,9 +126,6 @@ public:
// Edit
//- Delete the allocated entries, but retain the list size.
using PtrList<T>::free;
//- Squeeze out intermediate nullptr entries in the list of pointers
//- and adjust the addressable size accordingly.
// \return the number of non-null entries
@ -138,6 +135,13 @@ public:
template<int AnySizeMin>
inline void swap(PtrDynList<T, AnySizeMin>& other);
//- Transfer contents of the argument PtrList into this.
inline void transfer(PtrList<T>& list);
//- Transfer contents of any sized PtrDynList into this.
template<int AnySizeMin>
inline void transfer(PtrDynList<T, AnySizeMin>& list);
//- Construct an element at the end of the list,
//- return reference to the new list element
template<class... Args>

View File

@ -216,6 +216,44 @@ inline void Foam::PtrDynList<T, SizeMin>::swap
}
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::transfer(PtrList<T>& other)
{
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other)
)
{
return; // Self assignment is a no-op
}
UPtrList<T>::swap(other);
other.clear();
}
template<class T, int SizeMin>
template<int AnySizeMin>
inline void Foam::PtrDynList<T, SizeMin>::transfer
(
PtrDynList<T, AnySizeMin>& other
)
{
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other)
)
{
return; // Self assignment is a no-op
}
this->swap(other);
other.clear();
}
template<class T, int SizeMin>
template<class... Args>
inline T& Foam::PtrDynList<T, SizeMin>::emplace_back(Args&&... args)

View File

@ -78,8 +78,6 @@ protected:
template<class INew>
void readIstream(Istream& is, const INew& inew);
//- Delete the allocated entries, but retain the list size.
inline void free();
public:
@ -142,6 +140,9 @@ public:
//- Clear the PtrList. Delete allocated entries and set size to zero.
inline void clear();
//- Free memory and nullify all entries. Does not change the list size.
inline void free();
//- Adjust size of PtrList.
// New entries are initialized to nullptr, removed entries are deleted
void resize(const label newLen);

View File

@ -30,15 +30,6 @@ License
#include "refPtr.H"
#include "tmp.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class T>
inline void Foam::PtrList<T>::free()
{
(this->ptrs_).free(); // free old pointers
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T>
@ -96,11 +87,18 @@ inline Foam::PtrList<T>::PtrList
template<class T>
inline void Foam::PtrList<T>::clear()
{
(this->ptrs_).free(); // free old pointers
(this->ptrs_).free(); // Free and nullify old pointers
UPtrList<T>::clear();
}
template<class T>
inline void Foam::PtrList<T>::free()
{
(this->ptrs_).free(); // Free and nullify old pointers
}
template<class T>
template<class... Args>
inline T& Foam::PtrList<T>::emplace_back(Args&&... args)
@ -260,7 +258,12 @@ inline Foam::autoPtr<T> Foam::PtrList<T>::release(const label i)
template<class T>
inline void Foam::PtrList<T>::transfer(PtrList<T>& list)
{
(this->ptrs_).free(); // free old pointers
if (this == &list)
{
return; // Self-assignment is a no-op
}
(this->ptrs_).free(); // Free and nullify old pointers
UPtrList<T>::transfer(list);
}

View File

@ -295,6 +295,9 @@ public:
//- Set list size to zero.
inline void clear();
//- Nullify all entries. Does not change the list size.
inline void free();
//- Change the size of the list.
// New entries are initialized to nullptr.
inline void resize(const label newLen);

View File

@ -205,6 +205,13 @@ inline void Foam::UPtrList<T>::clear()
}
template<class T>
inline void Foam::UPtrList<T>::free()
{
ptrs_.setNull();
}
template<class T>
inline void Foam::UPtrList<T>::swap(UPtrList<T>& list)
{

View File

@ -191,7 +191,7 @@ void Foam::mapDistributeBase::send
// Set up receives from neighbours
recvFields.clear();
recvFields.free();
recvFields.resize(nProcs);
for (const int domain : UPstream::allProcs(comm))
@ -219,7 +219,7 @@ void Foam::mapDistributeBase::send
// Set up sends to neighbours
sendFields.clear();
recvFields.free();
sendFields.resize(nProcs);
for (const int domain : UPstream::allProcs(comm))

View File

@ -206,6 +206,13 @@ Foam::polyBoundaryMesh::polyBoundaryMesh
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
void Foam::polyBoundaryMesh::clear()
{
polyPatchList::clear();
clearAddressing();
}
void Foam::polyBoundaryMesh::clearGeom()
{
polyPatchList& patches = *this;
@ -219,9 +226,9 @@ void Foam::polyBoundaryMesh::clearGeom()
void Foam::polyBoundaryMesh::clearAddressing()
{
neighbourEdgesPtr_.clear();
patchIDPtr_.clear();
groupIDsPtr_.clear();
neighbourEdgesPtr_.reset(nullptr);
patchIDPtr_.reset(nullptr);
groupIDsPtr_.reset(nullptr);
polyPatchList& patches = *this;
@ -493,7 +500,7 @@ void Foam::polyBoundaryMesh::setGroup
const labelUList& patchIDs
)
{
groupIDsPtr_.clear();
groupIDsPtr_.reset(nullptr);
polyPatchList& patches = *this;
@ -1179,9 +1186,9 @@ void Foam::polyBoundaryMesh::movePoints(const pointField& p)
void Foam::polyBoundaryMesh::updateMesh()
{
neighbourEdgesPtr_.clear();
patchIDPtr_.clear();
groupIDsPtr_.clear();
neighbourEdgesPtr_.reset(nullptr);
patchIDPtr_.reset(nullptr);
groupIDsPtr_.reset(nullptr);
PstreamBuffers pBufs(Pstream::defaultCommsType);

View File

@ -94,23 +94,24 @@ class polyBoundaryMesh
//- Read if IOobject flags set. Return true if read.
bool readContents(const bool allowReadIfPresent);
//- No copy construct
polyBoundaryMesh(const polyBoundaryMesh&) = delete;
//- No copy assignment
void operator=(const polyBoundaryMesh&) = delete;
public:
//- Declare friendship with polyMesh
friend class polyMesh;
//- Runtime type information
TypeName("polyBoundaryMesh");
// Generated Methods
//- No copy construct
polyBoundaryMesh(const polyBoundaryMesh&) = delete;
//- No copy assignment
void operator=(const polyBoundaryMesh&) = delete;
// Constructors
//- Read constructor given IOobject and a polyMesh reference
@ -142,15 +143,17 @@ public:
~polyBoundaryMesh() = default;
// Member Functions
//- Clear the patch list and all demand-driven data
void clear();
//- Clear geometry at this level and at patches
void clearGeom();
//- Clear addressing at this level and at patches
void clearAddressing();
// Member Functions
//- Return the mesh reference
const polyMesh& mesh() const noexcept
{

View File

@ -40,9 +40,7 @@ void Foam::polyMesh::removeBoundary()
{
DebugInFunction << "Removing boundary patches." << endl;
// Remove the point zones
boundary_.clear();
boundary_.setSize(0);
clearOut();
}

View File

@ -212,7 +212,7 @@ Foam::polyMesh::readUpdateState Foam::polyMesh::readUpdate()
<< "unexpected consequences. Proceed with care." << endl;
boundary_.clear();
boundary_.setSize(newBoundary.size());
boundary_.resize(newBoundary.size());
forAll(newBoundary, patchi)
{

View File

@ -462,8 +462,7 @@ void Foam::boundaryMesh::clearOut()
void Foam::boundaryMesh::read(const polyMesh& mesh)
{
patches_.clear();
patches_.setSize(mesh.boundaryMesh().size());
patches_.resize(mesh.boundaryMesh().size());
// Number of boundary faces
const label nBFaces = mesh.nBoundaryFaces();
@ -630,7 +629,7 @@ void Foam::boundaryMesh::readTriSurface(const fileName& fName)
// There are as many surface patches as region numbers in triangles
// so use the surface patches
patches_.setSize(surfPatches.size());
patches_.resize(surfPatches.size());
// Take over patches, setting size to 0 for now.
forAll(surfPatches, patchi)
@ -655,7 +654,7 @@ void Foam::boundaryMesh::readTriSurface(const fileName& fName)
{
// There are not enough surface patches. Make up my own.
patches_.setSize(regionToBoundaryPatch.size());
patches_.resize(regionToBoundaryPatch.size());
forAll(patches_, patchi)
{
@ -1627,9 +1626,7 @@ void Foam::boundaryMesh::deletePatch(const word& patchName)
newPatches.set(patchi - 1, patches_[patchi].clone());
}
patches_.clear();
patches_ = newPatches;
patches_ = std::move(newPatches);
if (debug)
{

View File

@ -176,6 +176,15 @@ Foam::faBoundaryMesh::faBoundaryMesh
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
void Foam::faBoundaryMesh::clear()
{
faPatchList::clear();
groupIDsPtr_.reset(nullptr);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faBoundaryMesh::calcGeometry()

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2018-2022 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -90,12 +90,6 @@ class faBoundaryMesh
//- Read if IOobject flags set. Return true if read.
bool readContents(const bool allowReadIfPresent);
//- No copy construct
faBoundaryMesh(const faBoundaryMesh&) = delete;
//- No copy assignment
void operator=(const faBoundaryMesh&) = delete;
public:
@ -103,6 +97,15 @@ public:
TypeName("faBoundaryMesh");
// Generated Methods
//- No copy construct
faBoundaryMesh(const faBoundaryMesh&) = delete;
//- No copy assignment
void operator=(const faBoundaryMesh&) = delete;
// Constructors
//- Construct from faMesh
@ -127,6 +130,9 @@ public:
// Member Functions
//- Clear the patch list and all demand-driven data
void clear();
//- Return the mesh reference
const faMesh& mesh() const noexcept
{

View File

@ -155,7 +155,7 @@ void Foam::sampledSets::gatherAllSets()
const PtrList<sampledSet>& localSets = *this;
gatheredSets_.clear();
gatheredSets_.free();
gatheredSets_.resize(localSets.size());
gatheredSorting_.resize_nocopy(localSets.size());
globalIndices_.resize_nocopy(localSets.size());