From 73e89f93326e18a871b018cb6a4995c49007a8be Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 21 Jan 2019 09:51:02 +0100 Subject: [PATCH] ENH: add UPtrList method to squeeze out (remove) null pointers - moves any nullptr to the end of the list where they can be eliminated in a second step with resize() --- applications/test/PtrList/Test-PtrList.C | 27 +++++++++++++++++++ .../PtrLists/PtrDynList/PtrDynList.H | 7 ++--- .../PtrLists/PtrDynList/PtrDynListI.H | 4 +-- .../containers/PtrLists/PtrList/PtrList.H | 3 +-- .../containers/PtrLists/UPtrList/UPtrList.C | 26 +++++++++++++++++- .../containers/PtrLists/UPtrList/UPtrList.H | 9 ++++--- 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/applications/test/PtrList/Test-PtrList.C b/applications/test/PtrList/Test-PtrList.C index 70e8ce184c..0082df0a1b 100644 --- a/applications/test/PtrList/Test-PtrList.C +++ b/applications/test/PtrList/Test-PtrList.C @@ -488,6 +488,33 @@ int main(int argc, char *argv[]) report(Info, dynPlanes, true); + { + // No clone for plane - do manual copy + PtrList stdPlanes(dynPlanes.size()); + + forAll(dynPlanes, i) + { + const plane* pln = dynPlanes.set(i); + if (pln) + { + stdPlanes.set(i, new plane(*pln)); + } + } + + report(Info, stdPlanes); + printAddr(Info, stdPlanes); + + stdPlanes.resize(stdPlanes.squeezeNull()); + + Info<<"After pruning nullptr entries" << endl; + printAddr(Info, stdPlanes); + } + + dynPlanes.resize(dynPlanes.squeezeNull()); + + Info<<"After pruning nullptr entries" << endl; + report(Info, dynPlanes, true); + Info<<"free()" << endl; dynPlanes.free(); diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H index f2c653973b..c4727fd6b9 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H @@ -106,7 +106,7 @@ public: //- Alter the addressed list size. inline void resize(const label newLen); - //- Alter the addressed list size. + //- Same as resize() inline void setSize(const label newLen); //- Reserve allocation space for at least this size. @@ -139,8 +139,9 @@ public: //- Remove and return the top element inline autoPtr remove(); - //- Return true if element is set (ie, not a nullptr) - inline bool set(const label i) const; + //- Return const pointer to element (if set) or nullptr. + // The return value can be tested as a bool. + inline const T* set(const label i) const; //- Set element to given pointer and return old element (can be null) inline autoPtr set(const label i, T* ptr); diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H index 159068a43d..e19508dd31 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H @@ -243,9 +243,9 @@ inline Foam::autoPtr Foam::PtrDynList::remove() template -inline bool Foam::PtrDynList::set(const label i) const +inline const T* Foam::PtrDynList::set(const label i) const { - return (i >= 0 && i < PtrList::size()) ? PtrList::set(i) : false; + return (i >= 0 && i < PtrList::size()) ? PtrList::set(i) : nullptr; } diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H index 2650882573..686efa83ad 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H @@ -131,8 +131,7 @@ public: // New entries are initialized to nullptr, removed entries are deleted void resize(const label newLen); - //- Adjust size of PtrList. - // New entries are initialized to nullptr, removed entries are deleted + //- Same as resize() inline void setSize(const label newLen); //- Append an element to the end of the list diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C index ca77270205..9b03f54871 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2015-2019 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -38,6 +38,30 @@ Foam::UPtrList::UPtrList(PtrList& list) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +Foam::label Foam::UPtrList::squeezeNull() +{ + const label len = this->size(); + label newLen = 0; + + for (label i=0; i < len; ++i) + { + T* ptr = ptrs_[i]; + if (ptr) + { + if (i != newLen) + { + ptrs_[newLen] = ptr; + ptrs_[i] = nullptr; + } + ++newLen; + } + } + + return newLen; +} + + template void Foam::UPtrList::reorder(const labelUList& oldToNew) { diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H index c7eac064fe..739fdf320c 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H @@ -132,7 +132,7 @@ public: inline explicit UPtrList(UList& list); - // Member functions + // Member Functions // Access @@ -164,10 +164,13 @@ public: // New entries are initialized to nullptr. inline void resize(const label newLen); - //- Reset size of list. - // New entries are initialized to nullptr. + //- Same as resize() inline void setSize(const label newLen); + //- Squeeze out intermediate nullptr entries in the list of pointers + // \return the number of non-null entries + label squeezeNull(); + //- Append an element to the end of the list inline void append(T* ptr);