ENH: additional PtrList constructor and memory management method

- PtrList::release() method.

  Similar to autoPtr and unique_ptr and clearer in purpose than
  using set(i,nullptr)

- Construct from List of pointers, taking ownership.

  Useful when upgrading code. Eg,

     List<polyPatch*> oldList = ...;
     PtrList<polyPatch> newList(oldList);
     ...

BUG: incorrect resizing method names (PtrDynList) in previously unused code
This commit is contained in:
Mark Olesen
2019-02-22 15:55:17 +01:00
parent f0ff7627b1
commit b5e4924eec
8 changed files with 161 additions and 21 deletions

View File

@ -203,6 +203,39 @@ Ostream& print
} }
template<class T>
Ostream& print
(
Ostream& os,
const UList<T*>& list
)
{
const label len = list.size();
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
const T* ptr = list[i];
if (ptr)
{
os << *ptr << nl;
}
else
{
os << "nullptr" << nl;
}
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
}
template<class T> template<class T>
Ostream& report Ostream& report
( (
@ -304,12 +337,60 @@ int main(int argc, char *argv[])
<<"list2: " << list2 << nl <<"list2: " << list2 << nl
<<"list-appended: " << listApp << endl; <<"list-appended: " << listApp << endl;
Info<<"indirectly delete some items via set(.., 0) :" << endl;
for (label i = 0; i < 3; i++) // Release values
{
DynamicList<Scalar*> ptrs;
forAll(listApp, i)
{
auto old = listApp.release(i);
if (old)
{
ptrs.append(old.release());
}
}
Info<<"Released pointers from";
print(Info, listApp) << nl;
Info<<"Into plain list of pointers";
print(Info, ptrs) << nl;
PtrDynList<Scalar> newlist1(ptrs);
Info<<"Constructed from plain list of pointers";
print(Info, ptrs) << nl;
print(Info, newlist1) << nl;
}
Info<<"indirectly delete some items via set(.., nullptr) :" << endl;
for (label i = 2; i < 5; i++)
{ {
list1.set(i, nullptr); list1.set(i, nullptr);
} }
Info<<"release some items:" << endl;
for (label i = -2; i < 5; i++)
{
auto old = list1.release(i);
if (!old)
{
Info<< i << " was already released" << nl;
}
}
Info<<"list1: ";
print(Info, list1) << nl;
list1.resize(list1.squeezeNull());
Info<<"squeezed null: ";
print(Info, list1) << nl;
Info<<"transfer list2 -> list1:" << endl; Info<<"transfer list2 -> list1:" << endl;
list1.transfer(list2); list1.transfer(list2);

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -47,7 +47,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
template<class T, int SizeMin> class PtrDynList; template<class T, int SizeMin> class PtrDynList;
@ -62,11 +62,18 @@ class PtrDynList
{ {
static_assert(SizeMin > 0, "Invalid min size parameter"); static_assert(SizeMin > 0, "Invalid min size parameter");
// Private data // Private Data
//- The capacity (allocated size) of the list. //- The capacity (allocated size) of the list.
label capacity_; label capacity_;
// Private Member Functions
//- Adjust addressable size
void setAddressableSize(const label len);
public: public:
// Constructors // Constructors
@ -83,6 +90,9 @@ public:
//- Move construct //- Move construct
inline PtrDynList(PtrDynList<T, SizeMin>&& list); inline PtrDynList(PtrDynList<T, SizeMin>&& list);
//- Take ownerskip of pointers in the list, set old pointers to null.
inline explicit PtrDynList(UList<T*>& list);
//- Destructor //- Destructor
~PtrDynList() = default; ~PtrDynList() = default;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -26,6 +26,15 @@ License
#include "autoPtr.H" #include "autoPtr.H"
#include "tmp.H" #include "tmp.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::setAddressableSize(const label len)
{
(this->ptrs_).setAddressableSize(len);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T, int SizeMin> template<class T, int SizeMin>
@ -42,7 +51,7 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList(const label len)
PtrList<T>(len), PtrList<T>(len),
capacity_(len) capacity_(len)
{ {
PtrList<T>::size(0); setAddressableSize(0);
} }
@ -70,6 +79,14 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
} }
template<class T, int SizeMin>
inline Foam::PtrDynList<T, SizeMin>::PtrDynList(UList<T*>& list)
:
PtrList<T>(list),
capacity_(PtrList<T>::size())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, int SizeMin> template<class T, int SizeMin>
@ -92,7 +109,7 @@ inline void Foam::PtrDynList<T, SizeMin>::setCapacity(const label nElem)
} }
PtrList<T>::resize(capacity_); PtrList<T>::resize(capacity_);
(this->ptrs_).setAddressableSize(nextFree); setAddressableSize(nextFree);
} }
@ -108,7 +125,7 @@ inline void Foam::PtrDynList<T, SizeMin>::reserve(const label nElem)
// Adjust allocated size, leave addressed size untouched // Adjust allocated size, leave addressed size untouched
const label nextFree = PtrList<T>::size(); const label nextFree = PtrList<T>::size();
PtrList<T>::resize(capacity_); PtrList<T>::resize(capacity_);
(this->ptrs_).setAddressableSize(nextFree); setAddressableSize(nextFree);
} }
} }
@ -143,8 +160,7 @@ inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen)
} }
} }
// Adjust addressed size setAddressableSize(newLen);
ptrs.setAddressableSize(newLen);
} }
@ -159,7 +175,7 @@ template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::clear() inline void Foam::PtrDynList<T, SizeMin>::clear()
{ {
(this->ptrs_).free(); // free old pointers (this->ptrs_).free(); // free old pointers
(this->ptrs_).setAddressableSize(0); setAddressableSize(0);
} }
@ -177,7 +193,7 @@ inline Foam::label Foam::PtrDynList<T, SizeMin>::expandStorage()
const label nextFree = PtrList<T>::size(); const label nextFree = PtrList<T>::size();
// Allow addressing into the entire list // Allow addressing into the entire list
PtrList<T>::size(capacity_); setAddressableSize(capacity_);
return nextFree; return nextFree;
} }
@ -190,12 +206,12 @@ inline void Foam::PtrDynList<T, SizeMin>::shrink()
if (capacity_ > nextFree) if (capacity_ > nextFree)
{ {
// Use the full list when resizing // Use the full list when resizing
PtrList<T>::size(capacity_); setAddressableSize(capacity_);
// The new size // The new size
capacity_ = nextFree; capacity_ = nextFree;
PtrList<T>::resize(capacity_); PtrList<T>::resize(capacity_);
PtrList<T>::size(nextFree); setAddressableSize(nextFree);
} }
} }
@ -219,7 +235,7 @@ inline void Foam::PtrDynList<T, SizeMin>::append(const autoPtr<T>& aptr)
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::append(const tmp<T>& tptr) inline void Foam::PtrDynList<T, SizeMin>::append(const tmp<T>& tptr)
{ {
return this->append(const_cast<autoPtr<T>&>(tptr).ptr()); return this->append(tptr.ptr());
} }
@ -236,7 +252,7 @@ inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::remove()
autoPtr<T> old(this->ptrs_[idx]); autoPtr<T> old(this->ptrs_[idx]);
this->ptrs_[idx] = nullptr; this->ptrs_[idx] = nullptr;
(this->ptrs_).setAddressableSize(idx); setAddressableSize(idx);
return old; return old;
} }

