ENH: support move append lists for PtrList and UPtrList

This commit is contained in:
Mark Olesen
2022-05-17 10:13:46 +02:00
parent 60e07d1f93
commit 87f3866f20
7 changed files with 134 additions and 16 deletions

View File

@ -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<Scalar> dynlist1d;
PtrDynList<Scalar, 5> dynlist1b(list1b.clone());
PtrDynList<Scalar, 8> 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<Scalar> 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<Scalar> list3(std::move(list1));
Info<< "Move constructed" << endl;
@ -473,6 +513,8 @@ int main(int argc, char *argv[])
Info<< "UPtrList from PtrList" << nl;
UPtrList<Scalar> ulist1(list3);
UPtrList<Scalar> ulist1b(list3);
UPtrList<Scalar> 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;

View File

@ -87,6 +87,9 @@ public:
//- Move construct
inline PtrDynList(PtrDynList<T, SizeMin>&& list);
//- Move construct from PtrList
inline PtrDynList(PtrList<T>&& list);
//- Take ownership of pointers in the list, set old pointers to null.
inline explicit PtrDynList(UList<T*>& list);

View File

@ -73,6 +73,17 @@ inline Foam::PtrDynList<T, SizeMin>::PtrDynList
}
template<class T, int SizeMin>
inline Foam::PtrDynList<T, SizeMin>::PtrDynList
(
PtrList<T>&& list
)
:
PtrList<T>(std::move(list)),
capacity_(PtrList<T>::size())
{}
template<class T, int SizeMin>
inline Foam::PtrDynList<T, SizeMin>::PtrDynList(UList<T*>& list)
:
@ -195,8 +206,11 @@ inline void Foam::PtrDynList<T, SizeMin>::swap
PtrDynList<T, AnySizeMin>& other
)
{
// Cannot compare 'this' for different types, so use cdata()
if (this->cdata() == other.cdata())
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other)
)
{
return; // Self-swap is a no-op
}
@ -271,7 +285,7 @@ inline void Foam::PtrDynList<T, SizeMin>::append(PtrList<T>&& other)
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,6 +299,17 @@ inline void Foam::PtrDynList<T, SizeMin>::append
PtrDynList<T, AnySizeMin>&& other
)
{
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other)
)
{
FatalErrorInFunction
<< "Attempted append to self"
<< abort(FatalError);
}
const label idx = this->size();
const label len = other.size();
@ -292,7 +317,7 @@ inline void Foam::PtrDynList<T, SizeMin>::append
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<T, SizeMin>::operator=
const PtrDynList<T, AnySizeMin>& list
)
{
// Cannot compare 'this' for different types, so use cdata()
if (this->cdata() == list.cdata())
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&list)
)
{
return; // Self-assignment is a no-op
}
@ -503,8 +531,11 @@ inline void Foam::PtrDynList<T, SizeMin>::operator=
PtrDynList<T, AnySizeMin>&& list
)
{
// Cannot compare 'this' for different types, so use cdata()
if (this->cdata() == list.cdata())
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&list)
)
{
return; // Self-assignment is a no-op
}

View File

@ -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<T>& ptr);
//- Move append another list to the end of this list.
inline void append(PtrList<T>&& other);
//- Construct and set an element
template<class... Args>
inline autoPtr<T> emplace(const label i, Args&&... args);

View File

@ -151,6 +151,30 @@ inline void Foam::PtrList<T>::append(const tmp<T>& ptr)
}
template<class T>
inline void Foam::PtrList<T>::append(PtrList<T>&& 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<class T>
template<class... Args>
inline Foam::autoPtr<T> Foam::PtrList<T>::emplace

View File

@ -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<T>&& other);
//- Swap content
inline void swap(UPtrList<T>& list);

View File

@ -196,9 +196,15 @@ inline void Foam::UPtrList<T>::resize(const label newLen)
template<class T>
inline void Foam::UPtrList<T>::append(T* ptr)
{
const label idx = this->size();
ptrs_.resize(idx + 1);
ptrs_[idx] = ptr;
ptrs_.append(ptr);
}
template<class T>
inline void Foam::UPtrList<T>::append(UPtrList<T>&& other)
{
ptrs_.append(other.ptrs_);
other.ptrs_.clear();
}