ENH: update List and DynamicList methods (issue #595)

- improve functional compatibility with DynList (remove methods)
  * eg, remove an element from any position in a DynamicList
  * reduce the number of template parameters
  * remove/subset regions of DynamicList

- propagate Swap template specializations for lists, hashtables

- move construct/assignment to various containers.

- add find/found methods for FixedList and UList for a more succinct
  (and clearer?) usage than the equivalent global findIndex() function.

- simplify List_FOR_ALL loops
This commit is contained in:
Mark Olesen
2017-09-20 17:20:54 +02:00
parent 68e7533847
commit 049617d037
74 changed files with 3205 additions and 1169 deletions

View File

@ -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) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,7 +27,10 @@ Description
#include "DynamicList.H"
#include "IOstreams.H"
#include "FlatOutput.H"
#include "ListOps.H"
#include "labelRange.H"
#include "labelIndList.H"
using namespace Foam;
@ -44,15 +47,15 @@ void printInfo
{
Info<< " size=\"" << lst.size() << "\"";
}
Info<< ">" << lst << "</" << tag << ">" << endl;
Info<< ">" << nl << flatOutput(lst) << nl << "</" << tag << ">" << endl;
}
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
template<class T, int SizeMin>
void printInfo
(
const word& tag,
const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst,
const DynamicList<T, SizeMin>& lst,
const bool showSize = false
)
{
@ -62,7 +65,7 @@ void printInfo
Info<< " size=\"" << lst.size()
<< "\" capacity=\"" << lst.capacity() << "\"";
}
Info<< ">" << lst << "</" << tag << ">" << endl;
Info<< ">" << nl << flatOutput(lst) << nl << "</" << tag << ">" << endl;
}
@ -71,7 +74,7 @@ void printInfo
int main(int argc, char *argv[])
{
List<DynamicList<label, 1, 0>> ldl(2);
List<DynamicList<label>> ldl(2);
ldl[0](0) = 0;
ldl[0](2) = 2;
@ -89,7 +92,7 @@ int main(int argc, char *argv[])
ldl[1] = 3;
Info<< "<ldl>" << ldl << "</ldl>" << nl << "sizes: ";
Info<< "<ldl>" << flatOutput(ldl) << "</ldl>" << nl << "sizes: ";
forAll(ldl, i)
{
Info<< " " << ldl[i].size() << "/" << ldl[i].capacity();
@ -100,7 +103,7 @@ int main(int argc, char *argv[])
ll[0].transfer(ldl[0]);
ll[1].transfer(ldl[1].shrink());
Info<< "<ldl>" << ldl << "</ldl>" << nl << "sizes: ";
Info<< "<ldl>" << flatOutput(ldl) << "</ldl>" << nl << "sizes: ";
forAll(ldl, i)
{
Info<< " " << ldl[i].size() << "/" << ldl[i].capacity();
@ -111,18 +114,18 @@ int main(int argc, char *argv[])
// test the transfer between DynamicLists
DynamicList<label, 1, 0> dlA
DynamicList<label> dlA
{
0, 1, 2, 3, 4
};
dlA.append({ 5, 6 });
dlA = { 1, 2, 4 };
DynamicList<label, 1, 0> dlB;
DynamicList<label> dlB;
dlA.setCapacity(10);
Info<< "<dlA>" << dlA << "</dlA>" << nl << "sizes: "
Info<< "<dlA>" << flatOutput(dlA) << "</dlA>" << nl << "sizes: "
<< " " << dlA.size() << "/" << dlA.capacity() << endl;
dlB.transfer(dlA);
@ -132,9 +135,9 @@ int main(int argc, char *argv[])
dlB[6] = 6;
Info<< "Transferred to dlB" << endl;
Info<< "<dlA>" << dlA << "</dlA>" << nl << "sizes: "
Info<< "<dlA>" << flatOutput(dlA) << "</dlA>" << nl << "sizes: "
<< " " << dlA.size() << "/" << dlA.capacity() << endl;
Info<< "<dlB>" << dlB << "</dlB>" << nl << "sizes: "
Info<< "<dlB>" << flatOutput(dlB) << "</dlB>" << nl << "sizes: "
<< " " << dlB.size() << "/" << dlB.capacity() << endl;
// try with a normal list:
@ -166,7 +169,7 @@ int main(int argc, char *argv[])
// check allocation granularity
DynamicList<label, 6, 0> dlC;
DynamicList<label> dlC;
printInfo("dlC", dlC, true);
@ -227,15 +230,89 @@ int main(int argc, char *argv[])
dlE2[i] *= 10;
}
UIndirectList<label> uil
labelUIndList uil
(
dlE2, addr
);
Info<< "use UIndirectList " << uil << " remapped from " << dlE2 << endl;
dlE4 = uil;
printInfo("dlE4", dlE4, true);
}
}
{
Info<< nl << "Test moving:" << nl;
labelList input1 = identity(15);
labelList input2 = identity(15);
inplaceReverseList(input2);
DynamicList<label> list1(std::move(input1));
DynamicList<label> list2;
Info<< "move construct:" << nl
<< "input: " << flatOutput(input1) << nl
<< "list: " << flatOutput(list1) << endl;
list1 = std::move(input2);
Info<< "move assignment:" << nl
<< "input: " << flatOutput(input2) << nl
<< "list: " << flatOutput(list1) << endl;
list2 = std::move(list1);
Info<< "list in: " << flatOutput(list1) << nl
<< "list out: " << flatOutput(list2) << endl;
input2 = std::move(identity(15));
list2 = std::move(input2);
Info<< "list in: " << flatOutput(input2) << nl
<< "list out: " << flatOutput(list2) << endl;
input1 = identity(15);
input2 = identity(15);
inplaceReverseList(input2);
Info<< "test move-append with "
<< flatOutput(input1) << " and " << flatOutput(input2) << endl;
list2.append(std::move(list1));
list2.append(std::move(input1));
list2.append(std::move(input2));
Info<< "result: " << flatOutput(list2) << nl
<< "inputs: " << flatOutput(list1) << " / "
<< flatOutput(input1) << " / "
<< flatOutput(input2) << nl;
input1 = list2;
Info<< nl << "test subset/remove with "
<< flatOutput(input1) << endl;
for
(
const labelRange range :
{
labelRange(-10, 8), // invalid range
labelRange(40, 18), // trailing portion
labelRange(-5, 10), // leading portion
labelRange(10, 8), // mid-portion
labelRange(0, input1.size()), // everything
}
)
{
list1 = input1;
list2 = input1;
list1.remove(range);
list2.subset(range);
Info<< "input = " << flatOutput(input1) << nl
<< "remove " << range << " = " << flatOutput(list1) << nl
<< "subset " << range << " = " << flatOutput(list2) << nl;
}
}
Info<< "\nEnd\n";

