mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: relocate Foam::sort from PtrListOps to UPtrList.H
- can sort directly without ListOps or other intermediates (eg labelList order). - PtrListOps::less/greater wrappers -> UPtrList::less/greater
This commit is contained in:
@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
~Scalar()
|
~Scalar()
|
||||||
{
|
{
|
||||||
Info<<"delete Scalar: " << data_ << endl;
|
Info<< "delete Scalar: " << data_ << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scalar& value() const
|
const scalar& value() const
|
||||||
@ -324,7 +324,7 @@ int main(int argc, char *argv[])
|
|||||||
list1.set(i, new Scalar(1.3*i));
|
list1.set(i, new Scalar(1.3*i));
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<<"Emplace set " << list2.size() << " values" << nl;
|
Info<< "Emplace set " << list2.size() << " values" << nl;
|
||||||
forAll(list2, i)
|
forAll(list2, i)
|
||||||
{
|
{
|
||||||
list2.emplace(i, (10 + 1.3*i));
|
list2.emplace(i, (10 + 1.3*i));
|
||||||
@ -338,9 +338,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
Info<< nl
|
Info<< nl
|
||||||
<<"list1: " << list1 << nl
|
<< "list1: " << list1 << nl
|
||||||
<<"list2: " << list2 << nl
|
<< "list2: " << list2 << nl
|
||||||
<<"list-appended: " << listApp << endl;
|
<< "list-appended: " << listApp << endl;
|
||||||
|
|
||||||
|
|
||||||
// Release values
|
// Release values
|
||||||
@ -357,27 +357,27 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<<"Released pointers from";
|
Info<< "Released pointers from";
|
||||||
print(Info, listApp) << nl;
|
print(Info, listApp) << nl;
|
||||||
|
|
||||||
Info<<"Into plain list of pointers";
|
Info<< "Into plain list of pointers";
|
||||||
print(Info, ptrs) << nl;
|
print(Info, ptrs) << nl;
|
||||||
|
|
||||||
PtrDynList<Scalar> newlist1(ptrs);
|
PtrDynList<Scalar> newlist1(ptrs);
|
||||||
|
|
||||||
Info<<"Constructed from plain list of pointers";
|
Info<< "Constructed from plain list of pointers";
|
||||||
print(Info, ptrs) << nl;
|
print(Info, ptrs) << nl;
|
||||||
print(Info, newlist1) << nl;
|
print(Info, newlist1) << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Info<<"indirectly delete some items via set(.., nullptr) :" << endl;
|
Info<< "indirectly delete some items via set(.., nullptr) :" << endl;
|
||||||
for (label i = 2; i < 5; i++)
|
for (label i = 2; i < 5; i++)
|
||||||
{
|
{
|
||||||
list1.set(i, nullptr);
|
list1.set(i, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<<"release some items:" << endl;
|
Info<< "release some items:" << endl;
|
||||||
|
|
||||||
for (label i = -2; i < 5; i++)
|
for (label i = -2; i < 5; i++)
|
||||||
{
|
{
|
||||||
@ -389,31 +389,31 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<<"list1: ";
|
Info<< "list1: ";
|
||||||
print(Info, list1) << nl;
|
print(Info, list1) << nl;
|
||||||
|
|
||||||
list1.resize(list1.squeezeNull());
|
list1.resize(list1.squeezeNull());
|
||||||
Info<<"squeezed null: ";
|
Info<< "squeezed null: ";
|
||||||
print(Info, list1) << nl;
|
print(Info, list1) << nl;
|
||||||
|
|
||||||
Info<<"transfer list2 -> list1:" << endl;
|
Info<< "transfer list2 -> list1:" << endl;
|
||||||
list1.transfer(list2);
|
list1.transfer(list2);
|
||||||
|
|
||||||
Info<<"list1: " << list1 << nl
|
Info<< "list1: " << list1 << nl
|
||||||
<<"list2: " << list2 << endl;
|
<< "list2: " << list2 << endl;
|
||||||
|
|
||||||
Info<<"indirectly delete some items via setSize :" << endl;
|
Info<< "indirectly delete some items via setSize :" << endl;
|
||||||
list1.setSize(4);
|
list1.setSize(4);
|
||||||
|
|
||||||
Info<<"list1: " << list1 << endl;
|
Info<< "list1: " << list1 << endl;
|
||||||
|
|
||||||
{
|
{
|
||||||
PtrList<Scalar> list1a(list1, false);
|
PtrList<Scalar> list1a(list1, false);
|
||||||
|
|
||||||
Info<<"Clone constructed" << endl;
|
Info<< "Clone constructed" << endl;
|
||||||
Info<<"in: " << list1 << nl
|
Info<< "in: " << list1 << nl
|
||||||
<<"out: " << list1a << nl
|
<< "out: " << list1a << nl
|
||||||
<<"addresses:" << nl;
|
<< "addresses:" << nl;
|
||||||
printAddr(Info, list1);
|
printAddr(Info, list1);
|
||||||
printAddr(Info, list1a);
|
printAddr(Info, list1a);
|
||||||
Info<<"values:" << nl;
|
Info<<"values:" << nl;
|
||||||
@ -423,112 +423,112 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
auto* ptr = &(list1a.first());
|
auto* ptr = &(list1a.first());
|
||||||
list1a.set(0, ptr);
|
list1a.set(0, ptr);
|
||||||
Info<<"values:" << nl;
|
Info<< "values:" << nl;
|
||||||
print(Info, list1a);
|
print(Info, list1a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PtrList<Scalar> list1b(list1a, true);
|
PtrList<Scalar> list1b(list1a, true);
|
||||||
|
|
||||||
Info<<"Reuse constructed" << endl;
|
Info<< "Reuse constructed" << endl;
|
||||||
Info<<"in: " << list1a << nl
|
Info<< "in: " << list1a << nl
|
||||||
<<"out: " << list1b << nl
|
<< "out: " << list1b << nl
|
||||||
<<"addresses:" << nl;
|
<< "addresses:" << nl;
|
||||||
printAddr(Info, list1a);
|
printAddr(Info, list1a);
|
||||||
printAddr(Info, list1b);
|
printAddr(Info, list1b);
|
||||||
|
|
||||||
|
|
||||||
PtrList<Scalar> list1c(list1b.clone());
|
PtrList<Scalar> list1c(list1b.clone());
|
||||||
|
|
||||||
Info<<"Explicit clone()" << endl;
|
Info<< "Explicit clone()" << endl;
|
||||||
Info<<"in: " << list1b << nl
|
Info<< "in: " << list1b << nl
|
||||||
<<"out: " << list1c << nl
|
<< "out: " << list1c << nl
|
||||||
<<"addresses:" << nl;
|
<< "addresses:" << nl;
|
||||||
printAddr(Info, list1b);
|
printAddr(Info, list1b);
|
||||||
printAddr(Info, list1c);
|
printAddr(Info, list1c);
|
||||||
}
|
}
|
||||||
|
|
||||||
PtrList<Scalar> list3(std::move(list1));
|
PtrList<Scalar> list3(std::move(list1));
|
||||||
Info<<"Move constructed" << endl;
|
Info<< "Move constructed" << endl;
|
||||||
|
|
||||||
Info<<"list1: " << list1 << nl
|
Info<< "list1: " << list1 << nl
|
||||||
<<"list2: " << list2 << nl
|
<< "list2: " << list2 << nl
|
||||||
<<"list3: " << list3 << endl;
|
<< "list3: " << list3 << endl;
|
||||||
|
|
||||||
|
|
||||||
Info<<"Move construct:" << endl;
|
Info<< "Move construct:" << endl;
|
||||||
|
|
||||||
PtrList<Scalar> list4(std::move(list3));
|
PtrList<Scalar> list4(std::move(list3));
|
||||||
|
|
||||||
Info<<"list3: " << list3 << nl
|
Info<< "list3: " << list3 << nl
|
||||||
<<"list4: " << list4 << endl;
|
<< "list4: " << list4 << endl;
|
||||||
|
|
||||||
Info<<"Move assign:" << endl;
|
Info<< "Move assign:" << endl;
|
||||||
list3 = std::move(list4);
|
list3 = std::move(list4);
|
||||||
|
|
||||||
Info<<"list3: " << list3 << nl
|
Info<< "list3: " << list3 << nl
|
||||||
<<"list4: " << list4 << endl;
|
<< "list4: " << list4 << endl;
|
||||||
|
|
||||||
|
|
||||||
Info<<"UPtrList from PtrList" << nl;
|
Info<< "UPtrList from PtrList" << nl;
|
||||||
|
|
||||||
UPtrList<Scalar> ulist1(list3);
|
UPtrList<Scalar> ulist1(list3);
|
||||||
|
|
||||||
Info<<"ulist1: " << ulist1 << nl;
|
Info<< "ulist1: " << ulist1 << nl;
|
||||||
Info<<"PtrList addresses:";
|
Info<< "PtrList addresses:";
|
||||||
printAddr(Info, list3);
|
printAddr(Info, list3);
|
||||||
Info<<"UPtrList addresses:";
|
Info<< "UPtrList addresses:";
|
||||||
printAddr(Info, ulist1);
|
printAddr(Info, ulist1);
|
||||||
Info<< nl;
|
Info<< nl;
|
||||||
|
|
||||||
{
|
{
|
||||||
Info<<"UPtrList(const UPtrList&)" << nl;
|
Info<< "UPtrList(const UPtrList&)" << nl;
|
||||||
|
|
||||||
const UPtrList<Scalar>& cref = ulist1;
|
const UPtrList<Scalar>& cref = ulist1;
|
||||||
|
|
||||||
UPtrList<Scalar> ulist1cp(cref);
|
UPtrList<Scalar> ulist1cp(cref);
|
||||||
|
|
||||||
Info<<"src addresses:";
|
Info<< "src addresses:";
|
||||||
printAddr(Info, cref);
|
printAddr(Info, cref);
|
||||||
Info<<"dst addresses:";
|
Info<< "dst addresses:";
|
||||||
printAddr(Info, ulist1cp);
|
printAddr(Info, ulist1cp);
|
||||||
Info<< nl;
|
Info<< nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Info<<"Move construct:" << endl;
|
Info<< "Move construct:" << endl;
|
||||||
|
|
||||||
UPtrList<Scalar> ulist2(std::move(ulist1));
|
UPtrList<Scalar> ulist2(std::move(ulist1));
|
||||||
|
|
||||||
Info<<"ulist1: " << ulist1 << nl
|
Info<< "ulist1: " << ulist1 << nl
|
||||||
<<"ulist2: " << ulist2 << nl;
|
<< "ulist2: " << ulist2 << nl;
|
||||||
|
|
||||||
Info<<"Copy assign:" << endl;
|
Info<< "Copy assign:" << endl;
|
||||||
ulist1 = ulist2;
|
ulist1 = ulist2;
|
||||||
|
|
||||||
Info<<"ulist1: " << ulist1 << nl
|
Info<< "ulist1: " << ulist1 << nl
|
||||||
<<"ulist2: " << ulist2 << nl;
|
<< "ulist2: " << ulist2 << nl;
|
||||||
|
|
||||||
Info<<"Move assign:" << endl;
|
Info<< "Move assign:" << endl;
|
||||||
ulist1 = std::move(ulist2);
|
ulist1 = std::move(ulist2);
|
||||||
|
|
||||||
Info<<"ulist1: " << ulist1 << nl
|
Info<< "ulist1: " << ulist1 << nl
|
||||||
<<"ulist2: " << ulist2 << nl;
|
<< "ulist2: " << ulist2 << nl;
|
||||||
|
|
||||||
// Test iterator random access
|
// Test iterator random access
|
||||||
{
|
{
|
||||||
auto iter1 = ulist1.begin();
|
auto iter1 = ulist1.begin();
|
||||||
auto iter2 = iter1 + 3;
|
auto iter2 = iter1 + 3;
|
||||||
|
|
||||||
Info<<"begin:" << *iter1 << " (+3):" << *iter2 << nl;
|
Info<< "begin:" << *iter1 << " (+3):" << *iter2 << nl;
|
||||||
Info<< "diff= " << (iter1 - iter2) << nl;
|
Info<< "diff= " << (iter1 - iter2) << nl;
|
||||||
Info<< "iter[2]=" << iter1[2] << nl;
|
Info<< "iter[2]=" << iter1[2] << nl;
|
||||||
Info<< "iter1 < iter2 : " << (iter1 < iter2) << nl;
|
Info<< "iter1 < iter2 : " << (iter1 < iter2) << 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;
|
Info<< "*" << (*iter1).value() << nl;
|
||||||
Info<<"()" << iter1().value() << nl;
|
Info<< "()" << iter1().value() << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
PtrList<plane> planes;
|
PtrList<plane> planes;
|
||||||
@ -541,7 +541,7 @@ int main(int argc, char *argv[])
|
|||||||
Info<< " plane " << p << endl;
|
Info<< " plane " << p << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<<"Testing PtrDynList" << nl;
|
Info<< "Testing PtrDynList" << nl;
|
||||||
|
|
||||||
PtrDynList<plane> dynPlanes;
|
PtrDynList<plane> dynPlanes;
|
||||||
|
|
||||||
@ -566,10 +566,10 @@ int main(int argc, char *argv[])
|
|||||||
report(Info, dynPlanes, true);
|
report(Info, dynPlanes, true);
|
||||||
|
|
||||||
dynPlanes.clear();
|
dynPlanes.clear();
|
||||||
Info<<"clear()" << nl;
|
Info<< "clear()" << nl;
|
||||||
report(Info, dynPlanes);
|
report(Info, dynPlanes);
|
||||||
|
|
||||||
Info<<"now append again" << endl;
|
Info<< "now append again" << endl;
|
||||||
{
|
{
|
||||||
dynPlanes.append(new plane(vector::one, vector::one));
|
dynPlanes.append(new plane(vector::one, vector::one));
|
||||||
dynPlanes.append(new plane(vector(1,2,3), vector::one));
|
dynPlanes.append(new plane(vector(1,2,3), vector::one));
|
||||||
@ -597,13 +597,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
stdPlanes.resize(stdPlanes.squeezeNull());
|
stdPlanes.resize(stdPlanes.squeezeNull());
|
||||||
|
|
||||||
Info<<"After pruning nullptr entries" << endl;
|
Info<< "After pruning nullptr entries" << endl;
|
||||||
printAddr(Info, stdPlanes);
|
printAddr(Info, stdPlanes);
|
||||||
}
|
}
|
||||||
|
|
||||||
dynPlanes.resize(dynPlanes.squeezeNull());
|
dynPlanes.resize(dynPlanes.squeezeNull());
|
||||||
|
|
||||||
Info<<"After pruning nullptr entries" << endl;
|
Info<< "After pruning nullptr entries" << endl;
|
||||||
report(Info, dynPlanes, true);
|
report(Info, dynPlanes, true);
|
||||||
|
|
||||||
|
|
||||||
@ -621,25 +621,48 @@ int main(int argc, char *argv[])
|
|||||||
sortedOrder(dynPlanes2, order);
|
sortedOrder(dynPlanes2, order);
|
||||||
Info<< "sorted order: " << flatOutput(order) << nl;
|
Info<< "sorted order: " << flatOutput(order) << nl;
|
||||||
|
|
||||||
sortedOrder(dynPlanes2, order, PtrListOps::greater<plane>(dynPlanes2));
|
sortedOrder(dynPlanes2, order, UPtrList<plane>::greater(dynPlanes2));
|
||||||
Info<< "sorted order: " << flatOutput(order) << nl;
|
Info<< "sorted order: " << flatOutput(order) << nl;
|
||||||
|
|
||||||
|
// Shuffle
|
||||||
|
shuffle(dynPlanes2);
|
||||||
|
Info<< "Shuffled" << endl;
|
||||||
|
report(Info, dynPlanes2, false);
|
||||||
|
|
||||||
|
// Reverse sort
|
||||||
|
sort
|
||||||
|
(
|
||||||
|
dynPlanes2,
|
||||||
|
[](const plane& a, const plane& b) { return (b < a); }
|
||||||
|
);
|
||||||
|
Info<< "Reverse sorted" << endl;
|
||||||
|
report(Info, dynPlanes2, false);
|
||||||
|
|
||||||
|
// Forward sort
|
||||||
sort(dynPlanes2);
|
sort(dynPlanes2);
|
||||||
|
Info<< "Sorted" << endl;
|
||||||
|
report(Info, dynPlanes2, false);
|
||||||
|
|
||||||
|
// Reverse pointer list - not yet available or needed!
|
||||||
|
/// reverse(dynPlanes2);
|
||||||
|
/// Info<< "Reversed" << endl;
|
||||||
|
/// report(Info, dynPlanes2, false);
|
||||||
|
|
||||||
// dynPlanes2.squeezeNull();
|
// dynPlanes2.squeezeNull();
|
||||||
|
|
||||||
Info<<"Append" << endl;
|
Info<< "Append" << endl;
|
||||||
report(Info, dynPlanes2, false);
|
report(Info, dynPlanes2, false);
|
||||||
|
|
||||||
dynPlanes.append(std::move(dynPlanes2));
|
dynPlanes.append(std::move(dynPlanes2));
|
||||||
|
|
||||||
Info<<"Result" << endl;
|
Info<< "Result" << endl;
|
||||||
report(Info, dynPlanes, false);
|
report(Info, dynPlanes, false);
|
||||||
|
|
||||||
Info<<"From" << endl;
|
Info<< "From" << endl;
|
||||||
report(Info, dynPlanes2, false);
|
report(Info, dynPlanes2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<<"free()" << endl;
|
Info<< "free()" << endl;
|
||||||
|
|
||||||
dynPlanes.free();
|
dynPlanes.free();
|
||||||
report(Info, dynPlanes, true);
|
report(Info, dynPlanes, true);
|
||||||
|
|||||||
@ -50,6 +50,9 @@ Foam::label Foam::Detail::PtrListDetail<T>::count() const
|
|||||||
template<class T>
|
template<class T>
|
||||||
Foam::label Foam::Detail::PtrListDetail<T>::findNull() const
|
Foam::label Foam::Detail::PtrListDetail<T>::findNull() const
|
||||||
{
|
{
|
||||||
|
// Same as List<T*>::find(nullptr);
|
||||||
|
// except perhaps without pointer ambiguities...
|
||||||
|
|
||||||
label idx = 0;
|
label idx = 0;
|
||||||
|
|
||||||
for (const T* ptr : *this)
|
for (const T* ptr : *this)
|
||||||
|
|||||||
@ -42,8 +42,8 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef PtrListDetail_H
|
#ifndef Foam_PtrListDetail_H
|
||||||
#define PtrListDetail_H
|
#define Foam_PtrListDetail_H
|
||||||
|
|
||||||
#include "List.H"
|
#include "List.H"
|
||||||
|
|
||||||
@ -92,9 +92,12 @@ public:
|
|||||||
//- Return the count of non-nullptr entries
|
//- Return the count of non-nullptr entries
|
||||||
label count() const;
|
label count() const;
|
||||||
|
|
||||||
//- Locate the first null entry, -1 if there are not any
|
//- Locate the first null entry, -1 if there are none (or empty list)
|
||||||
label findNull() const;
|
label findNull() const;
|
||||||
|
|
||||||
|
//- FatalError if any null exists in the list
|
||||||
|
inline void checkNonNull() const;
|
||||||
|
|
||||||
//- Assign all pointers to nullptr, without deleting.
|
//- Assign all pointers to nullptr, without deleting.
|
||||||
void setNull();
|
void setNull();
|
||||||
|
|
||||||
|
|||||||
@ -109,6 +109,20 @@ inline void Foam::Detail::PtrListDetail<T>::resize(const label newLen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void Foam::Detail::PtrListDetail<T>::checkNonNull() const
|
||||||
|
{
|
||||||
|
const label idx = this->findNull();
|
||||||
|
|
||||||
|
if (idx >= 0)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Element " << idx << " is null" << nl
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -40,8 +40,8 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef PtrListOps_H
|
#ifndef Foam_PtrListOps_H
|
||||||
#define PtrListOps_H
|
#define Foam_PtrListOps_H
|
||||||
|
|
||||||
#include "predicates.H"
|
#include "predicates.H"
|
||||||
#include "PtrList.H"
|
#include "PtrList.H"
|
||||||
@ -54,31 +54,23 @@ namespace Foam
|
|||||||
|
|
||||||
//- Return (stable) sort order for the list
|
//- Return (stable) sort order for the list
|
||||||
template<class T>
|
template<class T>
|
||||||
labelList sortedOrder(const UPtrList<T>& input);
|
labelList sortedOrder(const UPtrList<T>& list);
|
||||||
|
|
||||||
//- Generate (stable) sort order for the list
|
//- Generate (stable) sort order for the list
|
||||||
template<class T>
|
template<class T>
|
||||||
void sortedOrder(const UPtrList<T>& input, labelList& order);
|
void sortedOrder(const UPtrList<T>& list, labelList& order);
|
||||||
|
|
||||||
//- Generate (stable) sort order for the list,
|
//- Generate (stable) sort order for the list,
|
||||||
//- using the specified list compare predicate
|
//- using the specified list compare predicate
|
||||||
template<class T, class ListComparePredicate>
|
template<class T, class ListComparePredicate>
|
||||||
void sortedOrder
|
void sortedOrder
|
||||||
(
|
(
|
||||||
const UPtrList<T>& input,
|
const UPtrList<T>& list,
|
||||||
labelList& order,
|
labelList& order,
|
||||||
const ListComparePredicate& comp
|
const ListComparePredicate& comp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Inplace (stable) sorting of pointer list.
|
|
||||||
template<class T>
|
|
||||||
void sort(UPtrList<T>& list);
|
|
||||||
|
|
||||||
//- Inplace (stable) sorting of pointer list.
|
|
||||||
template<class T, class Compare>
|
|
||||||
void sort(UPtrList<T>& list, const Compare& comp);
|
|
||||||
|
|
||||||
//- Inplace shuffle of pointer list.
|
//- Inplace shuffle of pointer list.
|
||||||
template<class T>
|
template<class T>
|
||||||
void shuffle(UPtrList<T>& list);
|
void shuffle(UPtrList<T>& list);
|
||||||
@ -91,52 +83,6 @@ void shuffle(UPtrList<T>& list);
|
|||||||
namespace PtrListOps
|
namespace PtrListOps
|
||||||
{
|
{
|
||||||
|
|
||||||
// Public Classes
|
|
||||||
|
|
||||||
//- A UPtrList compare binary predicate for normal sort.
|
|
||||||
// Null entries sort to the end
|
|
||||||
template<class T>
|
|
||||||
struct less
|
|
||||||
{
|
|
||||||
const UPtrList<T>& values;
|
|
||||||
|
|
||||||
less(const UPtrList<T>& list)
|
|
||||||
:
|
|
||||||
values(list)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator()(const label a, const label b) const
|
|
||||||
{
|
|
||||||
const T* const ptr1 = values(a);
|
|
||||||
const T* const ptr2 = values(b);
|
|
||||||
|
|
||||||
return (ptr1 && ptr2) ? (*ptr1 < *ptr2) : !ptr2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- A UPtrList compare binary predicate for reverse sort.
|
|
||||||
// Null entries sort to the end
|
|
||||||
template<class T>
|
|
||||||
struct greater
|
|
||||||
{
|
|
||||||
const UPtrList<T>& values;
|
|
||||||
|
|
||||||
greater(const UPtrList<T>& list)
|
|
||||||
:
|
|
||||||
values(list)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator()(const label a, const label b) const
|
|
||||||
{
|
|
||||||
const T* const ptr1 = values(a);
|
|
||||||
const T* const ptr2 = values(b);
|
|
||||||
|
|
||||||
return (ptr1 && ptr2) ? (*ptr2 < *ptr1) : !ptr2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- List of values generated by applying the access operation
|
//- List of values generated by applying the access operation
|
||||||
//- to each list item.
|
//- to each list item.
|
||||||
//
|
//
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,11 +32,11 @@ License
|
|||||||
template<class T>
|
template<class T>
|
||||||
Foam::labelList Foam::sortedOrder
|
Foam::labelList Foam::sortedOrder
|
||||||
(
|
(
|
||||||
const UPtrList<T>& input
|
const UPtrList<T>& list
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
labelList order;
|
labelList order;
|
||||||
sortedOrder(input, order, typename PtrListOps::less<T>(input));
|
Foam::sortedOrder(list, order, typename UPtrList<T>::less(list));
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,59 +44,49 @@ Foam::labelList Foam::sortedOrder
|
|||||||
template<class T>
|
template<class T>
|
||||||
void Foam::sortedOrder
|
void Foam::sortedOrder
|
||||||
(
|
(
|
||||||
const UPtrList<T>& input,
|
const UPtrList<T>& list,
|
||||||
labelList& order
|
labelList& order
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
sortedOrder(input, order, typename PtrListOps::less<T>(input));
|
Foam::sortedOrder(list, order, typename UPtrList<T>::less(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class ListComparePredicate>
|
template<class T, class ListComparePredicate>
|
||||||
void Foam::sortedOrder
|
void Foam::sortedOrder
|
||||||
(
|
(
|
||||||
const UPtrList<T>& input,
|
const UPtrList<T>& list,
|
||||||
labelList& order,
|
labelList& order,
|
||||||
const ListComparePredicate& comp
|
const ListComparePredicate& comp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// List lengths must be identical. Old content is overwritten
|
// List lengths must be identical. Old content is overwritten
|
||||||
order.resize_nocopy(input.size());
|
order.resize_nocopy(list.size());
|
||||||
|
|
||||||
ListOps::identity(order);
|
// Same as std::iota and ListOps::identity
|
||||||
|
label value = 0;
|
||||||
|
for (label& item : order)
|
||||||
|
{
|
||||||
|
item = value;
|
||||||
|
++value;
|
||||||
|
}
|
||||||
|
|
||||||
Foam::stableSort(order, comp);
|
std::stable_sort(order.begin(), order.end(), comp);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void Foam::sort(UPtrList<T>& list)
|
|
||||||
{
|
|
||||||
labelList order;
|
|
||||||
sortedOrder(list, order);
|
|
||||||
list.sortOrder(order, false); // false = allow nullptr
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T, class Compare>
|
|
||||||
void Foam::sort(UPtrList<T>& list, const Compare& comp)
|
|
||||||
{
|
|
||||||
labelList order;
|
|
||||||
sortedOrder(list, order, comp);
|
|
||||||
list.sortOrder(order, false); // false = allow nullptr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::shuffle(UPtrList<T>& list)
|
void Foam::shuffle(UPtrList<T>& list)
|
||||||
{
|
{
|
||||||
|
// Cannot use std::shuffle directly since that would dereference
|
||||||
|
// the list entries, which may contain null pointers.
|
||||||
|
// The alternative would be to expose the pointer details (a bit ugly).
|
||||||
labelList order(identity(list.size()));
|
labelList order(identity(list.size()));
|
||||||
Foam::shuffle(order);
|
Foam::shuffle(order);
|
||||||
list.sortOrder(order, false); // false = allow nullptr
|
list.sortOrder(order, false); // false = no nullptr check
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Templated implementation for types(), names(), etc - file-scope
|
// Templated implementation for types(), names(), etc - file-scope
|
||||||
template<class ReturnType, class T, class AccessOp>
|
template<class ReturnType, class T, class AccessOp>
|
||||||
Foam::List<ReturnType> Foam::PtrListOps::get
|
Foam::List<ReturnType> Foam::PtrListOps::get
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2019 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -66,11 +66,7 @@ Foam::label Foam::UPtrList<T>::squeezeNull()
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::UPtrList<T>::reorder
|
void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
|
||||||
(
|
|
||||||
const labelUList& oldToNew,
|
|
||||||
const bool testNull
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
const label len = this->size();
|
const label len = this->size();
|
||||||
|
|
||||||
@ -87,37 +83,31 @@ void Foam::UPtrList<T>::reorder
|
|||||||
|
|
||||||
for (label i=0; i<len; ++i)
|
for (label i=0; i<len; ++i)
|
||||||
{
|
{
|
||||||
const label idx = oldToNew[i];
|
const label newIdx = oldToNew[i];
|
||||||
|
|
||||||
if (idx < 0 || idx >= len)
|
if (newIdx < 0 || newIdx >= len)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Illegal index " << idx << nl
|
<< "Illegal index " << newIdx << nl
|
||||||
<< "Valid indices are [0," << len << ") for type "
|
<< "Valid indices are [0," << len << ") for type "
|
||||||
<< typeid(T).name() << nl
|
<< typeid(T).name() << nl
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newList[idx])
|
if (newList[newIdx])
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "reorder map is not unique; element " << idx
|
<< "reorder map is not unique; element " << newIdx
|
||||||
<< " already used for type " << typeid(T).name()
|
<< " already used for type " << typeid(T).name()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
newList[idx] = ptrs_[i];
|
newList[newIdx] = ptrs_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that all pointers were indeed set
|
// Verify all pointers were indeed set
|
||||||
if (testNull)
|
if (check)
|
||||||
{
|
{
|
||||||
const label idx = newList.findNull();
|
newList.checkNonNull();
|
||||||
if (idx >= 0)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Element " << idx << " not set after reordering." << nl
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrs_.transfer(newList);
|
ptrs_.transfer(newList);
|
||||||
@ -125,11 +115,7 @@ void Foam::UPtrList<T>::reorder
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::UPtrList<T>::sortOrder
|
void Foam::UPtrList<T>::sortOrder(const labelUList& order, const bool check)
|
||||||
(
|
|
||||||
const labelUList& order,
|
|
||||||
const bool testNull
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
const label len = this->size();
|
const label len = this->size();
|
||||||
|
|
||||||
@ -147,39 +133,33 @@ void Foam::UPtrList<T>::sortOrder
|
|||||||
|
|
||||||
for (label i=0; i<len; ++i)
|
for (label i=0; i<len; ++i)
|
||||||
{
|
{
|
||||||
const label idx = order[i];
|
const label oldIdx = order[i];
|
||||||
|
|
||||||
if (idx < 0 || idx >= len)
|
if (oldIdx < 0 || oldIdx >= len)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Illegal index " << idx << nl
|
<< "Illegal index " << oldIdx << nl
|
||||||
<< "Valid indices are [0," << len << ") for type "
|
<< "Valid indices are [0," << len << ") for type "
|
||||||
<< typeid(T).name() << nl
|
<< typeid(T).name() << nl
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guard[idx])
|
if (guard[oldIdx])
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "order map is not unique; element " << idx
|
<< "order map is not unique; element " << oldIdx
|
||||||
<< " already used for type " << typeid(T).name()
|
<< " already used for type " << typeid(T).name()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
guard[idx] = ptrs_[idx];
|
guard[oldIdx] = ptrs_[oldIdx];
|
||||||
newList[i] = ptrs_[idx];
|
newList[i] = ptrs_[oldIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that all pointers were indeed set
|
// Verify that all pointers were indeed set
|
||||||
if (testNull)
|
if (check)
|
||||||
{
|
{
|
||||||
const label idx = newList.findNull();
|
newList.checkNonNull();
|
||||||
if (idx >= 0)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Element " << idx << " not set after reordering." << nl
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrs_.transfer(newList);
|
ptrs_.transfer(newList);
|
||||||
@ -195,4 +175,26 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class T, class Compare>
|
||||||
|
void Foam::sort(UPtrList<T>& list, const Compare& comp)
|
||||||
|
{
|
||||||
|
std::stable_sort
|
||||||
|
(
|
||||||
|
list.begin_ptr(),
|
||||||
|
list.end_ptr(),
|
||||||
|
typename UPtrList<T>::template value_compare<Compare>(comp)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void Foam::sort(UPtrList<T>& list)
|
||||||
|
{
|
||||||
|
// ie, lessOp<T>() or std::less<T>()
|
||||||
|
Foam::sort(list, [](const T& a, const T& b) { return (a < b); });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -110,6 +110,72 @@ public:
|
|||||||
class const_iterator;
|
class const_iterator;
|
||||||
|
|
||||||
|
|
||||||
|
// Public Classes
|
||||||
|
|
||||||
|
//- A wrapper for a binary comparison of values that interjects
|
||||||
|
//- pointer dereferencing with null pointer guards.
|
||||||
|
// It will also sort any null pointers to the end
|
||||||
|
// (eg, rubbish that can be truncated)
|
||||||
|
template<class Compare>
|
||||||
|
struct value_compare
|
||||||
|
{
|
||||||
|
const Compare& comp;
|
||||||
|
|
||||||
|
value_compare(const Compare& cmp)
|
||||||
|
:
|
||||||
|
comp(cmp)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Compare dereferenced pointers
|
||||||
|
bool operator()(const T* const a, const T* const b) const
|
||||||
|
{
|
||||||
|
return (a && b) ? comp(*a, *b) : bool(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//- A UPtrList compare binary predicate for normal sort order.
|
||||||
|
//- Null entries (if any) sort to the end.
|
||||||
|
struct less
|
||||||
|
{
|
||||||
|
const UPtrList<T>& values;
|
||||||
|
|
||||||
|
less(const UPtrList<T>& list)
|
||||||
|
:
|
||||||
|
values(list)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Compare dereferenced pointer locations for normal sort.
|
||||||
|
bool operator()(const label ai, const label bi) const
|
||||||
|
{
|
||||||
|
const T* const a = values.get(ai);
|
||||||
|
const T* const b = values.get(bi);
|
||||||
|
|
||||||
|
return (a && b) ? (*a < *b) : bool(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//- A UPtrList compare binary predicate for reverse sort order.
|
||||||
|
// Null entries (if any) sort to the end.
|
||||||
|
struct greater
|
||||||
|
{
|
||||||
|
const UPtrList<T>& values;
|
||||||
|
|
||||||
|
greater(const UPtrList<T>& list)
|
||||||
|
:
|
||||||
|
values(list)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Compare dereferenced pointer locations for reverse sort
|
||||||
|
bool operator()(const label ai, const label bi) const
|
||||||
|
{
|
||||||
|
const T* const a = values.get(ai);
|
||||||
|
const T* const b = values.get(bi);
|
||||||
|
|
||||||
|
return (a && b) ? (*b < *a) : bool(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Default construct
|
//- Default construct
|
||||||
@ -215,13 +281,19 @@ public:
|
|||||||
|
|
||||||
//- Reorder elements.
|
//- Reorder elements.
|
||||||
//- Reordering must be unique (ie, shuffle).
|
//- Reordering must be unique (ie, shuffle).
|
||||||
// Optionally verify that all pointers have been set.
|
// Optionally check that all pointers have been set.
|
||||||
void reorder(const labelUList& oldToNew, const bool testNull = true);
|
void reorder(const labelUList& oldToNew, const bool check = false);
|
||||||
|
|
||||||
//- Reorder elements according to new order mapping (newToOld).
|
//- Reorder elements according to new order mapping (newToOld).
|
||||||
//- Reordering must be unique (ie, shuffle).
|
//- Reordering must be unique (ie, shuffle).
|
||||||
// Optionally verify that all pointers have been set.
|
// Optionally check that all pointers have been set.
|
||||||
void sortOrder(const labelUList& order, const bool testNull = true);
|
void sortOrder(const labelUList& order, const bool check = false);
|
||||||
|
|
||||||
|
|
||||||
|
// Checks
|
||||||
|
|
||||||
|
//- Check and raise FatalError if any nullptr exists in the list
|
||||||
|
inline void checkNonNull() const;
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -362,22 +434,29 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//- Return an iterator to begin traversing the UPtrList
|
//- Iterator to begin of raw pointers traversal (use with caution)
|
||||||
|
T** begin_ptr() noexcept { return ptrs_.begin(); }
|
||||||
|
|
||||||
|
//- Iterator beyond end of raw pointers traversal (use with caution)
|
||||||
|
T** end_ptr() noexcept { return ptrs_.end(); }
|
||||||
|
|
||||||
|
|
||||||
|
//- Return an iterator to begin of UPtrList traversal
|
||||||
inline iterator begin() noexcept;
|
inline iterator begin() noexcept;
|
||||||
|
|
||||||
//- Return an iterator to end traversing the UPtrList
|
//- Return iterator beyond end of UPtrList traversal
|
||||||
inline iterator end() noexcept;
|
inline iterator end() noexcept;
|
||||||
|
|
||||||
//- Return an const_iterator to begin traversing the UPtrList
|
//- Return const_iterator to begin of UPtrList traversal
|
||||||
inline const_iterator cbegin() const noexcept;
|
inline const_iterator cbegin() const noexcept;
|
||||||
|
|
||||||
//- Return an const_iterator to end traversing the UPtrList
|
//- Return const_iterator beyond end of UPtrList traversal
|
||||||
inline const_iterator cend() const noexcept;
|
inline const_iterator cend() const noexcept;
|
||||||
|
|
||||||
//- Return an const_iterator to begin traversing the UPtrList
|
//- Return const_iterator to begin of UPtrList traversal
|
||||||
inline const_iterator begin() const noexcept;
|
inline const_iterator begin() const noexcept;
|
||||||
|
|
||||||
//- Return an const_iterator to end traversing the UPtrList
|
//- Return const_iterator beyond end of UPtrList traversal
|
||||||
inline const_iterator end() const noexcept;
|
inline const_iterator end() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
@ -392,6 +471,20 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
//- Inplace (stable) sorting of pointer list.
|
||||||
|
template<class T>
|
||||||
|
void sort(UPtrList<T>& list);
|
||||||
|
|
||||||
|
//- Inplace (stable) sorting of pointer list using given comparator,
|
||||||
|
//- which compares objects, not pointers.
|
||||||
|
// This sort function includes null pointer guards and will also sort
|
||||||
|
// any null pointers to the end (eg, rubbish that can be truncated)
|
||||||
|
template<class T, class Compare>
|
||||||
|
void sort(UPtrList<T>& list, const Compare& comp);
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -215,6 +215,13 @@ inline T* Foam::UPtrList<T>::set(const label i, T* ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void Foam::UPtrList<T>::checkNonNull() const
|
||||||
|
{
|
||||||
|
ptrs_.checkNonNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|||||||
Reference in New Issue
Block a user