diff --git a/applications/test/PtrList/Test-PtrList.C b/applications/test/PtrList/Test-PtrList.C index a8cf8686af..d35e321d71 100644 --- a/applications/test/PtrList/Test-PtrList.C +++ b/applications/test/PtrList/Test-PtrList.C @@ -403,7 +403,7 @@ int main(int argc, char *argv[]) << "list2: " << list2 << endl; Info<< "indirectly delete some items via setSize :" << endl; - list1.setSize(4); + list1.resize(4); Info<< "list1: " << list1 << endl; @@ -446,8 +446,48 @@ int main(int argc, char *argv[]) << "addresses:" << nl; printAddr(Info, list1b); printAddr(Info, list1c); + + + PtrDynList dynlist1d; + PtrDynList dynlist1b(list1b.clone()); + PtrDynList dynlist1c(list1b.clone()); + + Info<< "append:" << nl; + Info<< "in: " << dynlist1b << nl + << "in: " << dynlist1c << nl + << "addresses:" << nl; + printAddr(Info, dynlist1b); + printAddr(Info, dynlist1c); + + dynlist1d.append(std::move(dynlist1b)); + dynlist1d.append(std::move(dynlist1c)); + + Info<< "result:" << nl; + print(Info, dynlist1d); + + Info<< "addresses:" << nl; + printAddr(Info, dynlist1d); + + PtrList list1d; + + Info<< "append:" << nl; + Info<< "in: " << list1b << nl + << "in: " << list1c << nl + << "addresses:" << nl; + printAddr(Info, list1b); + printAddr(Info, list1c); + + list1d.append(std::move(list1b)); + list1d.append(std::move(list1c)); + + Info<< "result:" << nl; + print(Info, list1d); + + Info<< "addresses:" << nl; + printAddr(Info, list1d); } + PtrList list3(std::move(list1)); Info<< "Move constructed" << endl; @@ -473,6 +513,8 @@ int main(int argc, char *argv[]) Info<< "UPtrList from PtrList" << nl; UPtrList ulist1(list3); + UPtrList ulist1b(list3); + UPtrList ulist1c(list3); Info<< "ulist1: " << ulist1 << nl; Info<< "PtrList addresses:"; @@ -481,6 +523,12 @@ int main(int argc, char *argv[]) printAddr(Info, ulist1); Info<< nl; + ulist1c.append(std::move(ulist1b)); + + Info<< "UPtrList append/append:"; + printAddr(Info, ulist1c); + Info<< nl; + { Info<< "UPtrList(const UPtrList&)" << nl; diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H index 5311f33333..955766be26 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H @@ -87,6 +87,9 @@ public: //- Move construct inline PtrDynList(PtrDynList&& list); + //- Move construct from PtrList + inline PtrDynList(PtrList&& list); + //- Take ownership of pointers in the list, set old pointers to null. inline explicit PtrDynList(UList& list); diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H index cfb7f06d13..e5fc02a675 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H @@ -73,6 +73,17 @@ inline Foam::PtrDynList::PtrDynList } +template +inline Foam::PtrDynList::PtrDynList +( + PtrList&& list +) +: + PtrList(std::move(list)), + capacity_(PtrList::size()) +{} + + template inline Foam::PtrDynList::PtrDynList(UList& list) : @@ -195,8 +206,11 @@ inline void Foam::PtrDynList::swap PtrDynList& other ) { - // Cannot compare 'this' for different types, so use cdata() - if (this->cdata() == other.cdata()) + if + ( + static_cast*>(this) + == static_cast*>(&other) + ) { return; // Self-swap is a no-op } @@ -269,9 +283,9 @@ inline void Foam::PtrDynList::append(PtrList&& other) resize(idx + len); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { - set(idx + i, other.release(i)); // moves pointer + set(idx + i, other.release(i)); // Take pointer ownership } other.clear(); @@ -285,14 +299,25 @@ inline void Foam::PtrDynList::append PtrDynList&& other ) { + if + ( + static_cast*>(this) + == static_cast*>(&other) + ) + { + FatalErrorInFunction + << "Attempted append to self" + << abort(FatalError); + } + const label idx = this->size(); const label len = other.size(); resize(idx + len); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { - set(idx + i, other.release(i)); // moves pointer + set(idx + i, other.release(i)); // Take pointer ownership } other.clearStorage(); // Ensure capacity=0 @@ -451,8 +476,11 @@ inline void Foam::PtrDynList::operator= const PtrDynList& list ) { - // Cannot compare 'this' for different types, so use cdata() - if (this->cdata() == list.cdata()) + if + ( + static_cast*>(this) + == static_cast*>(&list) + ) { return; // Self-assignment is a no-op } @@ -503,8 +531,11 @@ inline void Foam::PtrDynList::operator= PtrDynList&& list ) { - // Cannot compare 'this' for different types, so use cdata() - if (this->cdata() == list.cdata()) + if + ( + static_cast*>(this) + == static_cast*>(&list) + ) { return; // Self-assignment is a no-op } diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H index a1814440b3..ec59fb7a2b 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2020 OpenCFD Ltd. + Copyright (C) 2018-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -173,6 +173,9 @@ public: //- Move or clone append a tmp to the end of the list inline void append(const tmp& ptr); + //- Move append another list to the end of this list. + inline void append(PtrList&& other); + //- Construct and set an element template inline autoPtr emplace(const label i, Args&&... args); diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H index 452bd85d2a..ce80607dc5 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H @@ -151,6 +151,30 @@ inline void Foam::PtrList::append(const tmp& ptr) } +template +inline void Foam::PtrList::append(PtrList&& other) +{ + if (this == &other) + { + FatalErrorInFunction + << "Attempted append to self" + << abort(FatalError); + } + + const label idx = this->size(); + const label len = other.size(); + + resize(idx + len); + + for (label i = 0; i < len; ++i) + { + set(idx + i, other.release(i)); // Take pointer ownership + } + + other.clear(); +} + + template template inline Foam::autoPtr Foam::PtrList::emplace diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H index 4f88822e98..6caee41a85 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H @@ -268,6 +268,9 @@ public: //- Append an element to the end of the list inline void append(T* ptr); + //- Move append another list to the end of this list. + inline void append(UPtrList&& other); + //- Swap content inline void swap(UPtrList& list); diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H index 1716ddf253..b96f1371e9 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrListI.H @@ -93,7 +93,7 @@ inline Foam::UPtrList::UPtrList(UList& list) { const label len = ptrs_.size(); - for (label i=0; i::resize(const label newLen) template inline void Foam::UPtrList::append(T* ptr) { - const label idx = this->size(); - ptrs_.resize(idx + 1); - ptrs_[idx] = ptr; + ptrs_.append(ptr); +} + + +template +inline void Foam::UPtrList::append(UPtrList&& other) +{ + ptrs_.append(other.ptrs_); + other.ptrs_.clear(); }