View File

@ -1,3 +0,0 @@
Test-Field.C
EXE = $(FOAM_USER_APPBIN)/Test-Field

View File

@ -1,2 +0,0 @@
/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
/* EXE_LIBS = -lfiniteVolume */

View File

@ -1,11 +0,0 @@
#include "Test-Field.H"
int main()
{
Vector<double> v1(1, 2);
Vector<double> v2(2, 3);
std::cout << v1 + v2;
return 0;
}

View File

@ -1,58 +0,0 @@
#include <iostream>
template<class C>
class Vector;
template<class C>
Vector<C> operator+(const Vector<C>& v1, const Vector<C>& v2);
template<class C>
std::ostream& operator<<(std::ostream& os, const Vector<C>& v);
/*---------------------------------------------------------------------------*\
Class Vector Declaration
\*---------------------------------------------------------------------------*/
template<class C>
class Vector
{
double X, Y;
public:
inline Vector(const double x, const double y);
C x() const
{
return X;
}
C y() const
{
return Y;
}
friend Vector<C> operator+ <C>(const Vector<C>& v1, const Vector<C>& v2);
friend std::ostream& operator<<(std::ostream& os, const Vector<C>& v)
{
os << v.X << '\t' << v.Y << '\n';
return os;
}
};
template<class C>
inline Vector<C>::Vector(const double x, const double y)
{
X = x;
Y = y;
}
template<class C>
inline Vector<C> operator+(const Vector<C>& v1, const Vector<C>& v2)
{
return Vector<C>(v1.X+v2.X, v1.Y+v2.Y);
}

View File

@ -35,6 +35,7 @@ See also
#include "argList.H"
#include "FixedList.H"
#include "Fstream.H"
#include "List.H"
#include "IPstream.H"
#include "OPstream.H"
@ -47,36 +48,44 @@ int main(int argc, char *argv[])
{
argList args(argc, argv);
FixedList<label, 4> list;
list[0] = 1;
list[1] = 2;
list[2] = 3;
list[3] = 4;
Info<< "list:" << list
<< " hash:" << FixedList<label, 4>::Hash<>()(list) << endl;
label a[4] = {0, 1, 2, 3};
FixedList<label, 4> list2(a);
Info<< "list2:" << list2
<< " hash:" << FixedList<label, 4>::Hash<>()(list2) << endl;
// Using FixedList for content too
{
List<FixedList<label, 4>> twolists{list, list2};
Info<<"List of FixedList: " << flatOutput(twolists) << endl;
sort(twolists);
// outer-sort only
Info<<"sorted FixedList : " << flatOutput(twolists) << endl;
}
FixedList<label, 4> list1{1, 2, 3, 4};
Info<< "list: " << list << nl
<< "list2: " << list2 << endl;
list.swap(list2);
Info<< "Swapped via the swap() method" << endl;
Info<< "list: " << list << nl
<< "list2: " << list2 << endl;
Info<< "list1:" << list1
<< " hash:" << FixedList<label, 4>::Hash<>()(list1) << endl;
label a[4] = {0, 1, 2, 3};
FixedList<label, 4> list2(a);
Info<< "list2:" << list2
<< " hash:" << FixedList<label, 4>::Hash<>()(list2) << endl;
// Using FixedList for content too
{
List<FixedList<label, 4>> twolists{list1, list2};
Info<<"List of FixedList: " << flatOutput(twolists) << endl;
sort(twolists);
// outer-sort only
Info<<"sorted FixedList : " << flatOutput(twolists) << endl;
}
Info<< "====" << nl
<< "Test swap" << nl;
Info<< "list1: " << list1 << nl
<< "list2: " << list2 << endl;
list1.swap(list2);
Info<< "The swap() method" << endl;
Info<< "list1: " << list1 << nl
<< "list2: " << list2 << endl;
Swap(list1, list2);
Info<< "The Swap() function" << endl;
Info<< "list1: " << list1 << nl
<< "list2: " << list2 << endl;
Info<< "====" << nl;
}
List<label> list3{0, 1, 2, 3};
FixedList<label, 4> list4(list3.begin(), list3.end());

