diff --git a/applications/test/PtrList/Test-PtrList.C b/applications/test/PtrList/Test-PtrList.C index a2b51cc887fb558471aa11682c9c29a6a91fe0d6..e76ee21e092525147572d103a76046d380c5fd65 100644 --- a/applications/test/PtrList/Test-PtrList.C +++ b/applications/test/PtrList/Test-PtrList.C @@ -29,7 +29,7 @@ Description #include "scalar.H" #include "IOstreams.H" -#include "PtrList.H" +#include "PtrDynList.H" #include "DLPtrList.H" #include "SLPtrList.H" #include "plane.H" @@ -58,6 +58,16 @@ public: Info<<"delete Scalar: " << data_ << endl; } + const scalar& value() const + { + return data_; + } + + scalar& value() + { + return data_; + } + autoPtr<Scalar> clone() const { return autoPtr<Scalar>::New(data_); @@ -71,6 +81,151 @@ public: }; + +// As per +// +// template<class T> +// Ostream& operator<<(Ostream& os, const UPtrList<T>& list) +// +// but handle nullptr + +template<class T> +Ostream& printAddr +( + Ostream& os, + const UPtrList<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) + { + os << "addr=" << long(list(i)) << nl; + } + + // End delimiter + os << decrIndent << indent << token::END_LIST << nl; + return os; +} + + +// As per +// +// template<class T> +// Ostream& operator<<(Ostream& os, const UPtrList<T>& list) +// +// but handle nullptr + +template<class T> +Ostream& print +( + Ostream& os, + const UPtrList<T>& list, + const bool debug=false +) +{ + 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, int SizeMin> +Ostream& print +( + Ostream& os, + const PtrDynList<T, SizeMin>& list, + const bool debug=false +) +{ + 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; + } + } + + if (debug) + { + const label cap = list.capacity(); + + for (label i=len; i < cap; ++i) + { + const T* ptr = list(i); + + os << "unused " << long(ptr) << nl; + } + } + + + // End delimiter + os << decrIndent << indent << token::END_LIST << nl; + return os; +} + + +template<class T> +Ostream& report +( + Ostream& os, + const UPtrList<T>& list, + const bool debug=false +) +{ + return print(os, list, debug); +} + + +template<class T, int SizeMin> +Ostream& report +( + Ostream& os, + const PtrDynList<T,SizeMin>& list, + const bool debug=false +) +{ + os << "capacity=" << list.capacity() << nl; + return print(os, list, debug); +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -110,6 +265,23 @@ int main(int argc, char *argv[]) } } + // Same but as SLPtrList + { + SLPtrList<Scalar> llist1; + llist1.insert(new Scalar(100)); + llist1.insert(new Scalar(200)); + llist1.insert(new Scalar(300)); + + for (const auto& it : llist1) + { + Info<< typeid(it).name() << nl + << "for-: " << it << endl; + } + + PtrList<Scalar> list1b(llist1); + Info<< list1b << endl; + } + forAll(list1, i) { list1.set(i, new Scalar(1.3*i)); @@ -133,7 +305,7 @@ int main(int argc, char *argv[]) Info<<"indirectly delete some items via set(.., 0) :" << endl; for (label i = 0; i < 3; i++) { - list1.set(i, 0); + list1.set(i, nullptr); } Info<<"transfer list2 -> list1:" << endl; @@ -147,6 +319,36 @@ int main(int argc, char *argv[]) Info<<"list1: " << list1 << endl; + { + PtrList<Scalar> list1a(list1, false); + + Info<<"Clone constructed" << endl; + Info<<"in: " << list1 << nl + <<"out: " << list1a << nl + <<"addresses:" << nl; + printAddr(Info, list1); + printAddr(Info, list1a); + + PtrList<Scalar> list1b(list1a, true); + + Info<<"Reuse constructed" << endl; + Info<<"in: " << list1a << nl + <<"out: " << list1b << nl + <<"addresses:" << nl; + printAddr(Info, list1a); + printAddr(Info, list1b); + + + PtrList<Scalar> list1c(list1b.clone()); + + Info<<"Explicit clone()" << endl; + Info<<"in: " << list1b << nl + <<"out: " << list1c << nl + <<"addresses:" << nl; + printAddr(Info, list1b); + printAddr(Info, list1c); + } + PtrList<Scalar> list3(std::move(list1)); Info<<"Move constructed" << endl; @@ -174,6 +376,26 @@ int main(int argc, char *argv[]) UPtrList<Scalar> ulist1(list3); Info<<"ulist1: " << ulist1 << nl; + Info<<"PtrList addresses:"; + printAddr(Info, list3); + Info<<"UPtrList addresses:"; + printAddr(Info, ulist1); + Info<< nl; + + { + Info<<"UPtrList(const UPtrList&)" << nl; + + const UPtrList<Scalar>& cref = ulist1; + + UPtrList<Scalar> ulist1cp(cref); + + Info<<"src addresses:"; + printAddr(Info, cref); + Info<<"dst addresses:"; + printAddr(Info, ulist1cp); + Info<< nl; + } + Info<<"Move construct:" << endl; @@ -204,6 +426,10 @@ int main(int argc, char *argv[]) Info<< "iter[2]=" << iter1[2] << nl; Info<< "iter1 < iter2 : " << (iter1 < iter2) << nl; Info<< "iter1 >= iter2 : " << (iter1 >= iter2) << nl; + + Info<<"->" << iter1->value() << nl; + Info<<"*" << (*iter1).value() << nl; + Info<<"()" << iter1().value() << nl; } PtrList<plane> planes; @@ -216,6 +442,46 @@ int main(int argc, char *argv[]) Info<< " plane " << p << endl; } + Info<<"Testing PtrDynList" << nl; + + PtrDynList<plane> dynPlanes; + + { + dynPlanes.append(new plane(vector::one, vector::one)); + dynPlanes.append(new plane(vector(1,2,3), vector::one)); + dynPlanes.append(nullptr); + + dynPlanes.set(6, new plane(vector(2,2,1), vector::one)); + dynPlanes.set(10, new plane(vector(4,5,6), vector::one)); + } + + Info<< nl << "PtrList: "; + report(Info, dynPlanes, true); + + dynPlanes.resize(9); + + Info<< nl << "resize()"; + report(Info, dynPlanes, true); + + dynPlanes.clear(); + Info<<"clear()" << nl; + report(Info, dynPlanes); + + Info<<"now append again" << endl; + { + dynPlanes.append(new plane(vector::one, vector::one)); + dynPlanes.append(new plane(vector(1,2,3), vector::one)); + + dynPlanes.set(5, new plane(vector(2,2,1), vector::one)); + } + + report(Info, dynPlanes, true); + + Info<<"free()" << endl; + + dynPlanes.free(); + report(Info, dynPlanes, true); + Info<< nl << "Done." << endl; return 0; } diff --git a/applications/utilities/mesh/conversion/gambitToFoam/gambitToFoam.L b/applications/utilities/mesh/conversion/gambitToFoam/gambitToFoam.L index 436d3465b173329bf539cee6dc4d0610efadc5b0..38a013ac1348d19486cb809dd336f8aab37b9784 100644 --- a/applications/utilities/mesh/conversion/gambitToFoam/gambitToFoam.L +++ b/applications/utilities/mesh/conversion/gambitToFoam/gambitToFoam.L @@ -57,8 +57,6 @@ using namespace Foam; #include "emptyPolyPatch.H" #include "preservePatchTypes.H" #include "cellShape.H" -#include "SLList.H" -#include "SLPtrList.H" label nPoints = 0; label nCells = 0; diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H new file mode 100644 index 0000000000000000000000000000000000000000..c89d4e9f5ddb108e691c878958b30a90bef2040f --- /dev/null +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H @@ -0,0 +1,195 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::PtrDynList + +Description + A dynamically resizable PtrList with allocation management. + +See Also + Foam::UPtrList + Foam::PtrList + +SourceFiles + PtrDynListI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef PtrDynList_H +#define PtrDynList_H + +#include "PtrList.H" +#include <type_traits> + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declarations + +template<class T, int SizeMin> class PtrDynList; + +/*---------------------------------------------------------------------------*\ + Class PtrDynList Declaration +\*---------------------------------------------------------------------------*/ + +template<class T, int SizeMin=64> +class PtrDynList +: + public PtrList<T> +{ + static_assert(SizeMin > 0, "Invalid min size parameter"); + + // Private data + + //- The capacity (allocated size) of the list. + label capacity_; + +public: + + // Constructors + + //- Construct null + inline constexpr PtrDynList() noexcept; + + //- Construct with given capacity. + explicit inline PtrDynList(const label len); + + //- Copy construct using 'clone()' method on each element + inline PtrDynList(const PtrDynList<T, SizeMin>& list); + + //- Move construct + inline PtrDynList(PtrDynList<T, SizeMin>&& list); + + + //- Destructor + ~PtrDynList() = default; + + + // Member Functions + + // Access + + //- Size of the underlying storage. + inline label capacity() const; + + // Edit + + //- Delete the allocated entries, but retain the list size. + using PtrList<T>::free; + + //- Alter the size of the underlying storage. + inline void setCapacity(const label nElem); + + //- Alter the addressed list size. + inline void resize(const label newLen); + + //- Alter the addressed list size. + inline void setSize(const label newLen); + + //- Reserve allocation space for at least this size. + // Never shrinks the allocated size, use setCapacity() for that. + inline void reserve(const label nElem); + + //- Clear the addressed list, i.e. set the size to zero. + // Allocated size does not change + inline void clear(); + + //- Clear the list and delete storage. + inline void clearStorage(); + + //- Expand the addressable size to fit the allocated capacity. + // Returns the previous addressable size. + inline label expandStorage(); + + //- Shrink the allocated space to the number of elements used. + inline void shrink(); + + //- Append an element to the end of the list + inline void append(T* ptr); + + //- Append an element to the end of the list + inline void append(const autoPtr<T>& aptr); + + //- Append an element to the end of the list + inline void append(const tmp<T>& tptr); + + //- Remove and return the top element + inline autoPtr<T> remove(); + + //- Return true if element is set (ie, not a nullptr) + inline bool set(const label i) const; + + //- Set element to given pointer and return old element (can be null) + inline autoPtr<T> set(const label i, T* ptr); + + //- Set element to given autoPtr and return old element + inline autoPtr<T> set(const label i, const autoPtr<T>& aptr); + + //- Set element to given tmp and return old element + inline autoPtr<T> set(const label i, const tmp<T>& tptr); + + //- Reorder elements. Reordering must be unique (ie, shuffle). + inline void reorder(const labelUList& oldToNew); + + + // Member Operators + + //- Copy (clone) assignment + inline void operator=(const PtrList<T>& list); + + //- Copy (clone) assignment + inline void operator=(const PtrDynList<T, SizeMin>& list); + + //- Copy (clone) assignment with different sizing parameters + template<int AnySizeMin> + inline void operator=(const PtrDynList<T, AnySizeMin>& list); + + //- Move assignment + inline void operator=(PtrList<T>&& list); + + //- Move assignment + inline void operator=(PtrDynList<T, SizeMin>&& list); + + //- Move assignment with different sizing parameters + template<int AnySizeMin> + inline void operator=(PtrDynList<T, AnySizeMin>&& list); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "PtrDynListI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H new file mode 100644 index 0000000000000000000000000000000000000000..a1eaf65c374b14afe96b060684cfe828f5366e63 --- /dev/null +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H @@ -0,0 +1,373 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "autoPtr.H" +#include "tmp.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class T, int SizeMin> +inline constexpr Foam::PtrDynList<T, SizeMin>::PtrDynList() noexcept +: + PtrList<T>(), + capacity_(0) +{} + + +template<class T, int SizeMin> +inline Foam::PtrDynList<T, SizeMin>::PtrDynList(const label len) +: + PtrList<T>(len), + capacity_(len) +{ + PtrList<T>::size(0); +} + + +template<class T, int SizeMin> +inline Foam::PtrDynList<T, SizeMin>::PtrDynList +( + const PtrDynList<T, SizeMin>& list +) +: + PtrList<T>(list), + capacity_(PtrList<T>::size()) +{} + + +template<class T, int SizeMin> +inline Foam::PtrDynList<T, SizeMin>::PtrDynList +( + PtrDynList<T, SizeMin>&& list +) +: + PtrList<T>(std::move(list)), + capacity_(list.capacity_) +{ + list.clearStorage(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class T, int SizeMin> +inline Foam::label Foam::PtrDynList<T, SizeMin>::capacity() const +{ + return capacity_; +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::setCapacity(const label nElem) +{ + label nextFree = PtrList<T>::size(); + capacity_ = nElem; + + if (nextFree > capacity_) + { + // Truncate addressed sizes too + nextFree = capacity_; + } + + PtrList<T>::resize(capacity_); + (this->ptrs_).setAddressableSize(nextFree); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::reserve(const label nElem) +{ + if (nElem > capacity_) + { + // Allocate more capacity if necessary + + capacity_ = max(SizeMin, max(nElem, label(2*capacity_))); + + // Adjust allocated size, leave addressed size untouched + const label nextFree = PtrList<T>::size(); + PtrList<T>::resize(capacity_); + (this->ptrs_).setAddressableSize(nextFree); + } +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::resize(const label newLen) +{ + auto& ptrs = this->ptrs_; + + const label oldLen = ptrs.size(); + + if (newLen > capacity_) + { + // Allocate more capacity if necessary + capacity_ = max(SizeMin, max(newLen, label(2*capacity_))); + + PtrList<T>::resize(capacity_); + } + else if (newLen != oldLen) + { + // Truncation frees old pointers + for (label i=newLen; i<oldLen; ++i) + { + T* ptr = ptrs[i]; + + if (ptr) + { + delete ptr; + } + + ptrs[i] = nullptr; + } + } + + // Adjust addressed size + ptrs.setAddressableSize(newLen); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::setSize(const label newLen) +{ + this->resize(newLen); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::clear() +{ + (this->ptrs_).free(); // free old pointers + (this->ptrs_).setAddressableSize(0); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::clearStorage() +{ + PtrList<T>::clear(); + capacity_ = 0; +} + + +template<class T, int SizeMin> +inline Foam::label Foam::PtrDynList<T, SizeMin>::expandStorage() +{ + const label nextFree = PtrList<T>::size(); + + // Allow addressing into the entire list + PtrList<T>::size(capacity_); + + return nextFree; +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::shrink() +{ + label nextFree = PtrList<T>::size(); + if (capacity_ > nextFree) + { + // Use the full list when resizing + PtrList<T>::size(capacity_); + + // The new size + capacity_ = nextFree; + PtrList<T>::resize(capacity_); + PtrList<T>::size(nextFree); + } + return *this; +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::append(T* ptr) +{ + const label idx = this->size(); + resize(idx + 1); + this->ptrs_[idx] = ptr; +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::append(const autoPtr<T>& aptr) +{ + return this->append(const_cast<autoPtr<T>&>(aptr).release()); +} + + +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()); +} + + +template<class T, int SizeMin> +inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::remove() +{ + // Location of last element and simultaneously the new size + const label idx = (this->size() - 1); + + if (idx < 0) + { + return nullptr; // List is empty + } + + autoPtr<T> old(this->ptrs_[idx]); + this->ptrs_[idx] = nullptr; + (this->ptrs_).setAddressableSize(idx); + + return old; +} + + +template<class T, int SizeMin> +inline bool Foam::PtrDynList<T, SizeMin>::set(const label i) const +{ + return (i >= 0 && i < PtrList<T>::size()) ? PtrList<T>::set(i) : false; +} + + +template<class T, int SizeMin> +inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::set +( + const label i, + T* ptr +) +{ + if (i >= this->size()) + { + resize(i+1); + } + + return autoPtr<T>(UPtrList<T>::set(i, ptr)); +} + + +template<class T, int SizeMin> +inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::set +( + const label i, + const autoPtr<T>& aptr +) +{ + this->set(i, const_cast<autoPtr<T>&>(aptr).release()); +} + + +template<class T, int SizeMin> +inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::set +( + const label i, + const tmp<T>& tptr +) +{ + this->set(i, tptr.ptr()); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::reorder(const labelUList& oldToNew) +{ + // Shrinking first is a bit annoying, but saves needing a special version. + shrink(); + PtrList<T>::reorder(oldToNew); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::operator= +( + const PtrList<T>& list +) +{ + PtrList<T>::operator=(list); + capacity_ = PtrList<T>::size(); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::operator= +( + const PtrDynList<T, SizeMin>& list +) +{ + PtrList<T>::operator=(list); + capacity_ = PtrList<T>::size(); +} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline void Foam::PtrDynList<T, SizeMin>::operator= +( + const PtrDynList<T, AnySizeMin>& list +) +{ + PtrList<T>::operator=(list); + capacity_ = PtrList<T>::size(); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::operator= +( + PtrList<T>&& list +) +{ + PtrList<T>::transfer(list); + capacity_ = PtrList<T>::size(); + list.clearStorage(); +} + + +template<class T, int SizeMin> +inline void Foam::PtrDynList<T, SizeMin>::operator= +( + PtrDynList<T, SizeMin>&& list +) +{ + PtrList<T>::transfer(list); + capacity_ = list.capacity(); + list.clearStorage(); +} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline void Foam::PtrDynList<T, SizeMin>::operator= +( + PtrDynList<T, AnySizeMin>&& list +) +{ + PtrList<T>::transfer(list); + capacity_ = list.capacity(); + list.clearStorage(); +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/PtrList/PtrList.C b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.C similarity index 77% rename from src/OpenFOAM/containers/Lists/PtrList/PtrList.C rename to src/OpenFOAM/containers/PtrLists/PtrList/PtrList.C index d27a74223d14ed7656b2ac98446b479436b8b8a4..cad4676c67506f4a797fa5f610e07647ee6d49ae 100644 --- a/src/OpenFOAM/containers/Lists/PtrList/PtrList.C +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.C @@ -25,38 +25,10 @@ License #include "PtrList.H" #include "SLPtrList.H" +#include <utility> // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // -template<class T> -Foam::PtrList<T>::PtrList(const PtrList<T>& list) -: - UPtrList<T>(list.size()) -{ - const label len = this->size(); - - for (label i=0; i<len; ++i) - { - this->ptrs_[i] = (list[i]).clone().ptr(); - } -} - - -template<class T> -template<class CloneArg> -Foam::PtrList<T>::PtrList(const PtrList<T>& list, const CloneArg& cloneArg) -: - UPtrList<T>(list.size()) -{ - const label len = this->size(); - - for (label i=0; i<len; ++i) - { - this->ptrs_[i] = (list[i]).clone(cloneArg).ptr(); - } -} - - template<class T> Foam::PtrList<T>::PtrList(PtrList<T>& list, bool reuse) : @@ -64,6 +36,7 @@ Foam::PtrList<T>::PtrList(PtrList<T>& list, bool reuse) { if (!reuse) { + // This works like an inplace clone method const label len = this->size(); for (label i=0; i<len; ++i) @@ -90,67 +63,63 @@ Foam::PtrList<T>::PtrList(const SLPtrList<T>& list) } -// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template<class T> Foam::PtrList<T>::~PtrList() { - const label len = this->size(); - - // Free old pointers - for (label i=0; i<len; ++i) - { - if (this->ptrs_[i]) - { - delete this->ptrs_[i]; - } - } + (this->ptrs_).free(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class T> -void Foam::PtrList<T>::clear() +template<class... Args> +Foam::PtrList<T> Foam::PtrList<T>::clone(Args&&... args) const { const label len = this->size(); + PtrList<T> cloned(len); + for (label i=0; i<len; ++i) { - if (this->ptrs_[i]) + const T* ptr = this->ptrs_[i]; + + if (ptr) { - delete this->ptrs_[i]; + cloned.ptrs_[i] = ptr->clone(std::forward<Args>(args)...).ptr(); } } - UPtrList<T>::clear(); + return cloned; } template<class T> void Foam::PtrList<T>::resize(const label newLen) { + const label oldLen = this->size(); + if (newLen <= 0) { clear(); - return; } - - const label oldLen = this->size(); - - if (newLen != oldLen) + else if (newLen != oldLen) { // Truncation frees old pointers for (label i=newLen; i<oldLen; ++i) { - if (this->ptrs_[i]) + T* ptr = this->ptrs_[i]; + + if (ptr) { - delete this->ptrs_[i]; + delete ptr; } } // Any new elements are initialized to nullptr. - this->ptrs_.resize(newLen, reinterpret_cast<T*>(0)); + (this->ptrs_).resize(newLen); } } diff --git a/src/OpenFOAM/containers/Lists/PtrList/PtrList.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H similarity index 76% rename from src/OpenFOAM/containers/Lists/PtrList/PtrList.H rename to src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H index c04d92f7d6a1e08b778f2393b024649e2beb3476..7cdf1367a006d9fef7747d30c87574383a604c67 100644 --- a/src/OpenFOAM/containers/Lists/PtrList/PtrList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H @@ -30,7 +30,8 @@ Description The operator[] returns a reference to the object, not the pointer. See Also - Foam::PtrList + Foam::UPtrList + Foam::PtrDynList SourceFiles PtrListI.H @@ -56,7 +57,7 @@ template<class T> class autoPtr; template<class T> class tmp; template<class T> class PtrList; -template<class T> Istream& operator>>(Istream& is, PtrList<T>& lst); +template<class T> Istream& operator>>(Istream& is, PtrList<T>& list); /*---------------------------------------------------------------------------*\ @@ -68,7 +69,6 @@ class PtrList : public UPtrList<T> { - protected: // Protected Member Functions @@ -77,6 +77,8 @@ protected: template<class INew> void read(Istream& is, const INew& inew); + //- Delete the allocated entries, but retain the list size. + inline void free(); public: @@ -86,22 +88,22 @@ public: inline constexpr PtrList() noexcept; //- Construct with specified size, each element initialized to nullptr - explicit inline PtrList(const label nElem); + explicit inline PtrList(const label len); //- Copy construct using 'clone()' method on each element - PtrList(const PtrList<T>& list); + inline PtrList(const PtrList<T>& list); //- Move construct inline PtrList(PtrList<T>&& list); - //- Copy construct with additional argument for 'clone()' + //- Copy construct using 'clone()' method on each element template<class CloneArg> - PtrList(const PtrList<T>& list, const CloneArg& cloneArg); + inline PtrList(const PtrList<T>& list, const CloneArg& cloneArgs); //- Construct as copy or re-use as specified PtrList(PtrList<T>& list, bool reuse); - //- Construct as copy of SLPtrList<T> + //- Copy construct using 'clone()' on each element of SLPtrList\<T\> explicit PtrList(const SLPtrList<T>& list); //- Construct from Istream using given Istream constructor class @@ -118,24 +120,31 @@ public: // Member Functions - //- Clear the PtrList. Set size to zero and delete allocated entries - void clear(); + //- Make a copy by cloning each of the list elements. + template<class... Args> + PtrList<T> clone(Args&&... args) const; + + //- Clear the PtrList. Delete allocated entries and set size to zero. + inline void clear(); - //- Reset size of PtrList. + //- Adjust size of PtrList. // New entries are initialized to nullptr, removed entries are deleted void resize(const label newLen); - //- Reset size of PtrList. + //- Adjust size of PtrList. // New entries are initialized to nullptr, removed entries are deleted inline void setSize(const label newLen); - //- Append an element at the end of the list - using UPtrList<T>::append; + //- Append an element to the end of the list + inline void append(T* ptr); - //- Append an element at the end of the list - inline void append(const autoPtr<T>& aptr); + //- Move append an element to the end of the list + inline void append(autoPtr<T>& aptr); - //- Append an element at the end of the list + //- Move append an element to the end of the list + inline void append(autoPtr<T>&& aptr); + + //- Move or clone append a tmp to the end of the list inline void append(const tmp<T>& tptr); //- Transfer into this list and annul the argument list @@ -145,16 +154,19 @@ public: inline bool set(const label i) const; //- Set element to given pointer and return old element (can be null) - inline autoPtr<T> set(const label i, T* ptr); + inline autoPtr<T> set(label i, T* ptr); + + //- Set element to given autoPtr and return old element + inline autoPtr<T> set(label i, autoPtr<T>& aptr); //- Set element to given autoPtr and return old element - inline autoPtr<T> set(const label i, const autoPtr<T>& aptr); + inline autoPtr<T> set(label i, autoPtr<T>&& aptr); //- Set element to given tmp and return old element - inline autoPtr<T> set(const label i, const tmp<T>& tptr); + inline autoPtr<T> set(label i, const tmp<T>& tptr); - // Member operators + // Member Operators //- Copy assignment. // For existing list entries, values are copied from the list. @@ -167,7 +179,7 @@ public: // IOstream operator - //- Read PtrList from Istream, discarding contents of existing PtrList + //- Read from Istream, discarding contents of existing list friend Istream& operator>> <T>(Istream& is, PtrList<T>& list); }; diff --git a/src/OpenFOAM/containers/Lists/PtrList/PtrListI.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H similarity index 62% rename from src/OpenFOAM/containers/Lists/PtrList/PtrListI.H rename to src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H index 6b51538e96cacafaaee99190f0d26b25c0978c5a..bb2a19064a4334fe7e8c855489651f4b927af77d 100644 --- a/src/OpenFOAM/containers/Lists/PtrList/PtrListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H @@ -26,6 +26,15 @@ License #include "autoPtr.H" #include "tmp.H" +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +template<class T> +inline void Foam::PtrList<T>::free() +{ + (this->ptrs_).free(); +} + + // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // template<class T> @@ -36,9 +45,16 @@ inline constexpr Foam::PtrList<T>::PtrList() noexcept template<class T> -inline Foam::PtrList<T>::PtrList(const label nElem) +inline Foam::PtrList<T>::PtrList(const label len) +: + UPtrList<T>(len) +{} + + +template<class T> +inline Foam::PtrList<T>::PtrList(const PtrList<T>& list) : - UPtrList<T>(nElem) + UPtrList<T>(list.ptrs_.clone()) {} @@ -49,8 +65,28 @@ inline Foam::PtrList<T>::PtrList(PtrList<T>&& list) {} +template<class T> +template<class CloneArg> +inline Foam::PtrList<T>::PtrList +( + const PtrList<T>& list, + const CloneArg& cloneArg +) +: + UPtrList<T>(list.clone(cloneArg)()) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class T> +inline void Foam::PtrList<T>::clear() +{ + (this->ptrs_).free(); + UPtrList<T>::clear(); +} + + template<class T> inline void Foam::PtrList<T>::setSize(const label newLen) { @@ -59,16 +95,30 @@ inline void Foam::PtrList<T>::setSize(const label newLen) template<class T> -inline void Foam::PtrList<T>::append(const autoPtr<T>& aptr) +inline void Foam::PtrList<T>::append(T* ptr) { - return UPtrList<T>::append(const_cast<autoPtr<T>&>(aptr).ptr()); + UPtrList<T>::append(ptr); +} + + +template<class T> +inline void Foam::PtrList<T>::append(autoPtr<T>& aptr) +{ + return UPtrList<T>::append(aptr.release()); +} + + +template<class T> +inline void Foam::PtrList<T>::append(autoPtr<T>&& aptr) +{ + return UPtrList<T>::append(aptr.release()); } template<class T> inline void Foam::PtrList<T>::append(const tmp<T>& tptr) { - return UPtrList<T>::append(const_cast<tmp<T>&>(tptr).ptr()); + return UPtrList<T>::append(tptr.ptr()); } @@ -80,38 +130,37 @@ inline bool Foam::PtrList<T>::set(const label i) const template<class T> -inline Foam::autoPtr<T> Foam::PtrList<T>::set(const label i, T* ptr) +inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, T* ptr) { return autoPtr<T>(UPtrList<T>::set(i, ptr)); } template<class T> -inline Foam::autoPtr<T> Foam::PtrList<T>::set -( - const label i, - const autoPtr<T>& aptr -) +inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, autoPtr<T>& aptr) { - return set(i, const_cast<autoPtr<T>&>(aptr).ptr()); + return set(i, aptr.release()); } template<class T> -inline Foam::autoPtr<T> Foam::PtrList<T>::set -( - const label i, - const tmp<T>& tptr -) +inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, autoPtr<T>&& aptr) +{ + return set(i, aptr.release()); +} + + +template<class T> +inline Foam::autoPtr<T> Foam::PtrList<T>::set(label i, const tmp<T>& tptr) { - return set(i, const_cast<tmp<T>&>(tptr).ptr()); + return set(i, tptr.ptr()); } template<class T> inline void Foam::PtrList<T>::transfer(PtrList<T>& list) { - this->clear(); + this->free(); // free old pointers UPtrList<T>::transfer(list); } diff --git a/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListIO.C similarity index 88% rename from src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C rename to src/OpenFOAM/containers/PtrLists/PtrList/PtrListIO.C index 141225f776bb6289e55bb7b08006b44dfb12de48..be3da434352fcafa354f9fc35a25e53c85ccbcad 100644 --- a/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListIO.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 | + \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,7 +26,6 @@ License #include "PtrList.H" #include "SLList.H" #include "Istream.H" -#include "Ostream.H" #include "INew.H" // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // @@ -35,6 +34,8 @@ template<class T> template<class INew> void Foam::PtrList<T>::read(Istream& is, const INew& inew) { + clear(); // Delete old pointers and reset the list size + is.fatalCheck(FUNCTION_NAME); token firstToken(is); @@ -53,7 +54,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew) const label len = firstToken.labelToken(); // Set list length to that read - setSize(len); + resize(len); // Read beginning of contents const char delimiter = is.readBeginList("PtrList"); @@ -100,6 +101,8 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew) // "(...)" : read as SLList and transfer contents + // This would be more efficient (fewer allocations, lower overhead) + // using a DynamicList, but then we have circular dependencies if (firstToken.isPunctuation()) { if (firstToken.pToken() != token::BEGIN_LIST) @@ -111,7 +114,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew) << exit(FatalIOError); } - SLList<T*> sllPtrs; + SLList<T*> slList; token lastToken(is); while @@ -133,15 +136,15 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inew) << exit(FatalIOError); } - sllPtrs.append(inew(is).ptr()); + slList.append(inew(is).ptr()); is >> lastToken; } - setSize(sllPtrs.size()); + resize(slList.size()); - // A list of pointers - can simply copy + // A list of pointers - can simply shallow copy them label i = 0; - for (T* ptr : sllPtrs) + for (T* ptr : slList) { set(i++, ptr); } @@ -178,11 +181,9 @@ Foam::PtrList<T>::PtrList(Istream& is) // * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * // template<class T> -Foam::Istream& Foam::operator>>(Istream& is, PtrList<T>& lst) +Foam::Istream& Foam::operator>>(Istream& is, PtrList<T>& list) { - lst.clear(); - lst.read(is, INew<T>()); - + list.read(is, INew<T>()); return is; } diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C new file mode 100644 index 0000000000000000000000000000000000000000..96d2a9aaf83e8f7b4b7b666f160f989e055ce50f --- /dev/null +++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C @@ -0,0 +1,92 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "PtrListDetail.H" +#include <utility> + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class T> +Foam::label Foam::Detail::PtrListDetail<T>::count() const +{ + label ngood = 0; + + for (const T* ptr : *this) + { + if (ptr) + { + ++ngood; + } + } + + return ngood; +} + + +template<class T> +void Foam::Detail::PtrListDetail<T>::free() +{ + List<T*>& ptrs = *this; + const label len = ptrs.size(); + + for (label i=0; i<len; ++i) + { + T* ptr = ptrs[i]; + + if (ptr) + { + delete ptr; + } + + ptrs[i] = nullptr; + } +} + + +template<class T> +template<class... Args> +Foam::Detail::PtrListDetail<T> +Foam::Detail::PtrListDetail<T>::clone(Args&&... args) const +{ + const List<T*>& ptrs = *this; + const label len = ptrs.size(); + + PtrListDetail<T> cloned(len); + + for (label i=0; i<len; ++i) + { + const T* ptr = ptrs[i]; + + if (ptr) + { + cloned[i] = ptr->clone(std::forward<Args>(args)...).ptr(); + } + } + + return cloned; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H new file mode 100644 index 0000000000000000000000000000000000000000..5405699d03438e244ea40de10d26e35de8ae1324 --- /dev/null +++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H @@ -0,0 +1,147 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::Detail::PtrListDetail + +Description + A rudimentary list of pointers used for PtrList, UPtrList, etc. + This class is considered implementation detail and should not normally + be used other than by OpenFOAM container classes. + +SourceFiles + PtrListDetailI.H + PtrListDetail.C + PtrListDetailIO.C + +\*---------------------------------------------------------------------------*/ + +#ifndef PtrListDetail_H +#define PtrListDetail_H + +#include "List.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declarations +class Ostream; + +namespace Detail +{ + +/*---------------------------------------------------------------------------*\ + Class Detail::PtrListDetail Declaration +\*---------------------------------------------------------------------------*/ + +template<class T> +class PtrListDetail +: + public List<T*> +{ +public: + + // Constructors + + //- Construct null + inline constexpr PtrListDetail() noexcept; + + //- Construct with specified size, each element initialized to nullptr + inline PtrListDetail(const label len); + + //- Copy construct (shallow copies addresses) + inline PtrListDetail(const PtrListDetail<T>& list); + + //- Move construct + inline PtrListDetail(PtrListDetail<T>&& list); + + //- Copy or move (reuse) construct as specified + inline PtrListDetail(PtrListDetail<T>& list, bool reuse); + + + // Member Functions + + //- Return the count of non-nullptr entries + label count() const; + + //- Delete the allocated entries, but retain the list size. + void free(); + + //- Make a copy by cloning each of the list pointers. + template<class... Args> + PtrListDetail<T> clone(Args&&... args) const; + + //- Reset size of list. + // New entries are initialized to nullptr. + inline void resize(const label newLen); + + //- Override size to be inconsistent with allocated storage. + // Use with care + inline void setAddressableSize(const label n); + + //- Write output, optionally silently trimming nullptrs + Ostream& write(Ostream& os, const bool trimNull=false) const; + + + // Member Operators + + //- Copy assignment (shallow copies addresses) + inline void operator=(const PtrListDetail<T>& list); + + //- Move assignment + inline void operator=(PtrListDetail<T>&& list); + + + // Housekeeping + + // Just use resize(). + void setSize(const label) = delete; + void setSize(const label, const T&) = delete; + void setSize(const label, const T*) = delete; + +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Detail +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "PtrListDetailI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "PtrListDetail.C" + #include "PtrListDetailIO.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailI.H b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailI.H new file mode 100644 index 0000000000000000000000000000000000000000..9e0026e87f322efbc7fdba26ef6844090b26bc9d --- /dev/null +++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailI.H @@ -0,0 +1,119 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // + +template<class T> +inline constexpr Foam::Detail::PtrListDetail<T>::PtrListDetail() noexcept +: + List<T*>() +{} + + +template<class T> +inline Foam::Detail::PtrListDetail<T>::PtrListDetail(const label len) +: + List<T*>(len, reinterpret_cast<T*>(0)) +{} + + +template<class T> +inline Foam::Detail::PtrListDetail<T>::PtrListDetail +( + const PtrListDetail<T>& list +) +: + List<T*>(list) +{} + + +template<class T> +inline Foam::Detail::PtrListDetail<T>::PtrListDetail +( + PtrListDetail<T>&& list +) +: + List<T*>(std::move(list)) +{} + + +template<class T> +inline Foam::Detail::PtrListDetail<T>::PtrListDetail +( + PtrListDetail<T>& list, + bool reuse +) +: + List<T*>(list, reuse) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class T> +inline void Foam::Detail::PtrListDetail<T>::setAddressableSize(const label n) +{ + List<T*>::size(n); +} + + +template<class T> +inline void Foam::Detail::PtrListDetail<T>::resize(const label newLen) +{ + if (newLen <= 0) + { + List<T*>::clear(); + } + else if (newLen != List<T*>::size()) + { + // Truncate or extend. Any new elements are initialized to nullptr. + List<T*>::resize(newLen, reinterpret_cast<T*>(0)); + } +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template<class T> +inline void Foam::Detail::PtrListDetail<T>::operator= +( + const PtrListDetail<T>& list +) +{ + List<T*>::operator=(list); // shallow copy +} + + +template<class T> +inline void Foam::Detail::PtrListDetail<T>::operator= +( + PtrListDetail<T>&& list +) +{ + List<T*>::transfer(list); +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailIO.C similarity index 66% rename from src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C rename to src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailIO.C index bbc9f60282e74d5f817c200f9c4590ff42e6d71e..37d5f65a707864ffa7a5ebea228174a4ede66914 100644 --- a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C +++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailIO.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,24 +23,40 @@ License \*---------------------------------------------------------------------------*/ -#include "UPtrList.H" +#include "PtrListDetail.H" +#include "error.H" #include "Ostream.H" -// * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class T> -Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& lst) +Foam::Ostream& Foam::Detail::PtrListDetail<T>::write +( + Ostream& os, + const bool trimNull +) const { - const label len = lst.size(); + const label len = this->size(); - // Size and start delimiter - os << nl << indent << len << nl + // The (output) size and start delimiter + os << nl << indent << (trimNull ? this->count() : len) << nl << indent << token::BEGIN_LIST << incrIndent << nl; // Contents for (label i=0; i < len; ++i) { - os << lst[i] << nl; + const T* ptr = (*this)[i]; + if (ptr) + { + os << *ptr << nl; + } + else if (!trimNull) + { + FatalErrorInFunction + << "cannot dereference nullptr at index " << i + << " in range [0," << len << ")" + << abort(FatalError); + } } // End delimiter diff --git a/src/OpenFOAM/containers/Lists/UPtrList/UPtrList.C b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C similarity index 79% rename from src/OpenFOAM/containers/Lists/UPtrList/UPtrList.C rename to src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C index 317cf817d7a4792c122e32750e717db41b7e1461..ca77270205beee25c6a98ee0d6fc5ea7b01e971b 100644 --- a/src/OpenFOAM/containers/Lists/UPtrList/UPtrList.C +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C @@ -24,21 +24,16 @@ License \*---------------------------------------------------------------------------*/ #include "UPtrList.H" +#include "PtrList.H" +#include "Ostream.H" // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // template<class T> -Foam::UPtrList<T>::UPtrList(UList<T>& lst) +Foam::UPtrList<T>::UPtrList(PtrList<T>& list) : - ptrs_(lst.size()) -{ - const label len = lst.size(); - - for (label i=0; i<len; ++i) - { - ptrs_[i] = &(lst[i]); - } -} + ptrs_(list.ptrs_) // shallow copy (via const reference) +{} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -57,8 +52,7 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew) << abort(FatalError); } - // New list of pointers - List<T*> ptrLst(len, reinterpret_cast<T*>(0)); + Detail::PtrListDetail<T> newList(len); for (label i=0; i<len; ++i) { @@ -68,25 +62,25 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew) { FatalErrorInFunction << "Illegal index " << idx << nl - << "Valid indices are 0.." << len-1 - << " for type " << typeid(T).name() << nl + << "Valid indices are [0," << len << ") for type " + << typeid(T).name() << nl << abort(FatalError); } - if (ptrLst[idx]) + if (newList[idx]) { FatalErrorInFunction << "reorder map is not unique; element " << idx << " already set for type " << typeid(T).name() << abort(FatalError); } - ptrLst[idx] = ptrs_[i]; + newList[idx] = ptrs_[i]; } - // Verify that all pointers were set + // Verify that all pointers were indeed set for (label i=0; i<len; ++i) { - if (!ptrLst[i]) + if (!newList[i]) { FatalErrorInFunction << "Element " << i << " not set after reordering." << nl @@ -94,7 +88,16 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew) } } - ptrs_.swap(ptrLst); + ptrs_.transfer(newList); +} + + +// * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * // + +template<class T> +Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list) +{ + return list.ptrs_.write(os); } diff --git a/src/OpenFOAM/containers/Lists/UPtrList/UPtrList.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H similarity index 82% rename from src/OpenFOAM/containers/Lists/UPtrList/UPtrList.H rename to src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H index ae2061d4fb935b1f5ffbe949c713c13361f2fee9..212adf26e4f68efbc5246f4763a0701901a0f5ad 100644 --- a/src/OpenFOAM/containers/Lists/UPtrList/UPtrList.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H @@ -29,21 +29,25 @@ Description management of the pointers - this is to be done elsewhere. The operator[] returns a reference to the object, not the pointer. +Note + The class definition is such that it contains a list of pointers, but + itself does not inherit from a list of pointers since this would + wreak havoc later inheritance resolution. + See Also Foam::PtrList + Foam::PtrDynList SourceFiles UPtrListI.H UPtrList.C - UPtrListIO.C \*---------------------------------------------------------------------------*/ #ifndef UPtrList_H #define UPtrList_H -#include "List.H" -#include "PtrList.H" +#include "PtrListDetail.H" #include <iterator> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -68,9 +72,16 @@ class UPtrList { protected: - // Protected data + // Protected Member Data + + //- The list of pointers + Detail::PtrListDetail<T> ptrs_; + - List<T*> ptrs_; + // Constructors + + //- Low-level move construct + inline UPtrList(Detail::PtrListDetail<T>&& ptrs); public: @@ -101,32 +112,34 @@ public: //- Construct with specified size, each element initialized to nullptr explicit inline UPtrList(const label len); - //- Construct from PtrList, copying addresses of each list element. - // The argument is non-const access since this UPtrList can be used - // to change its values. - explicit inline UPtrList(PtrList<T>& list); + //- Copy construct (shallow copies addresses) + inline UPtrList(const UPtrList<T>& list); - //- Construct from UList, taking addresses of each list element - explicit UPtrList(UList<T>& list); + //- Move construct + inline UPtrList(UPtrList<T>&& list); - //- Construct as copy or re-use as specified + //- Construct as shallow copy or re-use as specified inline UPtrList(UPtrList<T>& list, bool reuse); - //- Copy construct - inline UPtrList(const UPtrList<T>& list) = default; + //- Shallow copy from PtrList. + // The argument is non-const to reflect that the UPtrList can change + // the values (but not the addresses) of the original list. + explicit UPtrList(PtrList<T>& list); - //- Move construct - inline UPtrList(UPtrList<T>&& list); + //- Construct from UList, taking the address of each list element + // The argument is non-const to reflect that the UPtrList can change + // the values of the original list. + explicit inline UPtrList(UList<T>& list); // Member functions // Access - //- Return the number of elements in the UPtrList + //- Return the number of elements in the list inline label size() const; - //- Return true if the UPtrList is empty (ie, size() is zero) + //- Return true if the list is empty (ie, size() is zero) inline bool empty() const; //- Return reference to the first element of the list @@ -147,11 +160,11 @@ public: //- Set list size to zero. inline void clear(); - //- Reset size of UPtrList. + //- Reset size of list. // New entries are initialized to nullptr. inline void resize(const label newLen); - //- Reset size of UPtrList. + //- Reset size of list. // New entries are initialized to nullptr. inline void setSize(const label newLen); @@ -164,10 +177,11 @@ public: //- Transfer contents into this list and annul the argument inline void transfer(UPtrList<T>& list); - //- Return true if element is set (ie, not a nullptr) + //- Return true if element is set (not a nullptr) inline bool set(const label i) const; - //- Set element to given pointer and return old element (can be null). + //- Set element to specified pointer and return the old list element, + //- which can be a nullptr. // No checks on new element inline T* set(const label i, T* ptr); @@ -175,19 +189,19 @@ public: void reorder(const labelUList& oldToNew); - // Member operators + // Member Operators - //- Return element const reference + //- Return const reference to the element inline const T& operator[](const label i) const; - //- Return element reference + //- Return reference to the element inline T& operator[](const label i); - //- Return element const pointer + //- Return const pointer to the element inline const T* operator()(const label i) const; - //- Copy assignment - UPtrList<T>& operator=(const UPtrList<T>& list) = default; + //- Copy assignment (shallow copies addresses) + inline void operator=(const UPtrList<T>& list); //- Move assignment inline void operator=(UPtrList<T>&& list); @@ -217,7 +231,9 @@ public: inline bool operator==(const iterator& iter) const; inline bool operator!=(const iterator& iter) const; + inline pointer operator->() const; inline reference operator*() const; + inline reference operator()() const; // Forward iteration @@ -269,7 +285,9 @@ public: inline bool operator==(const const_iterator& iter) const; inline bool operator!=(const const_iterator& iter) const; + inline pointer operator->() const; inline reference operator*() const; + inline reference operator()() const; // Forward iteration @@ -319,7 +337,11 @@ public: // IOstream operator //- Write UPtrList to Ostream - friend Ostream& operator<< <T>(Ostream& os, const UPtrList<T>& list); + friend Ostream& operator<< <T> + ( + Ostream& os, + const UPtrList<T>& list + ); }; @@ -336,7 +358,6 @@ public: #ifdef NoRepository #include "UPtrList.C" - #include "UPtrListIO.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListI.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H similarity index 90% rename from src/OpenFOAM/containers/Lists/UPtrList/UPtrListI.H rename to src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H index be76d3ea34543e06df728f1f1429ac30c71c4984..a93b00df713bba77426ac656e45e879a554516df 100644 --- a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListI.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H @@ -35,12 +35,19 @@ inline constexpr Foam::UPtrList<T>::UPtrList() noexcept template<class T> inline Foam::UPtrList<T>::UPtrList(const label len) : - ptrs_(len, reinterpret_cast<T*>(0)) + ptrs_(len) {} template<class T> -inline Foam::UPtrList<T>::UPtrList(PtrList<T>& list) +inline Foam::UPtrList<T>::UPtrList(Detail::PtrListDetail<T>&& ptrs) +: + ptrs_(std::move(ptrs)) +{} + + +template<class T> +inline Foam::UPtrList<T>::UPtrList(const UPtrList<T>& list) : ptrs_(list.ptrs_) {} @@ -60,6 +67,20 @@ inline Foam::UPtrList<T>::UPtrList(UPtrList<T>& list, bool reuse) {} +template<class T> +inline Foam::UPtrList<T>::UPtrList(UList<T>& list) +: + ptrs_(list.size()) +{ + const label len = ptrs_.size(); + + for (label i=0; i<len; ++i) + { + ptrs_[i] = &(list[i]); + } +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class T> @@ -128,25 +149,14 @@ inline const T& Foam::UPtrList<T>::last() const template<class T> inline void Foam::UPtrList<T>::resize(const label newLen) { - if (newLen <= 0) - { - clear(); - return; - } - - const label oldLen = this->size(); - if (newLen != oldLen) - { - // Truncate or extend. Any new elements are initialized to nullptr. - ptrs_.resize(newLen, reinterpret_cast<T*>(0)); - } + ptrs_.resize(newLen); } template<class T> inline void Foam::UPtrList<T>::setSize(const label newLen) { - this->resize(newLen); + ptrs_.resize(newLen); } @@ -180,30 +190,34 @@ inline T* Foam::UPtrList<T>::set(const label i, T* ptr) template<class T> inline const T& Foam::UPtrList<T>::operator[](const label i) const { - if (!ptrs_[i]) + const T* ptr = ptrs_[i]; + + if (!ptr) { FatalErrorInFunction << "cannot dereference nullptr at index " << i - << " (size " << size() << ")" + << " in range [0," << size() << ")" << abort(FatalError); } - return *(ptrs_[i]); + return *ptr; } template<class T> inline T& Foam::UPtrList<T>::operator[](const label i) { - if (!ptrs_[i]) + T* ptr = ptrs_[i]; + + if (!ptr) { FatalErrorInFunction << "cannot dereference nullptr at index " << i - << " (size " << size() << ")" + << " in range [0," << size() << ")" << abort(FatalError); } - return *(ptrs_[i]); + return *ptr; } @@ -214,7 +228,7 @@ inline const T* Foam::UPtrList<T>::operator()(const label i) const } -// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * iterator * * * * * * * * * * * * * * * * // template<class T> inline Foam::UPtrList<T>::iterator::iterator(T** ptr) @@ -237,6 +251,13 @@ inline bool Foam::UPtrList<T>::iterator::operator!=(const iterator& iter) const } +template<class T> +inline T* Foam::UPtrList<T>::iterator::operator->() const +{ + return *ptr_; +} + + template<class T> inline T& Foam::UPtrList<T>::iterator::operator*() const { @@ -366,7 +387,7 @@ inline bool Foam::UPtrList<T>::iterator::operator>=(const iterator& iter) const } -// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * const_iterator * * * * * * * * * * * * * * // template<class T> inline Foam::UPtrList<T>::const_iterator::const_iterator(const T* const* ptr) @@ -402,6 +423,13 @@ inline bool Foam::UPtrList<T>::const_iterator::operator!= } +template<class T> +inline const T* Foam::UPtrList<T>::const_iterator::operator->() const +{ + return *ptr_; +} + + template<class T> inline const T& Foam::UPtrList<T>::const_iterator::operator*() const { @@ -596,10 +624,17 @@ Foam::UPtrList<T>::end() const // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // +template<class T> +inline void Foam::UPtrList<T>::operator=(const UPtrList<T>& list) +{ + ptrs_ = list.ptrs_; // shallow copy +} + + template<class T> inline void Foam::UPtrList<T>::operator=(UPtrList<T>&& list) { - this->transfer(list); + ptrs_.transfer(list.ptrs_); }