diff --git a/applications/test/PtrList/Test-PtrList.C b/applications/test/PtrList/Test-PtrList.C index dc55f9175cf9de9d5d1b4bd6dc8846f741e643dc..c6632ad4fbc20ce72e7dea8f2022e097c3ca8908 100644 --- a/applications/test/PtrList/Test-PtrList.C +++ b/applications/test/PtrList/Test-PtrList.C @@ -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); diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H index c4727fd6b931f3bdca9f2a0b5a10a8b9bc358c67..39b1a27fe88f0dc0794fa77791a30e2f258a39f3 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H @@ -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; diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H index 08ac982b5e5c45ba3eccf00cfeb6540ee5fcbb7a..d31a69a850482eff1b2809552bd135ab91d6f88e 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H @@ -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; } diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H index 61096e0c9371cd3b4470c3519905ded8d4b10a04..4a7e7595512f768eff7cf42592920620f1557370 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H @@ -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 diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H index a18ad3de019df4d44ed7955fb04739ff6a9404da..43a9b572d4fa6ee17f109e9b67a7a3b9434352e5 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H @@ -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) { diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C index 55d6671017bc77eda3d1ecb1727745a37100c07d..261b112947314cba7c2eac58317c14c08b1a2cd2 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C +++ b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C @@ -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 diff --git a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C index 0fd498b21df3d582772ad84fdbae6c42595deef7..2288ece2ad34619d156aa46232f2a119c5decfb9 100644 --- a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C +++ b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C @@ -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 diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C index 2892fe86362fbfde4f3de09134c7572a5a249f89..2bf31b267432fc10aea3b7fa68d065d84b766192 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C @@ -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()) {