View File

@ -0,0 +1,3 @@
Test-FixedList2.C
EXE = $(FOAM_USER_APPBIN)/Test-FixedList2

View File

@ -0,0 +1,190 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-FixedList2
Description
Test speeds, usability of some List/FixedList operations
See also
Foam::FixedList
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "FixedList.H"
#include "labelList.H"
#include "vectorList.H"
#include "ListOps.H"
#include "IFstream.H"
#include "OFstream.H"
#include "cpuTime.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam;
template<class ListType>
void runSwapTest
(
const label nLoops,
ListType& list1,
ListType& list2
)
{
cpuTime timer;
Info<<"Swapping fixed lists with " << list1.size() << " elements\n";
Info<< "input 1: " << list1.first() << nl;
Info<< "input 2: " << list2.first() << nl;
// Should be zero, since this is a compile-time value
Info<< "Perform " << nLoops << " swaps..." << nl;
for (label iLoop = 0; iLoop < nLoops; ++iLoop)
{
Swap(list1, list2);
}
Info<< "output 1: " << list1.first() << nl;
Info<< "output 2: " << list2.first() << nl;
Info<< "Operation took"
<< " " << timer.cpuTimeIncrement() << " s\n\n";
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addBoolOption("label");
argList::addBoolOption("float");
argList::addBoolOption("vector");
argList::addBoolOption("labelList");
argList::addBoolOption("vectorList");
argList::addBoolOption("fixedLabel");
argList::addBoolOption("fixedLabelList");
argList args(argc, argv);
if (args.options().empty())
{
Info<< nl << "Specify an option! " << nl << endl;
}
if (args.optionFound("label"))
{
FixedList<label, 100000> list1(1);
FixedList<label, 100000> list2(0);
runSwapTest(1000001, list1, list2);
}
if (args.optionFound("float"))
{
FixedList<double, 100000> list1(1.0);
FixedList<double, 100000> list2(0.0);
runSwapTest(1000001, list1, list2);
}
if (args.optionFound("vector"))
{
FixedList<vector, 100000> list1(vector::one);
FixedList<vector, 100000> list2(vector::zero);
runSwapTest(100001, list1, list2);
}
if (args.optionFound("labelList"))
{
typedef labelList testType;
testType initVal(500);
initVal = 0;
FixedList<testType, 1000> list1(initVal);
initVal = 1;
FixedList<testType, 1000> list2(initVal);
runSwapTest(100001, list1, list2);
}
if (args.optionFound("vectorList"))
{
typedef vectorList testType;
testType initVal(500);
initVal = vector::zero;
FixedList<testType, 1000> list1(initVal);
initVal = vector::one;
FixedList<testType, 1000> list2(initVal);
runSwapTest(100001, list1, list2);
}
if (args.optionFound("fixedLabel"))
{
typedef FixedList<label,1000> testType;
testType initVal;
initVal = 0;
FixedList<testType, 1000> list1(initVal);
initVal = 1;
FixedList<testType, 1000> list2(initVal);
runSwapTest(100001, list1, list2);
}
if (args.optionFound("fixedLabelList"))
{
typedef labelList testType;
typedef FixedList<testType,10> containerType;
testType tinitVal(500);
containerType initVal;
tinitVal = 0;
initVal = tinitVal;
FixedList<containerType, 1000> list1(initVal);
tinitVal = 1;
initVal = tinitVal;
FixedList<containerType, 1000> list2(initVal);
runSwapTest(10001, list1, list2);
}
Info<< nl << "Done" << nl << endl;
return 0;
}
// ************************************************************************* //

View File