View File

@ -53,7 +53,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
template<class T> class autoPtr; template<class T> class autoPtr;
template<class T> class tmp; template<class T> class tmp;
@ -98,6 +98,9 @@ public:
//- Move construct //- Move construct
inline PtrList(PtrList<T>&& list); inline PtrList(PtrList<T>&& list);
//- Take ownerskip of pointers in the list, set old pointers to null.
inline explicit PtrList(UList<T*>& list);
//- Copy construct using 'clone()' method on each element //- Copy construct using 'clone()' method on each element
template<class CloneArg> template<class CloneArg>
inline PtrList(const PtrList<T>& list, const CloneArg& cloneArgs); inline PtrList(const PtrList<T>& list, const CloneArg& cloneArgs);
@ -168,6 +171,10 @@ public:
//- Set element to given tmp and return old element //- Set element to given tmp and return old element
inline autoPtr<T> set(const label i, const tmp<T>& tptr); inline autoPtr<T> set(const label i, const tmp<T>& tptr);
//- Release ownership of the pointer at the given position.
// Out of bounds addressing is a no-op and returns nullptr.
inline autoPtr<T> release(const label i);
// Member Operators // Member Operators

View File

@ -67,6 +67,20 @@ inline Foam::PtrList<T>::PtrList(PtrList<T>&& list)
{} {}
template<class T>
inline Foam::PtrList<T>::PtrList(UList<T*>& list)
:
UPtrList<T>(list.size())
{
// Take ownership of the pointer
forAll(list, i)
{
set(i, list[i]);
list[i] = nullptr;
}
}
template<class T> template<class T>
template<class CloneArg> template<class CloneArg>
inline Foam::PtrList<T>::PtrList inline Foam::PtrList<T>::PtrList
@ -159,6 +173,18 @@ inline Foam::autoPtr<T> Foam::PtrList<T>::set(const label i, const tmp<T>& tptr)
} }
template<class T>
inline Foam::autoPtr<T> Foam::PtrList<T>::release(const label i)
{
if (i < 0 || i >= this->size())
{
return nullptr;
}
return autoPtr<T>(UPtrList<T>::set(i, nullptr));
}
template<class T> template<class T>
inline void Foam::PtrList<T>::transfer(PtrList<T>& list) inline void Foam::PtrList<T>::transfer(PtrList<T>& list)
{ {

View File

@ -103,7 +103,7 @@ Foam::autoPtr<Foam::functionObject> Foam::functionObjectList::remove
oldIndex = *iter; oldIndex = *iter;
// Remove pointer from the old list // Remove pointer from the old list
oldptr = this->set(oldIndex, nullptr); oldptr = this->release(oldIndex);
indices_.erase(iter); indices_.erase(iter);
} }
else else

View File

@ -306,7 +306,7 @@ void Foam::RBD::rigidBodyModel::makeComposite(const label bodyID)
if (!isA<compositeBody>(bodies_[bodyID])) if (!isA<compositeBody>(bodies_[bodyID]))
{ {
// Retrieve the un-merged body // Retrieve the un-merged body
autoPtr<rigidBody> bodyPtr = bodies_.set(bodyID, nullptr); autoPtr<rigidBody> bodyPtr = bodies_.release(bodyID);
// Insert the compositeBody containing the original body // Insert the compositeBody containing the original body
bodies_.set bodies_.set

View File

@ -391,7 +391,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
{ {
const dictionary& surfDict = capture[inputi]; const dictionary& surfDict = capture[inputi];
autoPtr<sampledSurface> surf = input.set(inputi, nullptr); autoPtr<sampledSurface> surf = input.release(inputi);
if (!surf.valid() || !surf->enabled()) if (!surf.valid() || !surf->enabled())
{ {