diff --git a/applications/test/PtrList/Test-PtrList.C b/applications/test/PtrList/Test-PtrList.C index a2b51cc887..e76ee21e09 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 clone() const { return autoPtr::New(data_); @@ -71,6 +81,151 @@ public: }; + +// As per +// +// template +// Ostream& operator<<(Ostream& os, const UPtrList& list) +// +// but handle nullptr + +template +Ostream& printAddr +( + Ostream& os, + const UPtrList& 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 +// Ostream& operator<<(Ostream& os, const UPtrList& list) +// +// but handle nullptr + +template +Ostream& print +( + Ostream& os, + const UPtrList& 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 +Ostream& print +( + Ostream& os, + const PtrDynList& 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 +Ostream& report +( + Ostream& os, + const UPtrList& list, + const bool debug=false +) +{ + return print(os, list, debug); +} + + +template +Ostream& report +( + Ostream& os, + const PtrDynList& 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 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 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 list1a(list1, false); + + Info<<"Clone constructed" << endl; + Info<<"in: " << list1 << nl + <<"out: " << list1a << nl + <<"addresses:" << nl; + printAddr(Info, list1); + printAddr(Info, list1a); + + PtrList list1b(list1a, true); + + Info<<"Reuse constructed" << endl; + Info<<"in: " << list1a << nl + <<"out: " << list1b << nl + <<"addresses:" << nl; + printAddr(Info, list1a); + printAddr(Info, list1b); + + + PtrList list1c(list1b.clone()); + + Info<<"Explicit clone()" << endl; + Info<<"in: " << list1b << nl + <<"out: " << list1c << nl + <<"addresses:" << nl; + printAddr(Info, list1b); + printAddr(Info, list1c); + } + PtrList list3(std::move(list1)); Info<<"Move constructed" << endl; @@ -174,6 +376,26 @@ int main(int argc, char *argv[]) UPtrList 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& cref = ulist1; + + UPtrList 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 planes; @@ -216,6 +442,46 @@ int main(int argc, char *argv[]) Info<< " plane " << p << endl; } + Info<<"Testing PtrDynList" << nl; + + PtrDynList 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 436d3465b1..38a013ac13 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 0000000000..c89d4e9f5d --- /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 . + +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 + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declarations + +template class PtrDynList; + +/*---------------------------------------------------------------------------*\ + Class PtrDynList Declaration +\*---------------------------------------------------------------------------*/ + +template +class PtrDynList +: + public PtrList +{ + 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& list); + + //- Move construct + inline PtrDynList(PtrDynList&& 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::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& aptr); + + //- Append an element to the end of the list + inline void append(const tmp& tptr); + + //- 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; + + //- Set element to given pointer and return old element (can be null) + inline autoPtr set(const label i, T* ptr); + + //- Set element to given autoPtr and return old element + inline autoPtr set(const label i, const autoPtr& aptr); + + //- Set element to given tmp and return old element + inline autoPtr set(const label i, const tmp& 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& list); + + //- Copy (clone) assignment + inline void operator=(const PtrDynList& list); + + //- Copy (clone) assignment with different sizing parameters + template + inline void operator=(const PtrDynList& list); + + //- Move assignment + inline void operator=(PtrList&& list); + + //- Move assignment + inline void operator=(PtrDynList&& list); + + //- Move assignment with different sizing parameters + template + inline void operator=(PtrDynList&& 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 0000000000..a1eaf65c37 --- /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 . + +\*---------------------------------------------------------------------------*/ + +#include "autoPtr.H" +#include "tmp.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +inline constexpr Foam::PtrDynList::PtrDynList() noexcept +: + PtrList(), + capacity_(0) +{} + + +template +inline Foam::PtrDynList::PtrDynList(const label len) +: + PtrList(len), + capacity_(len) +{ + PtrList::size(0); +} + + +template +inline Foam::PtrDynList::PtrDynList +( + const PtrDynList& list +) +: + PtrList(list), + capacity_(PtrList::size()) +{} + + +template +inline Foam::PtrDynList::PtrDynList +( + PtrDynList&& list +) +: + PtrList(std::move(list)), + capacity_(list.capacity_) +{ + list.clearStorage(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +inline Foam::label Foam::PtrDynList::capacity() const +{ + return capacity_; +} + + +template +inline void Foam::PtrDynList::setCapacity(const label nElem) +{ + label nextFree = PtrList::size(); + capacity_ = nElem; + + if (nextFree > capacity_) + { + // Truncate addressed sizes too + nextFree = capacity_; + } + + PtrList::resize(capacity_); + (this->ptrs_).setAddressableSize(nextFree); +} + + +template +inline void Foam::PtrDynList::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::size(); + PtrList::resize(capacity_); + (this->ptrs_).setAddressableSize(nextFree); + } +} + + +template +inline void Foam::PtrDynList::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::resize(capacity_); + } + else if (newLen != oldLen) + { + // Truncation frees old pointers + for (label i=newLen; i +inline void Foam::PtrDynList::setSize(const label newLen) +{ + this->resize(newLen); +} + + +template +inline void Foam::PtrDynList::clear() +{ + (this->ptrs_).free(); // free old pointers + (this->ptrs_).setAddressableSize(0); +} + + +template +inline void Foam::PtrDynList::clearStorage() +{ + PtrList::clear(); + capacity_ = 0; +} + + +template +inline Foam::label Foam::PtrDynList::expandStorage() +{ + const label nextFree = PtrList::size(); + + // Allow addressing into the entire list + PtrList::size(capacity_); + + return nextFree; +} + + +template +inline void Foam::PtrDynList::shrink() +{ + label nextFree = PtrList::size(); + if (capacity_ > nextFree) + { + // Use the full list when resizing + PtrList::size(capacity_); + + // The new size + capacity_ = nextFree; + PtrList::resize(capacity_); + PtrList::size(nextFree); + } + return *this; +} + + +template +inline void Foam::PtrDynList::append(T* ptr) +{ + const label idx = this->size(); + resize(idx + 1); + this->ptrs_[idx] = ptr; +} + + +template +inline void Foam::PtrDynList::append(const autoPtr& aptr) +{ + return this->append(const_cast&>(aptr).release()); +} + + +template +inline void Foam::PtrDynList::append(const tmp& tptr) +{ + return this->append(const_cast&>(tptr).ptr()); +} + + +template +inline Foam::autoPtr Foam::PtrDynList::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 old(this->ptrs_[idx]); + this->ptrs_[idx] = nullptr; + (this->ptrs_).setAddressableSize(idx); + + return old; +} + + +template +inline bool Foam::PtrDynList::set(const label i) const +{ + return (i >= 0 && i < PtrList::size()) ? PtrList::set(i) : false; +} + + +template +inline Foam::autoPtr Foam::PtrDynList::set +( + const label i, + T* ptr +) +{ + if (i >= this->size()) + { + resize(i+1); + } + + return autoPtr(UPtrList::set(i, ptr)); +} + + +template +inline Foam::autoPtr Foam::PtrDynList::set +( + const label i, + const autoPtr& aptr +) +{ + this->set(i, const_cast&>(aptr).release()); +} + + +template +inline Foam::autoPtr Foam::PtrDynList::set +( + const label i, + const tmp& tptr +) +{ + this->set(i, tptr.ptr()); +} + + +template +inline void Foam::PtrDynList::reorder(const labelUList& oldToNew) +{ + // Shrinking first is a bit annoying, but saves needing a special version. + shrink(); + PtrList::reorder(oldToNew); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +inline void Foam::PtrDynList::operator= +( + const PtrList& list +) +{ + PtrList::operator=(list); + capacity_ = PtrList::size(); +} + + +template +inline void Foam::PtrDynList::operator= +( + const PtrDynList& list +) +{ + PtrList::operator=(list); + capacity_ = PtrList::size(); +} + + +template +template +inline void Foam::PtrDynList::operator= +( + const PtrDynList& list +) +{ + PtrList::operator=(list); + capacity_ = PtrList::size(); +} + + +template +inline void Foam::PtrDynList::operator= +( + PtrList&& list +) +{ + PtrList::transfer(list); + capacity_ = PtrList::size(); + list.clearStorage(); +} + + +template +inline void Foam::PtrDynList::operator= +( + PtrDynList&& list +) +{ + PtrList::transfer(list); + capacity_ = list.capacity(); + list.clearStorage(); +} + + +template +template +inline void Foam::PtrDynList::operator= +( + PtrDynList&& list +) +{ + PtrList::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 d27a74223d..cad4676c67 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 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // -template -Foam::PtrList::PtrList(const PtrList& list) -: - UPtrList(list.size()) -{ - const label len = this->size(); - - for (label i=0; iptrs_[i] = (list[i]).clone().ptr(); - } -} - - -template -template -Foam::PtrList::PtrList(const PtrList& list, const CloneArg& cloneArg) -: - UPtrList(list.size()) -{ - const label len = this->size(); - - for (label i=0; iptrs_[i] = (list[i]).clone(cloneArg).ptr(); - } -} - - template Foam::PtrList::PtrList(PtrList& list, bool reuse) : @@ -64,6 +36,7 @@ Foam::PtrList::PtrList(PtrList& list, bool reuse) { if (!reuse) { + // This works like an inplace clone method const label len = this->size(); for (label i=0; i::PtrList(const SLPtrList& list) } -// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template Foam::PtrList::~PtrList() { - const label len = this->size(); - - // Free old pointers - for (label i=0; iptrs_[i]) - { - delete this->ptrs_[i]; - } - } + (this->ptrs_).free(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template -void Foam::PtrList::clear() +template +Foam::PtrList Foam::PtrList::clone(Args&&... args) const { const label len = this->size(); + PtrList cloned(len); + for (label i=0; iptrs_[i]) + const T* ptr = this->ptrs_[i]; + + if (ptr) { - delete this->ptrs_[i]; + cloned.ptrs_[i] = ptr->clone(std::forward(args)...).ptr(); } } - UPtrList::clear(); + return cloned; } template void Foam::PtrList::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; iptrs_[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(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 c04d92f7d6..7cdf1367a0 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 autoPtr; template class tmp; template class PtrList; -template Istream& operator>>(Istream& is, PtrList& lst); +template Istream& operator>>(Istream& is, PtrList& list); /*---------------------------------------------------------------------------*\ @@ -68,7 +69,6 @@ class PtrList : public UPtrList { - protected: // Protected Member Functions @@ -77,6 +77,8 @@ protected: template 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& list); + inline PtrList(const PtrList& list); //- Move construct inline PtrList(PtrList&& list); - //- Copy construct with additional argument for 'clone()' + //- Copy construct using 'clone()' method on each element template - PtrList(const PtrList& list, const CloneArg& cloneArg); + inline PtrList(const PtrList& list, const CloneArg& cloneArgs); //- Construct as copy or re-use as specified PtrList(PtrList& list, bool reuse); - //- Construct as copy of SLPtrList + //- Copy construct using 'clone()' on each element of SLPtrList\ explicit PtrList(const SLPtrList& 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 + PtrList clone(Args&&... args) const; - //- Reset size of PtrList. + //- Clear the PtrList. Delete allocated entries and set size to zero. + inline void clear(); + + //- 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::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& aptr); + //- Move append an element to the end of the list + inline void append(autoPtr& aptr); - //- Append an element at the end of the list + //- Move append an element to the end of the list + inline void append(autoPtr&& aptr); + + //- Move or clone append a tmp to the end of the list inline void append(const tmp& 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 set(const label i, T* ptr); + inline autoPtr set(label i, T* ptr); //- Set element to given autoPtr and return old element - inline autoPtr set(const label i, const autoPtr& aptr); + inline autoPtr set(label i, autoPtr& aptr); + + //- Set element to given autoPtr and return old element + inline autoPtr set(label i, autoPtr&& aptr); //- Set element to given tmp and return old element - inline autoPtr set(const label i, const tmp& tptr); + inline autoPtr set(label i, const tmp& 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>> (Istream& is, PtrList& 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 6b51538e96..bb2a19064a 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 +inline void Foam::PtrList::free() +{ + (this->ptrs_).free(); +} + + // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // template @@ -36,9 +45,16 @@ inline constexpr Foam::PtrList::PtrList() noexcept template -inline Foam::PtrList::PtrList(const label nElem) +inline Foam::PtrList::PtrList(const label len) : - UPtrList(nElem) + UPtrList(len) +{} + + +template +inline Foam::PtrList::PtrList(const PtrList& list) +: + UPtrList(list.ptrs_.clone()) {} @@ -49,8 +65,28 @@ inline Foam::PtrList::PtrList(PtrList&& list) {} +template +template +inline Foam::PtrList::PtrList +( + const PtrList& list, + const CloneArg& cloneArg +) +: + UPtrList(list.clone(cloneArg)()) +{} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +inline void Foam::PtrList::clear() +{ + (this->ptrs_).free(); + UPtrList::clear(); +} + + template inline void Foam::PtrList::setSize(const label newLen) { @@ -59,16 +95,30 @@ inline void Foam::PtrList::setSize(const label newLen) template -inline void Foam::PtrList::append(const autoPtr& aptr) +inline void Foam::PtrList::append(T* ptr) { - return UPtrList::append(const_cast&>(aptr).ptr()); + UPtrList::append(ptr); +} + + +template +inline void Foam::PtrList::append(autoPtr& aptr) +{ + return UPtrList::append(aptr.release()); +} + + +template +inline void Foam::PtrList::append(autoPtr&& aptr) +{ + return UPtrList::append(aptr.release()); } template inline void Foam::PtrList::append(const tmp& tptr) { - return UPtrList::append(const_cast&>(tptr).ptr()); + return UPtrList::append(tptr.ptr()); } @@ -80,38 +130,37 @@ inline bool Foam::PtrList::set(const label i) const template -inline Foam::autoPtr Foam::PtrList::set(const label i, T* ptr) +inline Foam::autoPtr Foam::PtrList::set(label i, T* ptr) { return autoPtr(UPtrList::set(i, ptr)); } template -inline Foam::autoPtr Foam::PtrList::set -( - const label i, - const autoPtr& aptr -) +inline Foam::autoPtr Foam::PtrList::set(label i, autoPtr& aptr) { - return set(i, const_cast&>(aptr).ptr()); + return set(i, aptr.release()); } template -inline Foam::autoPtr Foam::PtrList::set -( - const label i, - const tmp& tptr -) +inline Foam::autoPtr Foam::PtrList::set(label i, autoPtr&& aptr) { - return set(i, const_cast&>(tptr).ptr()); + return set(i, aptr.release()); +} + + +template +inline Foam::autoPtr Foam::PtrList::set(label i, const tmp& tptr) +{ + return set(i, tptr.ptr()); } template inline void Foam::PtrList::transfer(PtrList& list) { - this->clear(); + this->free(); // free old pointers UPtrList::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 141225f776..be3da43435 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 template void Foam::PtrList::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::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::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::read(Istream& is, const INew& inew) << exit(FatalIOError); } - SLList sllPtrs; + SLList slList; token lastToken(is); while @@ -133,15 +136,15 @@ void Foam::PtrList::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::PtrList(Istream& is) // * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * // template -Foam::Istream& Foam::operator>>(Istream& is, PtrList& lst) +Foam::Istream& Foam::operator>>(Istream& is, PtrList& list) { - lst.clear(); - lst.read(is, INew()); - + list.read(is, INew()); 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 0000000000..96d2a9aaf8 --- /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 . + +\*---------------------------------------------------------------------------*/ + +#include "PtrListDetail.H" +#include + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::label Foam::Detail::PtrListDetail::count() const +{ + label ngood = 0; + + for (const T* ptr : *this) + { + if (ptr) + { + ++ngood; + } + } + + return ngood; +} + + +template +void Foam::Detail::PtrListDetail::free() +{ + List& ptrs = *this; + const label len = ptrs.size(); + + for (label i=0; i +template +Foam::Detail::PtrListDetail +Foam::Detail::PtrListDetail::clone(Args&&... args) const +{ + const List& ptrs = *this; + const label len = ptrs.size(); + + PtrListDetail cloned(len); + + for (label i=0; iclone(std::forward(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 0000000000..5405699d03 --- /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 . + +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 PtrListDetail +: + public List +{ +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& list); + + //- Move construct + inline PtrListDetail(PtrListDetail&& list); + + //- Copy or move (reuse) construct as specified + inline PtrListDetail(PtrListDetail& 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 + PtrListDetail 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& list); + + //- Move assignment + inline void operator=(PtrListDetail&& 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 0000000000..9e0026e87f --- /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 . + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // + +template +inline constexpr Foam::Detail::PtrListDetail::PtrListDetail() noexcept +: + List() +{} + + +template +inline Foam::Detail::PtrListDetail::PtrListDetail(const label len) +: + List(len, reinterpret_cast(0)) +{} + + +template +inline Foam::Detail::PtrListDetail::PtrListDetail +( + const PtrListDetail& list +) +: + List(list) +{} + + +template +inline Foam::Detail::PtrListDetail::PtrListDetail +( + PtrListDetail&& list +) +: + List(std::move(list)) +{} + + +template +inline Foam::Detail::PtrListDetail::PtrListDetail +( + PtrListDetail& list, + bool reuse +) +: + List(list, reuse) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +inline void Foam::Detail::PtrListDetail::setAddressableSize(const label n) +{ + List::size(n); +} + + +template +inline void Foam::Detail::PtrListDetail::resize(const label newLen) +{ + if (newLen <= 0) + { + List::clear(); + } + else if (newLen != List::size()) + { + // Truncate or extend. Any new elements are initialized to nullptr. + List::resize(newLen, reinterpret_cast(0)); + } +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +inline void Foam::Detail::PtrListDetail::operator= +( + const PtrListDetail& list +) +{ + List::operator=(list); // shallow copy +} + + +template +inline void Foam::Detail::PtrListDetail::operator= +( + PtrListDetail&& list +) +{ + List::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 bbc9f60282..37d5f65a70 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 -Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList& lst) +Foam::Ostream& Foam::Detail::PtrListDetail::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 317cf817d7..ca77270205 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 -Foam::UPtrList::UPtrList(UList& lst) +Foam::UPtrList::UPtrList(PtrList& list) : - ptrs_(lst.size()) -{ - const label len = lst.size(); - - for (label i=0; i::reorder(const labelUList& oldToNew) << abort(FatalError); } - // New list of pointers - List ptrLst(len, reinterpret_cast(0)); + Detail::PtrListDetail newList(len); for (label i=0; i::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::reorder(const labelUList& oldToNew) } } - ptrs_.swap(ptrLst); + ptrs_.transfer(newList); +} + + +// * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * // + +template +Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList& 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 ae2061d4fb..212adf26e4 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 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -68,9 +72,16 @@ class UPtrList { protected: - // Protected data + // Protected Member Data - List ptrs_; + //- The list of pointers + Detail::PtrListDetail ptrs_; + + + // Constructors + + //- Low-level move construct + inline UPtrList(Detail::PtrListDetail&& 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& list); - - //- Construct from UList, taking addresses of each list element - explicit UPtrList(UList& list); - - //- Construct as copy or re-use as specified - inline UPtrList(UPtrList& list, bool reuse); - - //- Copy construct - inline UPtrList(const UPtrList& list) = default; + //- Copy construct (shallow copies addresses) + inline UPtrList(const UPtrList& list); //- Move construct inline UPtrList(UPtrList&& list); + //- Construct as shallow copy or re-use as specified + inline UPtrList(UPtrList& list, bool reuse); + + //- 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& 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& 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& 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& operator=(const UPtrList& list) = default; + //- Copy assignment (shallow copies addresses) + inline void operator=(const UPtrList& list); //- Move assignment inline void operator=(UPtrList&& 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<< (Ostream& os, const UPtrList& list); + friend Ostream& operator<< + ( + Ostream& os, + const UPtrList& 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 be76d3ea34..a93b00df71 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::UPtrList() noexcept template inline Foam::UPtrList::UPtrList(const label len) : - ptrs_(len, reinterpret_cast(0)) + ptrs_(len) {} template -inline Foam::UPtrList::UPtrList(PtrList& list) +inline Foam::UPtrList::UPtrList(Detail::PtrListDetail&& ptrs) +: + ptrs_(std::move(ptrs)) +{} + + +template +inline Foam::UPtrList::UPtrList(const UPtrList& list) : ptrs_(list.ptrs_) {} @@ -60,6 +67,20 @@ inline Foam::UPtrList::UPtrList(UPtrList& list, bool reuse) {} +template +inline Foam::UPtrList::UPtrList(UList& list) +: + ptrs_(list.size()) +{ + const label len = ptrs_.size(); + + for (label i=0; i @@ -128,25 +149,14 @@ inline const T& Foam::UPtrList::last() const template inline void Foam::UPtrList::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(0)); - } + ptrs_.resize(newLen); } template inline void Foam::UPtrList::setSize(const label newLen) { - this->resize(newLen); + ptrs_.resize(newLen); } @@ -180,30 +190,34 @@ inline T* Foam::UPtrList::set(const label i, T* ptr) template inline const T& Foam::UPtrList::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 inline T& Foam::UPtrList::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::operator()(const label i) const } -// * * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * iterator * * * * * * * * * * * * * * * * // template inline Foam::UPtrList::iterator::iterator(T** ptr) @@ -237,6 +251,13 @@ inline bool Foam::UPtrList::iterator::operator!=(const iterator& iter) const } +template +inline T* Foam::UPtrList::iterator::operator->() const +{ + return *ptr_; +} + + template inline T& Foam::UPtrList::iterator::operator*() const { @@ -366,7 +387,7 @@ inline bool Foam::UPtrList::iterator::operator>=(const iterator& iter) const } -// * * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * const_iterator * * * * * * * * * * * * * * // template inline Foam::UPtrList::const_iterator::const_iterator(const T* const* ptr) @@ -402,6 +423,13 @@ inline bool Foam::UPtrList::const_iterator::operator!= } +template +inline const T* Foam::UPtrList::const_iterator::operator->() const +{ + return *ptr_; +} + + template inline const T& Foam::UPtrList::const_iterator::operator*() const { @@ -596,10 +624,17 @@ Foam::UPtrList::end() const // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // +template +inline void Foam::UPtrList::operator=(const UPtrList& list) +{ + ptrs_ = list.ptrs_; // shallow copy +} + + template inline void Foam::UPtrList::operator=(UPtrList&& list) { - this->transfer(list); + ptrs_.transfer(list.ptrs_); }