@ -31,6 +31,7 @@ Description
#include "fvCFD.H"
#include "Function1.H"
#include "scalarIndList.H"
#include "IOdictionary.H"
#include "linearInterpolationWeights.H"
#include "splineInterpolationWeights.H"
@ -69,7 +70,7 @@ int main(int argc, char *argv[])
scalar baseSum = interpolator.weightedSum
(
weights,
UIndirectList<scalar>(values, indices)
scalarUIndList(values, indices)
);
Pout<< "baseSum=" << baseSum << nl << nl << endl;
@ -78,7 +79,7 @@ int main(int argc, char *argv[])
// scalar partialSum = interpolator.weightedSum
// (
// weights,
// UIndirectList<scalar>(values, indices)
// scalarUIndList(values, indices)
// );
// Pout<< "partialSum=" << partialSum << nl << nl << endl;
//
@ -90,7 +91,7 @@ int main(int argc, char *argv[])
// scalar sum = interpolator.weightedSum
// (
// weights,
// UIndirectList<scalar>(values, indices)
// scalarUIndList(values, indices)
// );
// Pout<< "integrand=" << sum << nl << nl << endl;

View File

@ -223,6 +223,31 @@ int main(int argc, char *argv[])
Info << i << endl;
}
Info<< nl << "Test swapping, moving etc." << nl;
setA.insert({ "some", "more", "entries" });
Info<< "input" << nl;
Info<< "setA: " << setA << nl;
wordHashSet setA1(std::move(setA));
Info<< "move construct" << nl;
Info<< "setA: " << setA << nl
<< "setA1: " << setA1 << nl;
wordHashSet setB1;
Info<< "move assign" << nl;
setB1 = std::move(setA1);
Info<< "setA1: " << setA1 << nl
<< "setB1: " << setB1 << nl;
setB1.swap(setA1);
Info<< "setA1: " << setA1 << nl
<< "setB1: " << setB1 << nl;
return 0;
}

View File

@ -324,6 +324,34 @@ int main()
<< nl;
// Start again with new value
table2.set("ada", 14.0);
table2.set("aeq", 15.0);
table2.set("aaw", 16.0);
Info<< nl << "input values" << nl;
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"global Swap function" << nl;
Swap(table1, table2);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"swap method" << nl;
table1.swap(table2);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"transfer" << nl;
table1.transfer(table2);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"move assign" << nl;
table2 = std::move(table1);
Info<<"table1 = " << table1 << nl <<"table2 = " << table2 << nl;
Info<<"move construct" << nl;
HashTable<scalar> table1b(std::move(table2));
Info<<"table1 = " << table1b << nl <<"table2 = " << table2 << nl;
Info<< "\nDone\n";
return 0;

View File

@ -27,58 +27,70 @@ Description
#include "IndirectList.H"
#include "IOstreams.H"
#include "ListOps.H"
#include "labelIndList.H"
using namespace Foam;
template<class ListType>
void printInfo(const ListType& lst)
{
Info<< "addr: " << lst.addressing() << nl
<< "list: " << lst << nl
Info<< "addr: " << flatOutput(lst.addressing()) << nl
<< "list: " << flatOutput(lst) << nl
<< endl;
}
template<class T, class ListType>
void testFind(const T& val, const ListType& lst)
{
Info<< nl
<< "Search for "<< val << " in " << flatOutput(lst) << nl
<<" found() = " << lst.found(val)
<<" find() = " << lst.find(val)
<<" rfind() = " << lst.rfind(val)
<<" find(2) = " << lst.find(val, 2)
<<" rfind(2) = " << lst.rfind(val, 2)
<<" findIndex = " << findIndex(lst, val) << nl
<< nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
List<double> completeList(10);
List<label> completeList(20);
forAll(completeList, i)
{
completeList[i] = 0.1*i;
completeList[i] = 10*i;
}
Info<< "raw : " << completeList << nl << endl;
Info<< "raw : " << flatOutput(completeList) << nl << endl;
List<label> addresses{1, 0, 3, 7, 4, 8, 5, 1, 0, 3, 7, 4, 8, 5, };
List<label> addresses(5);
addresses[0] = 1;
addresses[1] = 0;
addresses[2] = 7;
addresses[3] = 8;
addresses[4] = 5;
IndirectList<double> idl1(completeList, addresses);
labelIndList idl1(completeList, addresses);
printInfo(idl1);
addresses[4] = 1;
addresses[3] = 0;
addresses[2] = 7;
addresses[1] = 8;
addresses[0] = 5;
for (const label val : { 10, 30, 40, 50, 90, 80, 120 } )
{
testFind(val, idl1);
}
inplaceReverseList(addresses);
idl1.resetAddressing(addresses.xfer());
printInfo(idl1);
// test copying
UIndirectList<double> uidl1(idl1);
IndirectList<double> idl2(uidl1);
IndirectList<double> idl3(idl2);
// Test copying
labelUIndList uidl1(idl1);
labelIndList idl2(uidl1);
labelIndList idl3(idl2);
printInfo(uidl1);

View File

@ -50,6 +50,20 @@ See also
using namespace Foam;
template<class T, class ListType>
void testFind(const T& val, const ListType& lst)
{
Info<< nl
<< "Search for "<< val << " in " << flatOutput(lst) << nl
<<" found() = " << lst.found(val)
<<" find() = " << lst.find(val)
<<" rfind() = " << lst.rfind(val)
<<" find(2) = " << lst.find(val, 2)
<<" rfind(2) = " << lst.rfind(val, 2)
<<" findIndex = " << findIndex(lst, val) << nl
<< nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
@ -84,14 +98,20 @@ int main(int argc, char *argv[])
{
vector(0, 1, 2),
vector(3, 4, 5),
vector(6, 7, 8)
vector(6, 7, 8),
vector(0, 1, 2),
vector(3, 4, 5),
vector(6, 7, 8),
};
Info<< "list2: " << list2 << endl;
list1.append(list2);
Info<< "list1.append(list2): " << list1 << endl;
Info<< findIndex(list2, vector(3, 4, 5)) << endl;
for (const vector& val : { vector(3, 4, 5), vector(10,11, 12)} )
{
testFind(val, list2);
}
list2.setSize(10, vector(1, 2, 3));
Info<< "list2: " << list2 << endl;

View File

@ -0,0 +1,3 @@
Test-List2.C
EXE = $(FOAM_USER_APPBIN)/Test-List2

View File

View File

@ -0,0 +1,269 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-List2
Description
Test speeds, usability of some List/FixedList operations
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "FixedList.H"
#include "labelList.H"
#include "vectorList.H"
#include "ListOps.H"
#include "IFstream.H"
#include "OFstream.H"
#include "cpuTime.H"
#include <initializer_list>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam;
template<class ListType>
void runResizeTest
(
const label nLoops,
ListType& list,
std::initializer_list<label> sizes
)
{
cpuTime timer;
const label size0 = list.size();
const auto val = list.first();
Info<<"Resize list(" << list.size() << ") to";
for (auto len : sizes)
{
Info<< " " << len;
}
Info<< nl;
Info<< "Perform " << nLoops << " times..." << nl;
for (label iLoop = 0; iLoop < nLoops; ++iLoop)
{
list.setSize(size0, val);
for (auto len : sizes)
{
list.setSize(len, val);
}
}
Info<< "Operation took"
<< " " << timer.cpuTimeIncrement() << " s\n\n";
}
template<class ListType>
void runOrderingTest(const label nLoops, const ListType& list)
{
if (true)
{
cpuTime timer;
float total = 0;
Info<<"forAll - perform " << nLoops << " times..." << nl;
for (label iLoop = 0; iLoop < nLoops; ++iLoop)
{
float sum = 0;
forAll(list, i)
{
sum += list[i];
}
total += sum;
}
Info<< "Operation (sum " << total << ") took"
<< " " << timer.cpuTimeIncrement() << " s\n\n";
}
if (true)
{
cpuTime timer;
float total = 0;
Info<<"reverse pointer loop - perform " << nLoops << " times..." << nl;
for (label iLoop = 0; iLoop < nLoops; ++iLoop)
{
float sum = 0;
const typename ListType::value_type* __restrict__ fp
= (list).end();
label i = (list).size();
while (i--)
{
sum += (*--fp);
}
total += sum;
}
Info<< "Operation (sum " << total << ") took"
<< " " << timer.cpuTimeIncrement() << " s\n\n";
}
if (true)
{
cpuTime timer;
float total = 0;
Info<<"forward pointer loop - perform " << nLoops << " times..." << nl;
for (label iLoop = 0; iLoop < nLoops; ++iLoop)
{
float sum = 0;
const typename ListType::value_type* __restrict__ fp
= (list).begin();
label i = (list).size();
while (i--)
{
sum += (*fp++);
}
total += sum;
}
Info<< "Operation (sum " << total << ") took"
<< " " << timer.cpuTimeIncrement() << " s\n\n";
}
if (true)
{
cpuTime timer;
float total = 0;
Info<<"for loop - perform " << nLoops << " times..." << nl;
for (label iLoop = 0; iLoop < nLoops; ++iLoop)
{
float sum = 0;
const typename ListType::value_type* __restrict__ fp
= (list).begin();
const label sz = (list).size();
for (label i=0; i<sz; ++i)
{
sum += fp[i];
}
total += sum;
}
Info<< "Operation (sum " << total << ") took"
<< " " << timer.cpuTimeIncrement() << " s\n\n";
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addBoolOption("label");
argList::addBoolOption("float");
argList::addBoolOption("vector");
argList::addBoolOption("order");
argList::addBoolOption("labelList");
argList::addBoolOption("vectorList");
argList args(argc, argv);
if (args.options().empty())
{
Info<< nl << "Specify an option! " << nl << endl;
}
std::initializer_list<label> increments
= {10000, 20000, 40000, 80000, 160000};
if (args.optionFound("label"))
{
List<label> list(10, 1);
runResizeTest(100000, list, increments);
}
if (args.optionFound("float"))
{
List<double> list(10, 1.0);
runResizeTest(10000, list, increments);
}
if (args.optionFound("vector"))
{
List<vector> list(10, vector::one);
runResizeTest(10000, list, increments);
}
if (args.optionFound("labelList"))
{
typedef labelList testType;
testType initVal(500, label(1));
List<testType> list(10, initVal);
runResizeTest(200, list, increments);
}
if (args.optionFound("vectorList"))
{
typedef vectorList testType;
testType initVal(500, vector::one);
List<testType> list(10, initVal);
runResizeTest(100, list, increments);
}
if (args.optionFound("order"))
{
List<label> list(100000000, 1);
runOrderingTest(100, list);
}
Info<< nl << "Done" << nl << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,2 @@
Test-ListOps2.C
EXE = $(FOAM_USER_APPBIN)/Test-ListOps2

View File

@ -0,0 +1,3 @@
EXE_INC = /*-DFULLDEBUG -O0 -g*/ \
EXE_LIBS =

View File

@ -0,0 +1,144 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-ListOps2
Description
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "List.H"
#include "FixedList.H"
#include "DynamicList.H"
#include "SubList.H"
#include "ListOps.H"
#include "FlatOutput.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class ListType>
void testFind(const ListType& list)
{
Info<< nl << "list: " << flatOutput(list) << nl << endl;
for (auto val : { 20, 35, 6, 13, 12, -12})
{
Info<< "lookup " << val
<< " found " << list.found(val)
<< " index " << list.find(val) << nl;
}
}
template<class ListType>
void testMoving(ListType& list)
{
Info<< nl << "list: " << flatOutput(list) << nl << endl;
{
const label i = 3;
list.swapFirst(i);
Info<<"swapFirst: " << i << " = " << flatOutput(list) << nl;
}
{
const label i = 6;
list.moveFirst(i);
Info<<"moveFirst: " << i << " = " << flatOutput(list) << nl;
}
{
const label i = 6;
list.moveLast(i);
Info<<"moveLast: " << i << " = " << flatOutput(list) << nl;
}
{
const label i = 8;
list.swapLast(i);
Info<<"swapLast: " << i << " = " << flatOutput(list) << nl;
}
}
// Main program:
int main(int argc, char *argv[])
{
List<label> list1(identity(15));
shuffle(list1);
FixedList<label, 15> list2(list1);
inplaceReverseList(list2);
DynamicList<label> list3(list1);
inplaceReverseList(list3);
testFind(list1);
testFind(list2);
testFind(list3);
testMoving(list1);
testMoving(list2);
testMoving(list3);
// Test remove
{
auto& list = list3;
Info<< nl << "list: " << flatOutput(list) << nl << endl;
list.remove();
Info<<"remove = " << flatOutput(list) << nl;
{
const label i = 6;
list.remove(i);
Info<<"rmSwap: " << i << " = " << flatOutput(list) << nl;
}
{
const label i = 3;
list.remove(i);
Info<<"rmSwap: " << i << " = " << flatOutput(list) << nl;
}
{
const label i = 8;
list.remove(i);
Info<<"rmMove: " << i << " = " << flatOutput(list) << nl;
}
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -38,41 +38,75 @@ using namespace Foam;
int main(int argc, char *argv[])
{
Map<bool> banana{{5, true}};
Map<bool> map1
{
{1, true}, {2, false}, {3, true}, {4, false}, {5, true}
};
// Taking a const iterator from find does not work!
// Also, fails later on op==
Map<bool>::const_iterator bananaIter = banana.find(5);
Map<bool>::const_iterator map1Iter = map1.cfind(5);
// This works but now I can change the value.
//Map<bool>::iterator bananaIter = banana.find(5);
// Same, but with non-const access
// Map<bool>::iterator map1Iter = map1.find(5);
if (!bananaIter.found()) // same as (bananaIter == banana.end())
if (!map1Iter.found()) // same as (map1Iter == map1.end())
{
Info<< "not found" << endl;
}
else
{
Info<< "5 is " << bananaIter() << endl;
Info<< "5 is " << *map1Iter << endl;
}
// Same with STL
// Repeat with std::map
Info<< "Same with STL" << endl;
std::map<label, bool> STLbanana{{5, true}};
std::map<label, bool>::const_iterator STLbananaIter = STLbanana.find(5);
std::map<label, bool> stdmap1
{
{1, true}, {2, false}, {3, true}, {4, false}, {5, true}
};
if (STLbananaIter == STLbanana.end())
std::map<label, bool>::const_iterator stdmap1Iter = stdmap1.find(5);
if (stdmap1Iter == stdmap1.cend())
{
Info<< "not found" << endl;
}
else
{
Info<< "5 is " << STLbananaIter->second << endl;
Info<< "5 is " << stdmap1Iter->second << endl;
}
Info<< "End\n" << endl;
Info<<"test move construct" << nl;
Map<bool> map2(std::move(map1));
Map<bool> map3;
std::map<label, bool> stdmap2(std::move(stdmap1));
std::map<label, bool> stdmap3;
Info<<"map1: " << map1 << nl
<<"map2: " << map2 << nl;
Info
<<"stdmap1: " << stdmap1.size() << nl
<<"stdmap2: " << stdmap2.size() << nl;
Info<<"test move assign" << nl;
map3 = std::move(map2);
stdmap3 = std::move(stdmap2);
Info<<"map2: " << map2 << nl
<<"map3: " << map3 << nl;
Info
<<"stdmap2: " << stdmap2.size() << nl
<<"stdmap3: " << stdmap3.size() << nl;
Info<< nl << "End\n" << endl;
return 0;
}

View File

@ -29,75 +29,102 @@ Description
#include "DynamicList.H"
#include "IOstreams.H"
#include "ListOps.H"
#include "OFstream.H"
#include "labelIndList.H"
using namespace Foam;
template<class ListType>
void printInfo(const ListType& lst)
{
Info<< "addr: " << flatOutput(lst.addressing()) << nl
<< "list: " << flatOutput(lst) << nl
<< endl;
}
template<class T, class ListType>
void testFind(const T& val, const ListType& lst)
{
Info<< nl
<< "Search for "<< val << " in " << flatOutput(lst) << nl
<<" found() = " << lst.found(val)
<<" find() = " << lst.find(val)
<<" rfind() = " << lst.rfind(val)
<<" find(2) = " << lst.find(val, 2)
<<" rfind(2) = " << lst.rfind(val, 2)
<<" findIndex = " << findIndex(lst, val) << nl
<< nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
List<double> completeList(10);
List<label> completeList(20);
forAll(completeList, i)
{
completeList[i] = 0.1*i;
completeList[i] = 10*i;
}
List<label> addresses(5);
addresses[0] = 1;
addresses[1] = 0;
addresses[2] = 7;
addresses[3] = 8;
addresses[4] = 5;
Info<< "raw : " << flatOutput(completeList) << nl << endl;
UIndirectList<double> idl(completeList, addresses);
List<label> addresses{1, 0, 3, 7, 4, 8, 5, 1, 0, 3, 7, 4, 8, 5, };
Info<< idl << "\n";
labelUIndList idl1(completeList, addresses);
idl[1] = -666;
printInfo(idl1);
Info<< "idl[1] changed: " << idl << endl;
for (const label val : { 10, 30, 40, 50, 90, 80, 120 } )
{
testFind(val, idl1);
}
idl = -999;
Info<< flatOutput(idl1) << nl;
Info<< "idl changed: " << idl << endl;
idl1[1] = -666;
UIndirectList<double> idl2(idl);
Info<< "idl1[1] changed: " << flatOutput(idl1) << endl;
Info<< "idl2: " << idl2 << endl;
idl1 = -999;
Info<< "idl1 changed: " << flatOutput(idl1) << endl;
labelUIndList idl2(idl1);
Info<< "idl2: " << flatOutput(idl2) << endl;
{
List<double> ident(idl.size());
List<label> ident(idl1.size());
forAll(ident, i)
{
ident[i] = ident.size() - i;
}
idl = ident;
idl1 = ident;
}
Info<< "idl assigned from UList: " << idl << endl;
Info<< "idl1 assigned from UList: " << flatOutput(idl1) << endl;
// test List operations
List<double> flatList(UIndirectList<double>(completeList, addresses));
Info<< "List constructed from UIndirectList: " << flatList << endl;
List<label> flatList(labelUIndList(completeList, addresses));
Info<< "List construct from UIndirectList: " << flatOutput(flatList) << nl;
flatList = UIndirectList<double>(completeList, addresses);
Info<< "List assigned from UIndirectList: " << flatList << endl;
flatList = labelUIndList(completeList, addresses);
Info<< "List assign from UIndirectList: " << flatOutput(flatList) << nl;
flatList.append(UIndirectList<double>(completeList, addresses));
Info<< "List::append(UIndirectList): " << flatList << endl;
flatList.append(labelUIndList(completeList, addresses));
Info<< "List::append(UIndirectList): " << flatOutput(flatList) << nl;
DynamicList<double> dynList(UIndirectList<double>(completeList, addresses));
Info<< "DynamicList constructed from UIndirectList: " << dynList << endl;
DynamicList<label> dynList(labelUIndList(completeList, addresses));
Info<< "DynamicList construct from UIndirectList: " << flatOutput(dynList)
<< nl;
dynList.append(UIndirectList<double>(completeList, addresses));
Info<< "DynamicList::append(UIndirectList): " << dynList << endl;
dynList.append(labelUIndList(completeList, addresses));
Info<< "DynamicList::append(UIndirectList): " << flatOutput(dynList) << nl;
Info<< "\nEnd\n" << endl;

View File

@ -33,108 +33,147 @@ using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
template<class T>
void printInfo(const SortableList<T>& list)
{
Info<< "sorted: " << list << nl
<< "indices: " << list.indices() << endl;
}
int main(int argc, char *argv[])
{
labelList orig(8);
orig[0] = 7;
orig[1] = 9;
orig[2] = 1;
orig[3] = 2;
orig[4] = 4;
orig[5] = 7;
orig[6] = 4;
orig[7] = 0;
const labelList orig{7, 9, 1, 2, 4, 7, 4, 0};
labelList order;
labelList a(orig);
sortedOrder(a, order);
labelList list1(orig);
sortedOrder(list1, order);
SortableList<label> aReverse(a.size());
aReverse = a;
SortableList<label> list1r(list1.size());
list1r = list1;
Info<< "unsorted: " << a << endl;
sort(a);
Info<< "sorted: " << a << endl;
Info<< "indices: " << order << endl;
aReverse.reverseSort();
Info<< "reverse sorted: " << aReverse << endl;
Info<< "reverse indices: " << aReverse.indices() << endl;
SortableList<label> b(orig);
Info<< "unsorted: " << orig << endl;
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
sort(list1);
Info<< "sorted: " << list1 << nl
<< "indices: " << order << endl;
Info<< "shrunk: " << b.shrink() << endl;
Info<< "indices: " << b.indices() << endl;
list1r.reverseSort();
Info<< "reverse ..." << nl;
printInfo(list1r);
SortableList<label> list2(orig);
Info<< "unsorted: " << orig << nl;
printInfo(list2);
Info<< "shrunk: " << list2.shrink() << endl;
Info<< "indices: " << list2.indices() << endl;
// repeat by assignment
b = orig;
Info<< "unsorted: " << b << endl;
b.sort();
list2 = orig;
Info<< "unsorted: " << list2 << endl;
list2.sort();
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
printInfo(list2);
// find unique/duplicate values
b = orig;
list2 = orig;
Info<< "unsorted: " << b << endl;
uniqueOrder(b, order);
Info<< "unsorted: " << list2 << endl;
uniqueOrder(list2, order);
Info<< "unique: " << order << endl;
duplicateOrder(b, order);
duplicateOrder(list2, order);
Info<< "duplicate:" << order << endl;
// sort reverse
Info<< "unsorted: " << b << endl;
b.reverseSort();
Info<< "rsort: " << b << endl;
Info<< "indices: " << b.indices() << endl;
Info<< "unsorted: " << list2 << endl;
list2.reverseSort();
Info<< "rsort: " << list2 << endl;
Info<< "indices: " << list2.indices() << endl;
// transfer assignment
a = orig;
b.transfer(a);
Info<< "unsorted: " << b << endl;
b.sort();
{
list1 = orig;
list2.transfer(list1);
Info<< "unsorted: " << list2 << endl;
list2.sort();
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
printInfo(list2);
a.transfer(b);
list1.transfer(list2);
Info<< "plain: " << a << endl;
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
Info<< "plain: " << list1 << endl;
printInfo(list2);
}
// sort/duplicate/unique with identical values
b.setSize(8);
b = 5;
list2.setSize(8);
list2 = 5;
Info<< "unsorted: " << b << endl;
Info<< "unsorted: " << list2 << endl;
uniqueOrder(b, order);
uniqueOrder(list2, order);
Info<< "unique: " << order << endl;
duplicateOrder(b, order);
duplicateOrder(list2, order);
Info<< "duplicate:" << order << endl;
b.sort();
list2.sort();
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
printInfo(list2);
// with a single value
b.setSize(1);
list2.setSize(1);
Info<< "unsorted: " << b << endl;
uniqueOrder(b, order);
Info<< "unsorted: " << list2 << endl;
uniqueOrder(list2, order);
Info<< "unique: " << order << endl;
duplicateOrder(b, order);
duplicateOrder(list2, order);
Info<< "duplicate:" << order << endl;
b.sort();
list2.sort();
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
printInfo(list2);
{
labelList tmp(orig);
Info<< nl << "move construct from List: " << tmp << endl;
SortableList<label> list3(std::move(tmp));
Info<< "input: " << tmp << endl;
printInfo(list3);
list3.reverseSort();
Info<< nl << "move construct from SortableList: " << list3 << endl;
SortableList<label> list4(std::move(list3));
Info<< "input: " << list3 << endl;
printInfo(list3);
printInfo(list4);
tmp = orig;
Info<< nl << "move assign from List: " << tmp << endl;
list3 = std::move(tmp);
Info<< "input: " << tmp << endl;
printInfo(list3);
Info<< nl << "move assign from SortableList: " << list3 << endl;
list4 = std::move(list3);
Info<< "input: " << list3 << endl;
printInfo(list3);
printInfo(list4);
labelList values;
Info<< "move to flat-list: " << list4 << endl;
values = std::move(list4);
Info<< "input: " << list4 << endl;
printInfo(list4);
Info<< "flat = " << values << endl;
}
Info<< "\nEnd\n" << endl;