Commit 7795adfc authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

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
parent 683817bc
......@@ -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>
Ostream& report
(
......@@ -304,12 +337,60 @@ int main(int argc, char *argv[])
<<"list2: " << list2 << nl
<<"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);
}
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;
list1.transfer(list2);
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -47,7 +47,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
template<class T, int SizeMin> class PtrDynList;
......@@ -62,11 +62,18 @@ class PtrDynList
{
static_assert(SizeMin > 0, "Invalid min size parameter");
// Private data
// Private Data
//- The capacity (allocated size) of the list.
label capacity_;
// Private Member Functions
//- Adjust addressable size
void setAddressableSize(const label len);
public:
// Constructors
......@@ -83,6 +90,9 @@ public:
//- Move construct
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
~PtrDynList() = default;
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -26,6 +26,15 @@ License
#include "autoPtr.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 * * * * * * * * * * * * * * //
template<class T, int SizeMin>
......@@ -42,7 +51,7 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList(const label len)
PtrList<T>(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 * * * * * * * * * * * * * //
template<class T, int SizeMin>
......@@ -92,7 +109,7 @@ inline void Foam::PtrDynList<T, SizeMin>::setCapacity(const label nElem)
}
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
const label nextFree = PtrList<T>::size();
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
ptrs.setAddressableSize(newLen);
setAddressableSize(newLen);
}
......@@ -159,7 +175,7 @@ template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::clear()
{
(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();
// Allow addressing into the entire list
PtrList<T>::size(capacity_);
setAddressableSize(capacity_);
return nextFree;
}
......@@ -190,12 +206,12 @@ inline void Foam::PtrDynList<T, SizeMin>::shrink()
if (capacity_ > nextFree)
{
// Use the full list when resizing
PtrList<T>::size(capacity_);
setAddressableSize(capacity_);
// The new size
capacity_ = nextFree;
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>
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]);
this->ptrs_[idx] = nullptr;
(this->ptrs_).setAddressableSize(idx);
setAddressableSize(idx);
return old;
}
......
......@@ -53,7 +53,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
template<class T> class autoPtr;
template<class T> class tmp;
......@@ -98,6 +98,9 @@ public:
//- Move construct
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
template<class CloneArg>
inline PtrList(const PtrList<T>& list, const CloneArg& cloneArgs);
......@@ -168,6 +171,10 @@ public:
//- Set element to given tmp and return old element
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
......
......@@ -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 CloneArg>
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>
inline void Foam::PtrList<T>::transfer(PtrList<T>& list)
{
......
......@@ -103,7 +103,7 @@ Foam::autoPtr<Foam::functionObject> Foam::functionObjectList::remove
oldIndex = *iter;
// Remove pointer from the old list
oldptr = this->set(oldIndex, nullptr);
oldptr = this->release(oldIndex);
indices_.erase(iter);
}
else
......
......@@ -306,7 +306,7 @@ void Foam::RBD::rigidBodyModel::makeComposite(const label bodyID)
if (!isA<compositeBody>(bodies_[bodyID]))
{
// 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
bodies_.set
......
......@@ -391,7 +391,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
{
const dictionary& surfDict = capture[inputi];
autoPtr<sampledSurface> surf = input.set(inputi, nullptr);
autoPtr<sampledSurface> surf = input.release(inputi);
if (!surf.valid() || !surf->enabled())
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment