diff --git a/applications/test/DynamicList/Test-DynamicList.C b/applications/test/DynamicList/Test-DynamicList.C index c8e2ed4a93be0d6b8b2a0b713463e2189da48ea9..ca3f4fc7872698db2367def5db70589de0f00c57 100644 --- a/applications/test/DynamicList/Test-DynamicList.C +++ b/applications/test/DynamicList/Test-DynamicList.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) 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"; diff --git a/applications/test/Field/Make/files b/applications/test/Field/Make/files deleted file mode 100644 index f8f0bb64df86a9a9b3046fe13eb7359d827096cc..0000000000000000000000000000000000000000 --- a/applications/test/Field/Make/files +++ /dev/null @@ -1,3 +0,0 @@ -Test-Field.C - -EXE = $(FOAM_USER_APPBIN)/Test-Field diff --git a/applications/test/Field/Make/options b/applications/test/Field/Make/options deleted file mode 100644 index 6a9e9810b3d5ce6684bdaf03143933480ff45e42..0000000000000000000000000000000000000000 --- a/applications/test/Field/Make/options +++ /dev/null @@ -1,2 +0,0 @@ -/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */ -/* EXE_LIBS = -lfiniteVolume */ diff --git a/applications/test/Field/Test-Field.C b/applications/test/Field/Test-Field.C deleted file mode 100644 index 2e037f6a34b607546c8f525e89664d1fac084178..0000000000000000000000000000000000000000 --- a/applications/test/Field/Test-Field.C +++ /dev/null @@ -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; -} diff --git a/applications/test/Field/Test-Field.H b/applications/test/Field/Test-Field.H deleted file mode 100644 index bd6929f838ea4bea957f3fdff28abf6463b4c3fa..0000000000000000000000000000000000000000 --- a/applications/test/Field/Test-Field.H +++ /dev/null @@ -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); -} diff --git a/applications/test/FixedList/Test-FixedList.C b/applications/test/FixedList/Test-FixedList.C index b057b43f2765880829328a6e1a2d54b19a3d6e8c..a06abee82f6a48a7d814704118b14a007784d53d 100644 --- a/applications/test/FixedList/Test-FixedList.C +++ b/applications/test/FixedList/Test-FixedList.C @@ -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; + { + FixedList<label, 4> list1{1, 2, 3, 4}; - Info<< "list:" << list - << " hash:" << FixedList<label, 4>::Hash<>()(list) << endl; + Info<< "list1:" << list1 + << " hash:" << FixedList<label, 4>::Hash<>()(list1) << endl; - label a[4] = {0, 1, 2, 3}; - FixedList<label, 4> list2(a); + label a[4] = {0, 1, 2, 3}; + FixedList<label, 4> list2(a); - Info<< "list2:" << list2 - << " hash:" << FixedList<label, 4>::Hash<>()(list2) << endl; + 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; - } + // 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<< "list: " << list << nl - << "list2: " << list2 << endl; - list.swap(list2); - Info<< "Swapped via the swap() method" << endl; - Info<< "list: " << list << nl - << "list2: " << list2 << 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()); diff --git a/applications/test/FixedList/fixedListFile b/applications/test/FixedList/fixedListFile deleted file mode 100644 index 4faae2f6aab9b12b7503643eb87c1756e9139d44..0000000000000000000000000000000000000000 Binary files a/applications/test/FixedList/fixedListFile and /dev/null differ diff --git a/applications/test/FixedList2/Make/files b/applications/test/FixedList2/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..548fa36bc5ee5fb3f587cdd58a4efe01dcdfc6f6 --- /dev/null +++ b/applications/test/FixedList2/Make/files @@ -0,0 +1,3 @@ +Test-FixedList2.C + +EXE = $(FOAM_USER_APPBIN)/Test-FixedList2 diff --git a/applications/test/FixedList2/Make/options b/applications/test/FixedList2/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/applications/test/FixedList2/Test-FixedList2.C b/applications/test/FixedList2/Test-FixedList2.C new file mode 100644 index 0000000000000000000000000000000000000000..efd3cfabdcb620153f2135317a4272553eaea008 --- /dev/null +++ b/applications/test/FixedList2/Test-FixedList2.C @@ -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; +} + + +// ************************************************************************* // diff --git a/applications/test/Function1/Test-Function1.C b/applications/test/Function1/Test-Function1.C index ab4baee1509f8dd10ac285939a2fb97e029f89f6..d1d3b1f073c4ddff57d2ba432ecf58ce21da1ef5 100644 --- a/applications/test/Function1/Test-Function1.C +++ b/applications/test/Function1/Test-Function1.C @@ -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; diff --git a/applications/test/HashSet/Test-hashSet.C b/applications/test/HashSet/Test-hashSet.C index 55640829fb2ea0c2aa01630194e5260144253310..781c6ceabdf7fc32a2d4e433212734f98c4bd72a 100644 --- a/applications/test/HashSet/Test-hashSet.C +++ b/applications/test/HashSet/Test-hashSet.C @@ -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; } diff --git a/applications/test/HashTable/Test-hashTable.C b/applications/test/HashTable/Test-hashTable.C index 1071b0a473af0b2040d711f79f13abb92f1e731c..f0017d4e5af3738a2ffbbe4e845c89985b142bb3 100644 --- a/applications/test/HashTable/Test-hashTable.C +++ b/applications/test/HashTable/Test-hashTable.C @@ -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; diff --git a/applications/test/IndirectList/Test-IndirectList.C b/applications/test/IndirectList/Test-IndirectList.C index 1af5a1682cff577a64c60175dbdd0c596dcc5f8d..4727ed52484299843af5648239a65488ba177fa9 100644 --- a/applications/test/IndirectList/Test-IndirectList.C +++ b/applications/test/IndirectList/Test-IndirectList.C @@ -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); diff --git a/applications/test/List/Test-List.C b/applications/test/List/Test-List.C index 5d3f3ba4b49c840ecf6b835b9b3b398a325a6767..990da8729f577fbe979028ac68f17272680d650c 100644 --- a/applications/test/List/Test-List.C +++ b/applications/test/List/Test-List.C @@ -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; diff --git a/applications/test/List2/Make/files b/applications/test/List2/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..49c6d304c831ccb19da834a0a0fa59a672f76c15 --- /dev/null +++ b/applications/test/List2/Make/files @@ -0,0 +1,3 @@ +Test-List2.C + +EXE = $(FOAM_USER_APPBIN)/Test-List2 diff --git a/applications/test/List2/Make/options b/applications/test/List2/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/applications/test/List2/Test-List2.C b/applications/test/List2/Test-List2.C new file mode 100644 index 0000000000000000000000000000000000000000..0be3acda63e53e3d3a996c8dbfd46837bd2527e7 --- /dev/null +++ b/applications/test/List2/Test-List2.C @@ -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; +} + + +// ************************************************************************* // diff --git a/applications/test/ListOps2/Make/files b/applications/test/ListOps2/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..4149f5146d32a8a4441868a903ad5a40adc991a6 --- /dev/null +++ b/applications/test/ListOps2/Make/files @@ -0,0 +1,2 @@ +Test-ListOps2.C +EXE = $(FOAM_USER_APPBIN)/Test-ListOps2 diff --git a/applications/test/ListOps2/Make/options b/applications/test/ListOps2/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..51903c0ce4fdd9fb77e67d8ae80beba4ea282cd3 --- /dev/null +++ b/applications/test/ListOps2/Make/options @@ -0,0 +1,3 @@ +EXE_INC = /*-DFULLDEBUG -O0 -g*/ \ + +EXE_LIBS = diff --git a/applications/test/ListOps2/Test-ListOps2.C b/applications/test/ListOps2/Test-ListOps2.C new file mode 100644 index 0000000000000000000000000000000000000000..e41ae9f893b42b5dcf48ecfc8b313cc0b4e782af --- /dev/null +++ b/applications/test/ListOps2/Test-ListOps2.C @@ -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; +} + + +// ************************************************************************* // diff --git a/applications/test/Map/Test-Map.C b/applications/test/Map/Test-Map.C index 5ced3b569d0953d70be8214269fd81912ba88b50..5ba38e9f60bed6decb46023385e2c19ba9a2fde9 100644 --- a/applications/test/Map/Test-Map.C +++ b/applications/test/Map/Test-Map.C @@ -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} + }; + + std::map<label, bool>::const_iterator stdmap1Iter = stdmap1.find(5); - if (STLbananaIter == STLbanana.end()) + 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; } diff --git a/applications/test/PackedList/Test-PackedList.C b/applications/test/PackedList/Test-PackedList.C index 90ed8ac740810c7669a892d355c13ed1580016c6..45d5ab00b6e8333a30cc181b2cfc4b508096696b 100644 --- a/applications/test/PackedList/Test-PackedList.C +++ b/applications/test/PackedList/Test-PackedList.C @@ -41,7 +41,7 @@ using namespace Foam; template<unsigned nBits> inline void reportInfo() { - unsigned offset = PackedList<nBits>::packing(); + const unsigned offset = PackedList<nBits>::packing(); unsigned useSHL = ((1u << (nBits * offset)) - 1); unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - nBits * offset)); diff --git a/applications/test/UIndirectList/Test-UIndirectList.C b/applications/test/UIndirectList/Test-UIndirectList.C index be78bbd16b3fb643a7c9730b31e705ed68b606c3..7749a2b18fcb44cf68fa218fe90108ce6ebbaa11 100644 --- a/applications/test/UIndirectList/Test-UIndirectList.C +++ b/applications/test/UIndirectList/Test-UIndirectList.C @@ -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; + + List<label> addresses{1, 0, 3, 7, 4, 8, 5, 1, 0, 3, 7, 4, 8, 5, }; + + labelUIndList idl1(completeList, addresses); - UIndirectList<double> idl(completeList, addresses); + printInfo(idl1); - Info<< idl << "\n"; + for (const label val : { 10, 30, 40, 50, 90, 80, 120 } ) + { + testFind(val, idl1); + } - idl[1] = -666; + Info<< flatOutput(idl1) << nl; - Info<< "idl[1] changed: " << idl << endl; + idl1[1] = -666; - idl = -999; + Info<< "idl1[1] changed: " << flatOutput(idl1) << endl; - Info<< "idl changed: " << idl << endl; + idl1 = -999; - UIndirectList<double> idl2(idl); + Info<< "idl1 changed: " << flatOutput(idl1) << endl; - Info<< "idl2: " << idl2 << 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; diff --git a/applications/test/sort/Test-sortList.C b/applications/test/sort/Test-sortList.C index d92a4a7ad429ba9d1ce16fb0759676e6ac8d24d5..1fbfcfcf39cd6b14e0f3b8e805bc0ce734e002ce 100644 --- a/applications/test/sort/Test-sortList.C +++ b/applications/test/sort/Test-sortList.C @@ -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; + Info<< "unsorted: " << orig << endl; + sort(list1); + Info<< "sorted: " << list1 << nl + << "indices: " << order << endl; - aReverse.reverseSort(); - Info<< "reverse sorted: " << aReverse << endl; - Info<< "reverse indices: " << aReverse.indices() << endl; + list1r.reverseSort(); + Info<< "reverse ..." << nl; + printInfo(list1r); - SortableList<label> b(orig); - Info<< "unsorted: " << orig << endl; - Info<< "sorted: " << b << endl; - Info<< "indices: " << b.indices() << endl; + SortableList<label> list2(orig); + Info<< "unsorted: " << orig << nl; + printInfo(list2); - Info<< "shrunk: " << b.shrink() << endl; - Info<< "indices: " << b.indices() << endl; + 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(); + + 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; - Info<< "sorted: " << b << endl; - Info<< "indices: " << b.indices() << endl; + values = std::move(list4); + Info<< "input: " << list4 << endl; + printInfo(list4); + Info<< "flat = " << values << endl; + } Info<< "\nEnd\n" << endl; diff --git a/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C b/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C index 6ad6dfcd433517e33648136f380ca720a883726c..0309bd6c7476579f629ae71c36c257ab6c590fc0 100644 --- a/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C +++ b/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C @@ -589,7 +589,8 @@ void readDOFS is.getLine(line); { IStringStream lineStr(line); - patchNames.append(lineStr); + word pName(lineStr); + patchNames.append(pName); } Info<< "For DOF set " << group diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C index d9bf097d1d6d7023a378ca7d53232c0391795e03..302bd61b55360b706d8ee68df909e1cc79fcb2c2 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellSizeControlSurfaces/surfaceCellSizeFunction/cellSizeCalculationType/automatic/automatic.C @@ -282,7 +282,7 @@ Foam::tmp<Foam::triSurfacePointScalarField> Foam::automatic::load() forAll(surface_, fI) { - faces[fI] = surface_.triSurface::operator[](fI).triFaceFace(); + faces[fI] = surface_.triSurface::operator[](fI); } vtkSurfaceWriter().write diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C index 410182e01c2a68cda0484476d507ed1731a60bfb..ac840a07f74b0b5497ddf80e07c9f2ca638000fd 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C +++ b/applications/utilities/mesh/generation/foamyMesh/foamyHexMeshBackgroundMesh/foamyHexMeshBackgroundMesh.C @@ -721,7 +721,7 @@ int main(int argc, char *argv[]) isoFaces.setSize(iso.size()); forAll(isoFaces, i) { - isoFaces[i] = iso[i].triFaceFace(); + isoFaces[i] = iso[i]; } isoPoints = iso.points(); } diff --git a/applications/utilities/surface/surfaceCheck/surfaceCheck.C b/applications/utilities/surface/surfaceCheck/surfaceCheck.C index 09765e2d938c992bef366978581a35327593a6e5..43812170e1fd72aae248bce61aa8dfcb66c669d3 100644 --- a/applications/utilities/surface/surfaceCheck/surfaceCheck.C +++ b/applications/utilities/surface/surfaceCheck/surfaceCheck.C @@ -150,7 +150,7 @@ void writeZoning faceList faces(surf.size()); forAll(surf, i) { - faces[i] = surf[i].triFaceFace(); + faces[i] = surf[i]; } vtkSurfaceWriter().write diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C index ca7cba62cc624f7425d00d43a5f925221ff54cd9..eb7103faf1eab2ab0ef3da0d9096d3829acb27af 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C @@ -368,7 +368,7 @@ int main(int argc, char *argv[]) faces.setSize(surf.size()); forAll(surf, fi) { - faces[fi] = surf[fi].triFaceFace(); + faces[fi] = surf[fi]; } } diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C index 5b1f45b8395a9cf7e57d1cf171bcfb645a7145d6..809adb795b35f704e6e6ee46dec24f4e31e677b0 100644 --- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C +++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C @@ -275,7 +275,16 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const HashSet<Key, Hash>& tbl) } -/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template<class Key, class Hash> +void Foam::Swap(const HashSet<Key, Hash>& a, const HashSet<Key, Hash>& b) +{ + a.swap(b); +} + + +/* * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * */ template<class Key, class Hash> Foam::HashSet<Key, Hash> diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H index fe82253bc0fb205411c9bc54e8493f4cffac0196..12aea8bea33fa79835928dc59d3a989b4bd0015a 100644 --- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H +++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H @@ -127,12 +127,18 @@ public: //- Construct from an initializer list of Key HashSet(std::initializer_list<Key> lst); - //- Construct as copy - HashSet(const HashSet<Key, Hash>& hs) + //- Copy construct + HashSet(const this_type& hs) : parent_type(hs) {} + //- Move construct + HashSet(this_type&& hs) + : + parent_type(std::move(hs)) + {} + //- Construct by transferring the parameter contents HashSet(const Xfer<HashSet<Key, Hash>>& hs) : @@ -284,6 +290,20 @@ public: //- Return true if the entry exists, same as found(). inline bool operator[](const Key& key) const; + using parent_type::operator=; + + //- Copy assignment + void operator=(const this_type& rhs) + { + parent_type::operator=(rhs); + } + + //- Move assignment + void operator=(this_type&& rhs) + { + parent_type::operator=(std::move(rhs)); + } + // Comparison @@ -340,6 +360,17 @@ public: }; +// Global Functions + +// Exchange contents of hash tables - see HashTable::swap(). +template<class T, class Key, class Hash> +inline void Swap +( + HashSet<Key, Hash>& a, + HashSet<Key, Hash>& b +); + + // Global Operators //- Combine entries from HashSets diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C index bc887b7d3b9217107ec495e432a52eaf569cf5ec..1f209ef350ec3c075ed0ed2ae7dc7a36dab472ab 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C @@ -93,6 +93,18 @@ Foam::HashTable<T, Key, Hash>::HashTable(const HashTable<T, Key, Hash>& ht) } +template<class T, class Key, class Hash> +Foam::HashTable<T, Key, Hash>::HashTable(HashTable<T, Key, Hash>&& ht) +: + HashTableCore(), + nElmts_(0), + tableSize_(0), + table_(nullptr) +{ + transfer(ht); +} + + template<class T, class Key, class Hash> Foam::HashTable<T, Key, Hash>::HashTable ( @@ -750,6 +762,15 @@ void Foam::HashTable<T, Key, Hash>::clearStorage() } +template<class T, class Key, class Hash> +void Foam::HashTable<T, Key, Hash>::swap(HashTable<T, Key, Hash>& ht) +{ + Foam::Swap(table_, ht.table_); + Foam::Swap(tableSize_, ht.tableSize_); + Foam::Swap(nElmts_, ht.nElmts_); +} + + template<class T, class Key, class Hash> void Foam::HashTable<T, Key, Hash>::transfer(HashTable<T, Key, Hash>& ht) { @@ -908,6 +929,24 @@ void Foam::HashTable<T, Key, Hash>::operator= } +template<class T, class Key, class Hash> +void Foam::HashTable<T, Key, Hash>::operator= +( + HashTable<T, Key, Hash>&& rhs +) +{ + // Check for assignment to self + if (this == &rhs) + { + FatalErrorInFunction + << "attempted assignment to self" + << abort(FatalError); + } + + transfer(rhs); +} + + template<class T, class Key, class Hash> bool Foam::HashTable<T, Key, Hash>::operator== ( diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H index cd50551d5d51405c2f8455f8edb226d84b0b22d8..aa848e475c4dc7d2dbc7fc942065bf066345edad 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H @@ -293,6 +293,9 @@ public: //- Construct as copy HashTable(const HashTable<T, Key, Hash>& ht); + //- Move construct + HashTable(HashTable<T, Key, Hash>&& ht); + //- Construct by transferring the parameter contents HashTable(const Xfer<HashTable<T, Key, Hash>>& ht); @@ -528,6 +531,9 @@ public: // Equivalent to clear() followed by resize(0) void clearStorage(); + //- Swap contents of the argument table into this table + void swap(HashTable<T, Key, Hash>& ht); + //- Transfer the contents of the argument table into this table // and annul the argument table. void transfer(HashTable<T, Key, Hash>& ht); @@ -561,6 +567,9 @@ public: //- Assignment from an initializer list void operator=(std::initializer_list<std::pair<Key, T>> lst); + //- Move assign + void operator=(HashTable<T, Key, Hash>&& rhs); + //- Equality. Hash tables are equal if the keys and values are equal. // Independent of table storage size and table order. bool operator==(const HashTable<T, Key, Hash>& rhs) const; @@ -841,6 +850,17 @@ public: }; +// Global Functions + +// Exchange contents of hash tables - see HashTable::swap(). +template<class T, class Key, class Hash> +inline void Swap +( + HashTable<T, Key, Hash>& a, + HashTable<T, Key, Hash>& b +); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H index 4d8028ca139e61ecd8a0d880d156e6888c199471..50f0c42d1e70c614947a836f8f4d81ca38c05fb9 100644 --- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H +++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H @@ -604,4 +604,17 @@ Foam::HashTable<T, Key, Hash>::cend() const } +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template<class T, class Key, class Hash> +inline void Foam::Swap +( + HashTable<T, Key, Hash>& a, + HashTable<T, Key, Hash>& b +) +{ + a.swap(b); +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/containers/HashTables/Map/Map.H b/src/OpenFOAM/containers/HashTables/Map/Map.H index 56f59128dd168c826b9b5c3e8d042ab3c68fc71a..e862ff97e394fb0d18464d5070ac2b42b6e6d872 100644 --- a/src/OpenFOAM/containers/HashTables/Map/Map.H +++ b/src/OpenFOAM/containers/HashTables/Map/Map.H @@ -77,14 +77,20 @@ public: parent_type(is) {} - //- Construct as copy - Map(const Map<T>& map) + //- Copy construct + Map(const this_type& map) : parent_type(map) {} + //- Move construct + Map(this_type&& map) + : + parent_type(std::move(map)) + {} + //- Construct by transferring the parameter contents - Map(const Xfer<Map<T>>& map) + Map(const Xfer<this_type>& map) : parent_type(map) {} @@ -100,6 +106,25 @@ public: : parent_type(map) {} + + + // Member Operators + + using parent_type::operator=; + + //- Copy assignment + void operator=(const this_type& rhs) + { + parent_type::operator=(rhs); + } + + //- Move assignment + void operator=(this_type&& rhs) + { + parent_type::operator=(std::move(rhs)); + } + + }; diff --git a/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectList.H b/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectList.H index 66bd1cb397ad5df63b41c48fafd96f9f521ebdb4..371a64b5baca0b4443b3a5d2aaec219372ac12fc 100644 --- a/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectList.H +++ b/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectList.H @@ -65,7 +65,7 @@ public: ( const UList<T>& posList, const UList<T>& negList, - const labelUList& + const labelUList& addr ); //- Construct given the complete list and by transferring addressing @@ -73,7 +73,7 @@ public: ( const UList<T>& posList, const UList<T>& negList, - const Xfer<List<label>>& + const Xfer<List<label>>& addr ); @@ -94,14 +94,14 @@ public: inline const List<label>& addressing() const; //- Calculate index given whether index is into posList or negList - inline static label posIndex(const label); - inline static label negIndex(const label); + inline static label posIndex(const label i); + inline static label negIndex(const label i); // Edit //- Reset addressing - inline void resetAddressing(const labelUList&); - inline void resetAddressing(const Xfer<List<label>>&); + inline void resetAddressing(const labelUList& addr); + inline void resetAddressing(const Xfer<List<label>>& addr); // Member Operators @@ -110,16 +110,16 @@ public: inline List<T> operator()() const; //- Return non-const access to an element - inline T& operator[](const label); + inline T& operator[](const label i); //- Return const access to an element - inline const T& operator[](const label) const; + inline const T& operator[](const label i) const; //- Assignment to UList of addressed elements - inline void operator=(const UList<T>&); + inline void operator=(const UList<T>& ae); //- Assignment of all entries to the given value - inline void operator=(const T&); + inline void operator=(const T& val); }; diff --git a/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectListI.H b/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectListI.H index 1f1dd4de5b3df3555f17cedef0f99d933f66c291..6b8a6c0b92e77c6f642d5fa82694b7d9301cf681 100644 --- a/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectListI.H +++ b/src/OpenFOAM/containers/Lists/BiIndirectList/BiIndirectListI.H @@ -23,6 +23,22 @@ License \*---------------------------------------------------------------------------*/ +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +template<class T> +inline Foam::label Foam::BiIndirectList<T>::posIndex(const label i) +{ + return i; +} + + +template<class T> +inline Foam::label Foam::BiIndirectList<T>::negIndex(const label i) +{ + return -i-1; +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class T> @@ -111,20 +127,6 @@ inline void Foam::BiIndirectList<T>::resetAddressing } -template<class T> -inline Foam::label Foam::BiIndirectList<T>::posIndex(const label i) -{ - return i; -} - - -template<class T> -inline Foam::label Foam::BiIndirectList<T>::negIndex(const label i) -{ - return -i-1; -} - - // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<class T> @@ -144,7 +146,7 @@ inline Foam::List<T> Foam::BiIndirectList<T>::operator()() const template<class T> inline T& Foam::BiIndirectList<T>::operator[](const label i) { - label index = addressing_[i]; + const label index = addressing_[i]; if (index >= 0) { @@ -160,7 +162,7 @@ inline T& Foam::BiIndirectList<T>::operator[](const label i) template<class T> inline const T& Foam::BiIndirectList<T>::operator[](const label i) const { - label index = addressing_[i]; + const label index = addressing_[i]; if (index >= 0) { @@ -193,11 +195,11 @@ inline void Foam::BiIndirectList<T>::operator=(const UList<T>& ae) template<class T> -inline void Foam::BiIndirectList<T>::operator=(const T& t) +inline void Foam::BiIndirectList<T>::operator=(const T& val) { forAll(addressing_, i) { - operator[](i) = t; + operator[](i) = val; } } diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C index 363d6d98e49353e2a60e68b3049c581e6cb8d461..deb5b1e7f02d7f10087325c825ec17a778832636 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,23 +24,83 @@ License \*---------------------------------------------------------------------------*/ #include "DynamicList.H" +#include "labelRange.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class T, int SizeMin> +Foam::label Foam::DynamicList<T, SizeMin>::removeElements +( + const labelRange& slice +) +{ + if (!slice.size()) + { + // Noop + return 0; + } + else if (slice.after() >= this->size()) + { + // Remove tail + this->resize(slice.first()); + } + else + { + // Copy (swap) down + label j = slice.first(); + const label len = this->size(); + + for (label i = slice.after(); i < len; ++i, ++j) + { + Foam::Swap(this->operator[](i), this->operator[](j)); + } + + resize(this->size() - slice.size()); + } + + return slice.size(); +} -// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // +template<class T, int SizeMin> +Foam::label Foam::DynamicList<T, SizeMin>::subsetElements +( + const labelRange& slice +) +{ + if (slice.first() > 0) + { + // Copy (swap) down + label j = slice.first(); + const label len = slice.size(); + + for (label i = 0; i < len; ++i, ++j) + { + Foam::Swap(this->operator[](i), this->operator[](j)); + } + } + + // Don't need min size, since slice size was already checked before + resize(slice.size()); + return this->size(); +} + + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList(Istream& is) +template<class T, int SizeMin> +Foam::DynamicList<T, SizeMin>::DynamicList(Istream& is) : List<T>(is), capacity_(List<T>::size()) {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> Foam::Ostream& Foam::operator<< ( Ostream& os, - const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + const DynamicList<T, SizeMin>& lst ) { os << static_cast<const List<T>&>(lst); @@ -48,11 +108,11 @@ Foam::Ostream& Foam::operator<< } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> Foam::Istream& Foam::operator>> ( Istream& is, - DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + DynamicList<T, SizeMin>& lst ) { is >> static_cast<List<T>&>(lst); diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H index 6c03173401e8566d01371df78e450a2d664ef060..4dae845ed31837266abf2a37664a6a0c58fc4ce6 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H @@ -52,21 +52,20 @@ namespace Foam { // Forward declaration of friend functions and operators +template<class T, int SizeMin> class DynamicList; -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -class DynamicList; - -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> Ostream& operator<< ( Ostream& os, - const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + const DynamicList<T, SizeMin>& lst ); -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> + +template<class T, int SizeMin> Istream& operator>> ( Istream& is, - DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + DynamicList<T, SizeMin>& lst ); @@ -74,22 +73,36 @@ Istream& operator>> Class DynamicList Declaration \*---------------------------------------------------------------------------*/ -template<class T, unsigned SizeInc=0, unsigned SizeMult=2, unsigned SizeDiv=1> +template<class T, int SizeMin = 16> class DynamicList : public List<T> { - static_assert - ( - (SizeInc || SizeMult) && SizeDiv, - "Invalid sizing parameters" - ); + static_assert(SizeMin > 0, "Invalid min size parameter"); // Private data //- The capacity (allocated size) of the underlying list. label capacity_; +private: + + // Private Member Functions + + //- Remove elements in range + label removeElements(const labelRange& slice); + + //- Subset elements in range + label subsetElements(const labelRange& slice); + + +protected: + + // Protected Member Functions + + //- Copy assignment from another list + template<class ListType> + inline void assignDynList(const ListType& lst); public: @@ -108,18 +121,26 @@ public: explicit inline DynamicList(const label nElem); //- Construct with given size and value for all elements. - inline DynamicList(const label nElem, const T& a); + inline DynamicList(const label nElem, const T& val); + + //- Construct with given size initializing all elements to zero + inline DynamicList(const label s, const zero); + + //- Copy construct. + inline DynamicList(const DynamicList<T, SizeMin>& lst); - //- Construct copy. - inline DynamicList - ( - const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst - ); + //- Copy construct from DynamicList with different sizing parameters + template<int AnySizeMin> + inline DynamicList(const DynamicList<T, AnySizeMin>& lst); //- Construct from UList. Size set to UList size. // Also constructs from DynamicList with different sizing parameters. explicit inline DynamicList(const UList<T>& lst); + //- Construct from a FixedList + template<unsigned FixedSize> + inline DynamicList(const FixedList<T, FixedSize>& lst); + //- Construct given begin/end iterators. // Uses std::distance to determine the size. template<class InputIterator> @@ -131,9 +152,18 @@ public: //- Construct from UIndirectList. Size set to UIndirectList size. explicit inline DynamicList(const UIndirectList<T>& lst); - //- Construct by transferring the parameter contents + //- Transfer (move) construct explicit inline DynamicList(const Xfer<List<T>>& lst); + //- Move construct. + inline DynamicList(DynamicList<T, SizeMin>&& lst); + + //- Move construct from List + inline DynamicList(List<T>&& lst); + + //- Move construct from SortableList + DynamicList(SortableList<T>&& lst); + //- Construct from Istream. Size set to size of list read. explicit DynamicList(Istream& is); @@ -153,25 +183,23 @@ public: // Use this or reserve() in combination with append(). inline void setCapacity(const label nElem); - //- Alter the addressed list size. + //- Alter addressable list size. // New space will be allocated if required. // Use this to resize the list prior to using the operator[] for // setting values (as per List usage). inline void setSize(const label nElem); - //- Alter the addressed list size and fill new space with a - // constant. - inline void setSize(const label nElem, const T& t); + //- Alter addressable list size and fill new space with constant. + inline void setSize(const label nElem, const T& val); - //- Alter the addressed list size. + //- Alter addressable list size. // New space will be allocated if required. // Use this to resize the list prior to using the operator[] for // setting values (as per List usage). inline void resize(const label nElem); - //- Alter the addressed list size and fill new space with a - // constant. - inline void resize(const label nElem, const T& t); + //- Alter addressable list size and fill new space with constant. + inline void resize(const label nElem, const T& val); //- Reserve allocation space for at least this size. // Never shrinks the allocated size, use setCapacity() for that. @@ -186,101 +214,162 @@ public: //- Shrink the allocated space to the number of elements used. // Returns a reference to the DynamicList. - inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& shrink(); + inline DynamicList<T, SizeMin>& shrink(); + + //- Swap content with any sized DynamicList + template<int AnySizeMin> + inline void swap(DynamicList<T, AnySizeMin>& lst); //- Transfer contents of the argument List into this. inline void transfer(List<T>& lst); - //- Transfer contents of the argument DynamicList into this. - inline void transfer - ( - DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst - ); + //- Transfer contents of any sized DynamicList into this. + template<int AnySizeMin> + inline void transfer(DynamicList<T, AnySizeMin>& lst); + + //- Transfer contents of the argument SortableList into this. + inline void transfer(SortableList<T>& lst); //- Transfer contents to the Xfer container as a plain List inline Xfer<List<T>> xfer(); - // Member Operators + //- Append an element to the end of this list. + inline DynamicList<T, SizeMin>& append(const T& val); - //- Append an element at the end of the list - inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append - ( - const T& t - ); + //- Append another list to the end of this list. + inline DynamicList<T, SizeMin>& append(const UList<T>& lst); - //- Append a List at the end of this list - inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append - ( - const UList<T>& lst - ); + //- Append a FixedList to the end of this list. + template<unsigned FixedSize> + inline DynamicList<T, SizeMin>& + append(const FixedList<T, FixedSize>& lst); //- Append an initializer list at the end of this list. - inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append - ( - std::initializer_list<T> lst - ); + inline DynamicList<T, SizeMin>& + append(std::initializer_list<T> lst); //- Append a UIndirectList at the end of this list - inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append - ( - const UIndirectList<T>& lst - ); + inline DynamicList<T, SizeMin>& + append(const UIndirectList<T>& lst); + + //- Move append list + inline DynamicList<T, SizeMin>& append(List<T>&& lst); + + //- Move append list + inline DynamicList<T, SizeMin>& + append(DynamicList<T, SizeMin>&& lst); + + //- Move append list + template<int AnySizeMin> + inline DynamicList<T, SizeMin>& + append(DynamicList<T, AnySizeMin>&& lst); - //- Remove and return the top element + //- Move append list + inline DynamicList<T, SizeMin>& + append(SortableList<T>&& lst); + + //- Remove and return the last element. Fatal on an empty list. inline T remove(); + //- Remove and return the specified element. Fatal on an empty list. + // With fast=true (operates in constant time), the place of the + // removed element is swapped with the last one in the list, which + // changes the ordering. + // With fast=false (operates in linear time), the elements + // are swapped down in the list to preserve ordering. + inline T remove(const label idx, const bool fast=false); + + //- Remove a (start,size) subset from the list. + // The range is subsetted with the list size itself to ensure + // result always addresses a valid section of the list. + // Remaining elements are moved down. + inline label remove(const labelRange& range); + + //- Remove a (start,size) subset from the list. + inline label remove(std::initializer_list<label> start_size); + + //- Retain a (start,size) subset from the list. + // The range is subsetted with the list size itself to ensure + // result always addresses a valid section of the list. + // Remaining elements are moved down. + inline label subset(const labelRange& range); + + //- Retain a (start,size) subset from List. + inline label subset(std::initializer_list<label> start_size); + + + // Member Operators + //- Return non-const access to an element, resizing list if // necessary inline T& operator()(const label elemI); //- Assignment of all addressed entries to the given value - inline void operator=(const T& t); + inline void operator=(const T& val); - //- Assignment to DynamicList - inline void operator= - ( - const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst - ); + //- Assignment of all entries to zero + inline void operator=(const zero); //- Assignment to UList inline void operator=(const UList<T>& lst); + //- Assignment to FixedList + template<unsigned FixedSize> + inline void operator=(const FixedList<T, FixedSize>& lst); + + //- Assignment to DynamicList + inline void operator=(const DynamicList<T, SizeMin>& lst); + + //- Assignment from DynamicList with different sizing parameters + template<int AnySizeMin> + inline void operator=(const DynamicList<T, AnySizeMin>& lst); + //- Assignment from initializer list inline void operator=(std::initializer_list<T> lst); //- Assignment to UIndirectList inline void operator=(const UIndirectList<T>& lst); + //- Move assignment + inline void operator=(List<T>&& lst); - // STL member functions + //- Move assignment + inline void operator=(DynamicList<T, SizeMin>&& lst); - //- Erase an element, move the remaining elements to fill the gap - // and resize the List - typename UList<T>::iterator erase - ( - typename UList<T>::iterator curIter - ); + //- Move assignment + template<int AnySizeMin> + inline void operator=(DynamicList<T, AnySizeMin>&& lst); + + //- Move assignment + inline void operator=(SortableList<T>&& lst); // IOstream operators // Write DynamicList to Ostream. - friend Ostream& operator<< <T, SizeInc, SizeMult, SizeDiv> + friend Ostream& operator<< <T, SizeMin> ( Ostream& os, - const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + const DynamicList<T, SizeMin>& lst ); //- Read from Istream, discarding contents of existing DynamicList. - friend Istream& operator>> <T, SizeInc, SizeMult, SizeDiv> + friend Istream& operator>> <T, SizeMin> ( Istream& is, - DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + DynamicList<T, SizeMin>& lst ); }; +// Global Functions + +// Exchange contents of lists - see DynamicList::swap(). +template<class T, int SizeMin1, int SizeMin2> +inline void Swap(DynamicList<T, SizeMin1>& a, DynamicList<T, SizeMin2>& b); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H index e6ba973b48af96f1b5e83c46215745805f1dc588..a41f284f63999663585082f5bbe33725052732ab 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -23,17 +23,47 @@ License \*---------------------------------------------------------------------------*/ +#include "FixedList.H" + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +template<class T, int SizeMin> +template<class ListType> +inline void Foam::DynamicList<T, SizeMin>::assignDynList +( + const ListType& lst +) +{ + const label newSize = lst.size(); + + if (capacity_ >= newSize) + { + // Can copy w/o reallocating - adjust addressable size accordingly. + List<T>::size(newSize); + List<T>::operator=(lst); + } + else + { + // Ensure list size consistency prior to copying. + List<T>::size(capacity_); + + List<T>::operator=(lst); + capacity_ = List<T>::size(); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList() +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList() : capacity_(0) {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList ( const label nElem ) @@ -41,27 +71,52 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList List<T>(nElem), capacity_(nElem) { - // We could also enforce SizeInc granularity when (!SizeMult || !SizeDiv) + // We could also enforce sizing granularity + List<T>::size(0); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList +( + const label nElem, + const T& val +) +: + List<T>(nElem, val), + capacity_(nElem) +{} + + +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList ( const label nElem, - const T& a + const zero ) : - List<T>(nElem, a), + List<T>(nElem, Zero), capacity_(nElem) {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList +( + const DynamicList<T, SizeMin>& lst +) +: + List<T>(lst), + capacity_(lst.size()) +{} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList ( - const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + const DynamicList<T, AnySizeMin>& lst ) : List<T>(lst), @@ -69,8 +124,8 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList ( const UList<T>& lst ) @@ -80,9 +135,22 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> +template<unsigned FixedSize> +inline Foam::DynamicList<T, SizeMin>::DynamicList +( + const FixedList<T, FixedSize>& lst +) +: + capacity_(0) +{ + this->operator=(lst); +} + + +template<class T, int SizeMin> template<class InputIterator> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +inline Foam::DynamicList<T, SizeMin>::DynamicList ( InputIterator begIter, InputIterator endIter @@ -93,8 +161,8 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList ( std::initializer_list<T> lst ) @@ -104,8 +172,8 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList ( const UIndirectList<T>& lst ) @@ -115,8 +183,8 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList ( const Xfer<List<T>>& lst ) @@ -126,19 +194,42 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList {} +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList +( + DynamicList<T, SizeMin>&& lst +) +: + capacity_(0) +{ + transfer(lst); +} + + +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>::DynamicList +( + List<T>&& lst +) +: + capacity_(0) +{ + transfer(lst); +} + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::label Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::capacity() +template<class T, int SizeMin> +inline Foam::label Foam::DynamicList<T, SizeMin>::capacity() const { return capacity_; } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::setCapacity ( const label nElem ) @@ -152,15 +243,15 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity nextFree = capacity_; } - // We could also enforce SizeInc granularity when (!SizeMult || !SizeDiv) + // We could also enforce sizing granularity List<T>::setSize(capacity_); List<T>::size(nextFree); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::reserve +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::reserve ( const label nElem ) @@ -170,20 +261,25 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::reserve { capacity_ = max ( - nElem, - label(SizeInc + capacity_ * SizeMult / SizeDiv) + SizeMin, + max + ( + nElem, + // label(SizeInc + capacity_ * SizeMult / SizeDiv) + label(2 * capacity_) + ) ); // Adjust allocated size, leave addressed size untouched - label nextFree = List<T>::size(); + const label nextFree = List<T>::size(); List<T>::setSize(capacity_); List<T>::size(nextFree); } } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::setSize ( const label nElem ) @@ -193,8 +289,13 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize { capacity_ = max ( - nElem, - label(SizeInc + capacity_ * SizeMult / SizeDiv) + SizeMin, + max + ( + nElem, + // label(SizeInc + capacity_ * SizeMult / SizeDiv) + label(2 * capacity_) + ) ); List<T>::setSize(capacity_); @@ -205,11 +306,11 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::setSize ( const label nElem, - const T& t + const T& val ) { label nextFree = List<T>::size(); @@ -218,13 +319,13 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize // Set new elements to constant value while (nextFree < nElem) { - this->operator[](nextFree++) = t; + this->operator[](nextFree++) = val; } } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::resize ( const label nElem ) @@ -233,37 +334,37 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::resize +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::resize ( const label nElem, - const T& t + const T& val ) { - this->setSize(nElem, t); + this->setSize(nElem, val); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clear() +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::clear() { List<T>::size(0); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clearStorage() +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::clearStorage() { List<T>::clear(); capacity_ = 0; } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink() +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::shrink() { - label nextFree = List<T>::size(); + const label nextFree = List<T>::size(); if (capacity_ > nextFree) { // Use the full list when resizing @@ -278,9 +379,21 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink() } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> +template<int AnySizeMin> +inline void Foam::DynamicList<T, SizeMin>::swap +( + DynamicList<T, AnySizeMin>& lst +) +{ + Foam::Swap(static_cast<UList<T>&>(*this), static_cast<UList<T>&>(lst)); + Foam::Swap(capacity_, lst.capacity_); +} + + +template<class T, int SizeMin> inline void -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& lst) +Foam::DynamicList<T, SizeMin>::transfer(List<T>& lst) { // Take over storage, clear addressing for lst. capacity_ = lst.size(); @@ -288,11 +401,12 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& lst) } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> +template<int AnySizeMin> inline void -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer +Foam::DynamicList<T, SizeMin>::transfer ( - DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + DynamicList<T, AnySizeMin>& lst ) { // Take over storage as-is (without shrink), clear addressing for lst. @@ -302,32 +416,45 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> +inline void +Foam::DynamicList<T, SizeMin>::transfer +( + SortableList<T>& lst +) +{ + lst.shrink(); // Shrink away sort indices + capacity_ = lst.size(); // Capacity after transfer == list size + List<T>::transfer(lst); +} + + +template<class T, int SizeMin> inline Foam::Xfer<Foam::List<T>> -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::xfer() +Foam::DynamicList<T, SizeMin>::xfer() { return xferMoveTo<List<T>>(*this); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append ( - const T& t + const T& val ) { - const label elemI = List<T>::size(); - setSize(elemI + 1); + const label idx = List<T>::size(); + setSize(idx + 1); - this->operator[](elemI) = t; + this->operator[](idx) = val; return *this; } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append ( const UList<T>& lst ) @@ -341,17 +468,36 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append label nextFree = List<T>::size(); setSize(nextFree + lst.size()); - forAll(lst, elemI) + for (const T& val : lst) { - this->operator[](nextFree++) = lst[elemI]; + this->operator[](nextFree++) = val; + } + return *this; +} + + +template<class T, int SizeMin> +template<unsigned FixedSize> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append +( + const FixedList<T, FixedSize>& lst +) +{ + label nextFree = List<T>::size(); + setSize(nextFree + lst.size()); + + for (const T& val : lst) + { + this->operator[](nextFree++) = val; } return *this; } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append ( std::initializer_list<T> lst ) @@ -367,9 +513,9 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append ( const UIndirectList<T>& lst ) @@ -385,29 +531,159 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline T Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove() +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append +( + List<T>&& lst +) +{ + if (this == &lst) + { + FatalErrorInFunction + << "Attempted appending to self" << abort(FatalError); + } + + label nextFree = List<T>::size(); + setSize(nextFree + lst.size()); + + for (T& val : lst) + { + Foam::Swap(this->operator[](nextFree++), val); + } + + lst.clear(); + return *this; +} + + +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append +( + DynamicList<T, SizeMin>&& lst +) +{ + append(std::move(static_cast<List<T>&>(lst))); + lst.clearStorage(); // Ensure capacity=0 too + return *this; +} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append +( + DynamicList<T, AnySizeMin>&& lst +) +{ + append(std::move(static_cast<List<T>&>(lst))); + lst.clearStorage(); // Ensure capacity=0 too + return *this; +} + + +template<class T, int SizeMin> +inline Foam::DynamicList<T, SizeMin>& +Foam::DynamicList<T, SizeMin>::append +( + SortableList<T>&& lst +) +{ + lst.shrink(); // Shrink away sort indices + append(std::move(static_cast<List<T>&>(lst))); + return *this; +} + + +template<class T, int SizeMin> +inline T Foam::DynamicList<T, SizeMin>::remove() { - const label elemI = List<T>::size() - 1; + // Location of last element and simultaneously the new size + const label idx = List<T>::size() - 1; - if (elemI < 0) + if (idx < 0) { FatalErrorInFunction << "List is empty" << abort(FatalError); } - const T& val = List<T>::operator[](elemI); + const T& val = List<T>::operator[](idx); - List<T>::size(elemI); + List<T>::size(idx); return val; } +template<class T, int SizeMin> +inline T Foam::DynamicList<T, SizeMin>::remove +( + const label idx, + const bool fast +) +{ + if (fast) + { + // Simply swap idx <=> last + this->swapLast(idx); + } + else + { + // Move element to the end and move everything down + this->moveLast(idx); + } + + // Element to remove is now at the end + return this->remove(); +} + + +template<class T, int SizeMin> +inline Foam::label Foam::DynamicList<T, SizeMin>::remove +( + const labelRange& range +) +{ + return this->removeElements(this->validateRange(range)); +} + + +template<class T, int SizeMin> +inline Foam::label Foam::DynamicList<T, SizeMin>::remove +( + std::initializer_list<label> start_size +) +{ + return this->removeElements(this->validateRange(start_size)); +} + + +template<class T, int SizeMin> +inline Foam::label Foam::DynamicList<T, SizeMin>::subset +( + const labelRange& range +) +{ + return this->subsetElements(this->validateRange(range)); +} + + +template<class T, int SizeMin> +inline Foam::label Foam::DynamicList<T, SizeMin>::subset +( + std::initializer_list<label> start_size +) +{ + return this->subsetElements(this->validateRange(start_size)); +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator() +template<class T, int SizeMin> +inline T& Foam::DynamicList<T, SizeMin>::operator() ( const label elemI ) @@ -421,139 +697,156 @@ inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator() } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= ( - const T& t + const T& val ) { - UList<T>::operator=(t); + UList<T>::operator=(val); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= ( - const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst + const zero ) { - if (this == &lst) - { - FatalErrorInFunction - << "Attempted assignment to self" << abort(FatalError); - } + UList<T>::operator=(Zero); +} - if (capacity_ >= lst.size()) - { - // Can copy w/o reallocating, match initial size to avoid reallocation - List<T>::size(lst.size()); - List<T>::operator=(lst); - } - else - { - // Make everything available for the copy operation - List<T>::size(capacity_); - List<T>::operator=(lst); - capacity_ = List<T>::size(); - } +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= +( + const UList<T>& lst +) +{ + assignDynList(lst); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +template<unsigned FixedSize> +inline void Foam::DynamicList<T, SizeMin>::operator= ( - const UList<T>& lst + const FixedList<T, FixedSize>& lst ) { - if (capacity_ >= lst.size()) - { - // Can copy w/o reallocating, match initial size to avoid reallocation - List<T>::size(lst.size()); - List<T>::operator=(lst); - } - else - { - // Make everything available for the copy operation - List<T>::size(capacity_); + setSize(lst.size()); - List<T>::operator=(lst); - capacity_ = List<T>::size(); + forAll(lst, i) + { + this->operator[](i) = lst[i]; } } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= ( - std::initializer_list<T> lst + const DynamicList<T, SizeMin>& lst ) { - if (capacity_ >= lst.size()) + if (this == &lst) { - // Can copy w/o reallocating, match initial size to avoid reallocation - List<T>::size(lst.size()); - List<T>::operator=(lst); + FatalErrorInFunction + << "Attempted assignment to self" << abort(FatalError); } - else - { - // Make everything available for the copy operation - List<T>::size(capacity_); - List<T>::operator=(lst); - capacity_ = List<T>::size(); - } + assignDynList(lst); +} + + +template<class T, int SizeMin> +template<int SizeMin2> +inline void Foam::DynamicList<T, SizeMin>::operator= +( + const DynamicList<T, SizeMin2>& lst +) +{ + assignDynList(lst); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= +( + std::initializer_list<T> lst +) +{ + assignDynList(lst); +} + + +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= ( const UIndirectList<T>& lst ) { - if (capacity_ >= lst.size()) + assignDynList(lst); +} + + +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= +( + List<T>&& lst +) +{ + clear(); + transfer(lst); +} + + +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= +( + DynamicList<T, SizeMin>&& lst +) +{ + if (this == &lst) { - // Can copy w/o reallocating, match initial size to avoid reallocation - List<T>::size(lst.size()); - List<T>::operator=(lst); + FatalErrorInFunction + << "Attempted assignment to self" << abort(FatalError); } - else - { - // Make everything available for the copy operation - List<T>::size(capacity_); - List<T>::operator=(lst); - capacity_ = List<T>::size(); - } + clear(); + transfer(lst); } -// * * * * * * * * * * * * * * STL Member Functions * * * * * * * * * * * * // - -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -typename Foam::UList<T>::iterator -Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::erase +template<class T, int SizeMin> +template<int SizeMin2> +inline void Foam::DynamicList<T, SizeMin>::operator= ( - typename UList<T>::iterator curIter + DynamicList<T, SizeMin2>&& lst ) { - typename Foam::UList<T>::iterator iter = curIter; - typename Foam::UList<T>::iterator nextIter = curIter; + clear(); + transfer(lst); +} - if (iter != this->end()) - { - ++iter; - while (iter != this->end()) - { - *nextIter++ = *iter++; - } +template<class T, int SizeMin> +inline void Foam::DynamicList<T, SizeMin>::operator= +( + SortableList<T>&& lst +) +{ + clear(); + transfer(lst); +} - this->setSize(this->size() - 1); - } - return curIter; +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template<class T, int SizeMin1, int SizeMin2> +inline void Foam::Swap(DynamicList<T, SizeMin1>& a, DynamicList<T, SizeMin2>& b) +{ + a.swap(b); } diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C index 03c3d1676811d0ca915ef6672ad0322ef99e8dab..2a10efe4116ad07673afde138ab08ec778c8b188 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,19 +26,86 @@ License #include "FixedList.H" #include "ListLoopM.H" -// * * * * * * * * * * * * * * STL Member Functions * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class T, unsigned Size> -void Foam::FixedList<T, Size>::swap(FixedList<T, Size>& a) +Foam::label Foam::FixedList<T, Size>::find +( + const T& val, + const label start +) const { - List_ACCESS(T, (*this), vp); - List_ACCESS(T, a, ap); - T tmp; - List_FOR_ALL((*this), i) - tmp = List_CELEM((*this), vp, i); - List_ELEM((*this), vp, i) = List_CELEM(a, ap, i); - List_ELEM(a, ap, i) = tmp; - List_END_FOR_ALL + if (start >= 0) + { + List_CONST_ACCESS(T, *this, lst); + + for (label i = start; i < label(Size); ++i) + { + if (lst[i] == val) + { + return i; + } + } + } + + return -1; +} + + +template<class T, unsigned Size> +void Foam::FixedList<T, Size>::swap(FixedList<T, Size>& lst) +{ + Foam::Swap(v_, lst.v_); +} + + +template<class T, unsigned Size> +void Foam::FixedList<T, Size>::moveFirst(const label i) +{ + checkIndex(i); + + for (label lower = 0; lower < i; ++lower) + { + Foam::Swap(v_[lower], v_[i]); + } +} + + +template<class T, unsigned Size> +void Foam::FixedList<T, Size>::moveLast(const label i) +{ + checkIndex(i); + + for (label upper = label(Size - 1); upper > i; --upper) + { + Foam::Swap(v_[i], v_[upper]); + } +} + + +template<class T, unsigned Size> +void Foam::FixedList<T, Size>::swapFirst(const label i) +{ + checkIndex(i); + + if (i > 0) + { + Foam::Swap(v_[0], v_[i]); + } +} + + +template<class T, unsigned Size> +void Foam::FixedList<T, Size>::swapLast(const label i) +{ + checkIndex(i); + + const label upper = label(Size - 1); + + if (i < upper) + { + Foam::Swap(v_[i], v_[upper]); + } } @@ -52,10 +119,11 @@ bool Foam::FixedList<T, Size>::operator==(const FixedList<T, Size>& a) const List_CONST_ACCESS(T, (*this), vp); List_CONST_ACCESS(T, (a), ap); - List_FOR_ALL((*this), i) - equal = (List_ELEM((*this), vp, i) == List_ELEM((a), ap, i)); + for (unsigned i = 0; i < Size; ++i) + { + equal = (vp[i] == ap[i]); if (!equal) break; - List_END_FOR_ALL + } return equal; } @@ -71,8 +139,8 @@ bool Foam::FixedList<T, Size>::operator!=(const FixedList<T, Size>& a) const template<class T, unsigned Size> bool Foam::FixedList<T, Size>::operator<(const FixedList<T, Size>& a) const { - const T* const __restrict__ ptr1 = this->begin(); - const T* const __restrict__ ptr2 = a.begin(); + List_CONST_ACCESS(T, *this, ptr1); + List_CONST_ACCESS(T, a, ptr2); for (unsigned i=0; i<Size; ++i) { diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H index dce2cad0c63a23bd6c797d67d630fc31702584e6..8db0275bd4d529a413f36a8ce1d7bff1591e7cef 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H @@ -42,6 +42,8 @@ SourceFiles #include "uLabel.H" #include "Hash.H" #include "autoPtr.H" +#include "Swap.H" + #include <type_traits> #include <initializer_list> @@ -125,11 +127,17 @@ public: inline FixedList(); //- Construct from value - explicit inline FixedList(const T& t); + explicit inline FixedList(const T& val); //- Construct from C-array explicit inline FixedList(const T lst[Size]); + //- Copy constructor + inline FixedList(const FixedList<T, Size>& lst); + + //- Move constructor + inline FixedList(FixedList<T, Size>&& lst); + //- Construct given begin/end iterators // Uses std::distance when verifying the size. template<class InputIterator> @@ -144,9 +152,6 @@ public: //- Construct from SLList explicit inline FixedList(const SLList<T>& lst); - //- Copy constructor - inline FixedList(const FixedList<T, Size>& lst); - //- Construct from Istream FixedList(Istream& is); @@ -158,14 +163,26 @@ public: // Access - //- Return the forward circular index, i.e. the next index + //- Return the forward circular index, i.e. next index // which returns to the first at the end of the list inline label fcIndex(const label i) const; - //- Return the reverse circular index, i.e. the previous index + //- Return forward circular value (ie, next value in the list) + inline const T& fcValue(const label i) const; + + //- Return forward circular value (ie, next value in the list) + inline T& fcValue(const label i); + + //- Return the reverse circular index, i.e. previous index // which returns to the last at the beginning of the list inline label rcIndex(const label i) const; + //- Return reverse circular value (ie, previous value in the list) + inline const T& rcValue(const label i) const; + + //- Return reverse circular value (ie, previous value in the list) + inline T& rcValue(const label i); + //- Return a const pointer to the first data element, // similar to the STL front() method and the string::data() method @@ -202,19 +219,42 @@ public: inline void checkIndex(const label i) const; + // Search + + //- Find index of the first occurence of the value. + // Linear search. + // \return -1 if not found. + label find(const T& val, const label start=0) const; + + //- True if the value if found in the list. Linear search. + inline bool found(const T& val, const label start=0) const; + + // Edit - //- Dummy resize function - // needed to make FixedList consistent with List - inline void resize(const label s); + //- Dummy resize function + // needed to make FixedList consistent with List + inline void resize(const label s); + + //- Dummy setSize function + // needed to make FixedList consistent with List + inline void setSize(const label s); + + //- Move element to the first position. + void moveFirst(const label i); + + //- Move element to the last position. + void moveLast(const label i); + + //- Swap element with the first element. Fatal on an empty list. + void swapFirst(const label i); - //- Dummy setSize function - // needed to make FixedList consistent with List - inline void setSize(const label s); + //- Swap element with the last element. Fatal on an empty list. + void swapLast(const label i); - //- Copy (not transfer) the argument contents - // needed to make FixedList consistent with List - void transfer(const FixedList<T, Size>& lst); + //- Copy (not transfer) the argument contents + // needed to make FixedList consistent with List + void transfer(const FixedList<T, Size>& lst); // Member operators @@ -238,7 +278,13 @@ public: inline void operator=(std::initializer_list<T> lst); //- Assignment of all entries to the given value - inline void operator=(const T& t); + inline void operator=(const T& val); + + //- Copy assignment + inline void operator=(const FixedList<T, Size>& lst); + + //- Move assignment + inline void operator=(FixedList<T, Size>&& lst); // STL type definitions @@ -333,14 +379,14 @@ public: //- Always false since zero-sized FixedList is compile-time disabled. inline bool empty() const; - //- Swap two FixedLists of the same type in constant time - void swap(FixedList<T, Size>& a); + //- Swap content with another FixedList of the same type. + void swap(FixedList<T, Size>& lst); // STL member operators //- Equality operation on FixedLists of the same type. - // Returns true when the FixedLists are elementwise equal + // Returns true when the FixedLists are element-wise equal // (using FixedList::value_type::operator==). Takes linear time bool operator==(const FixedList<T, Size>& a) const; @@ -388,6 +434,13 @@ public: }; +// Global Functions + +// Exchange contents of lists - see FixedList::swap(). +template<class T, unsigned Size> +inline void Swap(FixedList<T,Size>& a, FixedList<T,Size>& b); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H index 1df4fb958a0ba6bf8d3c4c9b813e51072794e946..c9554231f451dec9691c9b50f7db1a483f168a9e 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H @@ -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,6 +27,9 @@ License #include "SLList.H" #include "contiguous.H" +#include <type_traits> +#include <utility> + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class T, unsigned Size> @@ -35,11 +38,11 @@ inline Foam::FixedList<T, Size>::FixedList() template<class T, unsigned Size> -inline Foam::FixedList<T, Size>::FixedList(const T& t) +inline Foam::FixedList<T, Size>::FixedList(const T& val) { for (unsigned i=0; i<Size; ++i) { - v_[i] = t; + v_[i] = val; } } @@ -54,6 +57,29 @@ inline Foam::FixedList<T, Size>::FixedList(const T lst[Size]) } +template<class T, unsigned Size> +inline Foam::FixedList<T, Size>::FixedList(const FixedList<T, Size>& lst) +{ + for (unsigned i=0; i<Size; ++i) + { + v_[i] = lst[i]; + } +} + + +template<class T, unsigned Size> +inline Foam::FixedList<T, Size>::FixedList(FixedList<T, Size>&& lst) +{ + // No significant speedup observed for copy assignment on simple types, + // use move assignment for generality with more complex types + + for (unsigned i=0; i<Size; ++i) + { + v_[i] = std::move(lst.v_[i]); + } +} + + template<class T, unsigned Size> template<class InputIterator> Foam::FixedList<T, Size>::FixedList @@ -113,16 +139,6 @@ inline Foam::FixedList<T, Size>::FixedList(const SLList<T>& lst) } -template<class T, unsigned Size> -inline Foam::FixedList<T, Size>::FixedList(const FixedList<T, Size>& lst) -{ - for (unsigned i=0; i<Size; ++i) - { - v_[i] = lst[i]; - } -} - - template<class T, unsigned Size> inline Foam::autoPtr<Foam::FixedList<T, Size>> Foam::FixedList<T, Size>::clone() const @@ -147,6 +163,20 @@ inline Foam::label Foam::FixedList<T, Size>::fcIndex(const label i) const } +template<class T, unsigned Size> +inline const T& Foam::FixedList<T, Size>::fcValue(const label i) const +{ + return this->operator[](this->fcIndex(i)); +} + + +template<class T, unsigned Size> +inline T& Foam::FixedList<T, Size>::fcValue(const label i) +{ + return this->operator[](this->fcIndex(i)); +} + + template<class T, unsigned Size> inline Foam::label Foam::FixedList<T, Size>::rcIndex(const label i) const { @@ -154,6 +184,20 @@ inline Foam::label Foam::FixedList<T, Size>::rcIndex(const label i) const } +template<class T, unsigned Size> +inline const T& Foam::FixedList<T, Size>::rcValue(const label i) const +{ + return this->operator[](this->rcIndex(i)); +} + + +template<class T, unsigned Size> +inline T& Foam::FixedList<T, Size>::rcValue(const label i) +{ + return this->operator[](this->rcIndex(i)); +} + + template<class T, unsigned Size> inline void Foam::FixedList<T, Size>::checkStart(const label start) const { @@ -190,6 +234,17 @@ inline void Foam::FixedList<T, Size>::checkIndex(const label i) const } +template<class T, unsigned Size> +inline bool Foam::FixedList<T, Size>::found +( + const T& val, + const label start +) const +{ + return (this->find(val, start) >= 0); +} + + template<class T, unsigned Size> inline void Foam::FixedList<T, Size>::resize(const label s) { @@ -206,6 +261,7 @@ inline void Foam::FixedList<T, Size>::setSize(const label s) #endif } + template<class T, unsigned Size> inline void Foam::FixedList<T, Size>::transfer(const FixedList<T, Size>& lst) { @@ -329,11 +385,31 @@ inline void Foam::FixedList<T, Size>::operator=(std::initializer_list<T> lst) } template<class T, unsigned Size> -inline void Foam::FixedList<T, Size>::operator=(const T& t) +inline void Foam::FixedList<T, Size>::operator=(const T& val) { for (unsigned i=0; i<Size; ++i) { - v_[i] = t; + v_[i] = val; + } +} + +template<class T, unsigned Size> +inline void Foam::FixedList<T, Size>::operator=(const FixedList<T, Size>& lst) +{ + for (unsigned i=0; i<Size; ++i) + { + v_[i] = lst.v_[i]; + } +} + +template<class T, unsigned Size> +inline void Foam::FixedList<T, Size>::operator=(FixedList<T, Size>&& lst) +{ + // No significant speedup observed for copy assignment on simple types, + // use move assignment for generality with more complex types + for (unsigned i=0; i<Size; ++i) + { + v_[i] = std::move(lst.v_[i]); } } @@ -485,4 +561,13 @@ inline unsigned Foam::FixedList<T, Size>::Hash<HashT>::operator() } +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template<class T, unsigned Size> +void Foam::Swap(FixedList<T, Size>& a, FixedList<T, Size>& b) +{ + a.swap(b); +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/IndirectList/IndirectList.H b/src/OpenFOAM/containers/Lists/IndirectList/IndirectList.H index a320682a60eacd62c713ad3da056f4458d8960aa..aa6c222ec262ba80be29e1aad69e7cda15c89f35 100644 --- a/src/OpenFOAM/containers/Lists/IndirectList/IndirectList.H +++ b/src/OpenFOAM/containers/Lists/IndirectList/IndirectList.H @@ -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. @@ -62,10 +62,10 @@ class IndirectListAddressing // Private Member Functions //- Disallow default bitwise copy construct - IndirectListAddressing(const IndirectListAddressing&); + IndirectListAddressing(const IndirectListAddressing&) = delete; //- Disallow default bitwise assignment - void operator=(const IndirectListAddressing&); + void operator=(const IndirectListAddressing&) = delete; protected: @@ -81,16 +81,16 @@ protected: // Member Functions - // Access + // Access - //- Return the list addressing - inline const List<label>& addressing() const; + //- Return the list addressing + inline const List<label>& addressing() const; - // Edit + // Edit - //- Reset addressing - inline void resetAddressing(const labelUList&); - inline void resetAddressing(const Xfer<List<label>>&); + //- Reset addressing + inline void resetAddressing(const labelUList& addr); + inline void resetAddressing(const Xfer<List<label>>& addr); }; @@ -108,10 +108,10 @@ class IndirectList // Private Member Functions //- Disallow default assignment operator - void operator=(const IndirectList<T>&); + void operator=(const IndirectList<T>&) = delete; //- Disallow assignment from UIndirectList - void operator=(const UIndirectList<T>&); + void operator=(const UIndirectList<T>&) = delete; public: @@ -119,37 +119,45 @@ public: // Constructors //- Construct given the complete list and the addressing array - inline IndirectList(const UList<T>&, const labelUList&); + inline IndirectList + ( + const UList<T>& completeList, + const labelUList& addr + ); //- Construct given the complete list and by transferring addressing - inline IndirectList(const UList<T>&, const Xfer<List<label>>&); + inline IndirectList + ( + const UList<T>& completeList, + const Xfer<List<label>>& addr + ); //- Copy constructor - inline IndirectList(const IndirectList<T>&); + inline IndirectList(const IndirectList<T>& lst); //- Construct from UIndirectList - explicit inline IndirectList(const UIndirectList<T>&); + explicit inline IndirectList(const UIndirectList<T>& lst); // Member Functions + // Access - // Access + //- Return the list addressing + using UIndirectList<T>::addressing; - //- Return the list addressing - using UIndirectList<T>::addressing; + // Edit - // Edit + //- Reset addressing + using IndirectListAddressing::resetAddressing; - //- Reset addressing - using IndirectListAddressing::resetAddressing; + // Member Operators - // Member Operators + //- Assignment operator + using UIndirectList<T>::operator=; - //- Assignment operator - using UIndirectList<T>::operator=; }; diff --git a/src/OpenFOAM/containers/Lists/IndirectList/IndirectListI.H b/src/OpenFOAM/containers/Lists/IndirectList/IndirectListI.H index 068b38ed9d21da56dbdff749bbd1baa1c9f3e037..1558c3a6611669b5c369c92d0c3d975ee17a9788 100644 --- a/src/OpenFOAM/containers/Lists/IndirectList/IndirectListI.H +++ b/src/OpenFOAM/containers/Lists/IndirectList/IndirectListI.H @@ -25,7 +25,6 @@ License // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - inline Foam::IndirectListAddressing::IndirectListAddressing ( const labelUList& addr diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C index ab8aea673f87fafe5b8bd987dbf4252a52fdc72c..556de7b6f35e3b64a35697bdfe6cb3489e46b7db 100644 --- a/src/OpenFOAM/containers/Lists/List/List.C +++ b/src/OpenFOAM/containers/Lists/List/List.C @@ -33,6 +33,8 @@ License #include "BiIndirectList.H" #include "contiguous.H" +#include <utility> + // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // template<class T> @@ -52,7 +54,7 @@ Foam::List<T>::List(const label s) template<class T> -Foam::List<T>::List(const label s, const T& a) +Foam::List<T>::List(const label s, const T& val) : UList<T>(nullptr, s) { @@ -69,8 +71,9 @@ Foam::List<T>::List(const label s, const T& a) { List_ACCESS(T, (*this), vp); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = a; - List_END_FOR_ALL + { + vp[i] = val; + } } } @@ -93,8 +96,9 @@ Foam::List<T>::List(const label s, const zero) { List_ACCESS(T, (*this), vp); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = Zero; - List_END_FOR_ALL + { + vp[i] = Zero; + } } } @@ -119,8 +123,9 @@ Foam::List<T>::List(const List<T>& a) List_ACCESS(T, (*this), vp); List_CONST_ACCESS(T, a, ap); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = List_ELEM(a, ap, i); - List_END_FOR_ALL + { + vp[i] = ap[i]; + } } } } @@ -139,19 +144,13 @@ Foam::List<T>::List(const List<T2>& a) List_ACCESS(T, (*this), vp); List_CONST_ACCESS(T2, a, ap); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = T(List_ELEM(a, ap, i)); - List_END_FOR_ALL + { + vp[i] = T(ap[i]); + } } } -template<class T> -Foam::List<T>::List(const Xfer<List<T>>& lst) -{ - transfer(lst()); -} - - template<class T> Foam::List<T>::List(List<T>& a, bool reuse) : @@ -159,6 +158,7 @@ Foam::List<T>::List(List<T>& a, bool reuse) { if (reuse) { + // swap content this->v_ = a.v_; a.v_ = nullptr; a.size_ = 0; @@ -178,27 +178,29 @@ Foam::List<T>::List(List<T>& a, bool reuse) List_ACCESS(T, (*this), vp); List_CONST_ACCESS(T, a, ap); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = List_ELEM(a, ap, i); - List_END_FOR_ALL + { + vp[i] = ap[i]; + } } } } template<class T> -Foam::List<T>::List(const UList<T>& a, const labelUList& mapAddressing) +Foam::List<T>::List(const UList<T>& lst, const labelUList& mapAddressing) : UList<T>(nullptr, mapAddressing.size()) { if (this->size_) { - // Note: cannot use List_ELEM since third argument has to be index. - alloc(); - forAll(*this, i) + List_ACCESS(T, (*this), vp); + + const label len = (*this).size(); + for (label i=0; i < len; ++i) { - this->operator[](i) = a[mapAddressing[i]]; + vp[i] = lst[mapAddressing[i]]; } } } @@ -263,6 +265,42 @@ Foam::List<T>::List(std::initializer_list<T> lst) {} +template<class T> +Foam::List<T>::List(const Xfer<List<T>>& lst) +{ + transfer(lst()); +} + + +template<class T> +Foam::List<T>::List(List<T>&& lst) +: + UList<T>(nullptr, 0) +{ + // Can use transfer or swap to manage content + transfer(lst); +} + + +template<class T> +template<int SizeMin> +Foam::List<T>::List(DynamicList<T, SizeMin>&& lst) +: + UList<T>(nullptr, 0) +{ + transfer(lst); +} + + +template<class T> +Foam::List<T>::List(SortableList<T>&& lst) +: + UList<T>(nullptr, 0) +{ + transfer(lst); +} + + // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * // template<class T> @@ -293,21 +331,24 @@ void Foam::List<T>::setSize(const label newSize) { T* nv = new T[label(newSize)]; - if (this->size_) - { - label i = min(this->size_, newSize); + const label overlap = min(this->size_, newSize); + if (overlap) + { #ifdef USEMEMCPY if (contiguous<T>()) { - memcpy(nv, this->v_, i*sizeof(T)); + memcpy(nv, this->v_, overlap*sizeof(T)); } else #endif { - T* vv = &this->v_[i]; - T* av = &nv[i]; - while (i--) *--av = *--vv; + // No speedup observed for copy assignment on simple types + List_ACCESS(T, *this, vp); + for (label i = 0; i < overlap; ++i) + { + nv[i] = std::move(vp[i]); + } } } @@ -324,49 +365,51 @@ void Foam::List<T>::setSize(const label newSize) template<class T> -void Foam::List<T>::setSize(const label newSize, const T& a) +void Foam::List<T>::setSize(const label newSize, const T& val) { const label oldSize = label(this->size_); this->setSize(newSize); - if (newSize > oldSize) + List_ACCESS(T, *this, vp); + for (label i = oldSize; i < newSize; ++i) { - label i = newSize - oldSize; - T* vv = &this->v_[newSize]; - while (i--) *--vv = a; + vp[i] = val; } } template<class T> -void Foam::List<T>::transfer(List<T>& a) +void Foam::List<T>::transfer(List<T>& lst) { + // Clear and swap - could also check for self assignment clear(); - this->size_ = a.size_; - this->v_ = a.v_; + this->size_ = lst.size_; + this->v_ = lst.v_; - a.size_ = 0; - a.v_ = nullptr; + lst.size_ = 0; + lst.v_ = nullptr; } template<class T> -template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -void Foam::List<T>::transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>& a) +template<int SizeMin> +void Foam::List<T>::transfer(DynamicList<T, SizeMin>& lst) { // Shrink the allocated space to the number of elements used - a.shrink(); - transfer(static_cast<List<T>&>(a)); - a.clearStorage(); + lst.shrink(); + transfer(static_cast<List<T>&>(lst)); + + // Ensure DynamicList has proper capacity=0 too + lst.clearStorage(); } template<class T> -void Foam::List<T>::transfer(SortableList<T>& a) +void Foam::List<T>::transfer(SortableList<T>& lst) { // Shrink away the sort indices - a.shrink(); - transfer(static_cast<List<T>&>(a)); + lst.shrink(); + transfer(static_cast<List<T>&>(lst)); } @@ -390,24 +433,25 @@ void Foam::List<T>::operator=(const UList<T>& a) List_ACCESS(T, (*this), vp); List_CONST_ACCESS(T, a, ap); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = List_ELEM(a, ap, i); - List_END_FOR_ALL + { + vp[i] = ap[i]; + } } } } template<class T> -void Foam::List<T>::operator=(const List<T>& a) +void Foam::List<T>::operator=(const List<T>& lst) { - if (this == &a) + if (this == &lst) { FatalErrorInFunction << "attempted assignment to self" << abort(FatalError); } - operator=(static_cast<const UList<T>&>(a)); + operator=(static_cast<const UList<T>&>(lst)); } @@ -448,12 +492,40 @@ void Foam::List<T>::operator=(std::initializer_list<T> lst) { reAlloc(lst.size()); - auto iter = lst.begin(); - forAll(*this, i) + label i = 0; + for (const auto& val : lst) + { + this->operator[](i++) = val; + } +} + + +template<class T> +void Foam::List<T>::operator=(List<T>&& lst) +{ + if (this == &lst) { - this->operator[](i) = *iter; - ++iter; + FatalErrorInFunction + << "attempted assignment to self" + << abort(FatalError); } + + transfer(lst); +} + + +template<class T> +template<int SizeMin> +void Foam::List<T>::operator=(DynamicList<T, SizeMin>&& lst) +{ + transfer(lst); +} + + +template<class T> +void Foam::List<T>::operator=(SortableList<T>&& lst) +{ + transfer(lst); } diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H index c8e3219d9928ad7eaf106a1bbe3c437b1ccf827f..d4ff38d488b60b01f6d779e99388def33103e89d 100644 --- a/src/OpenFOAM/containers/Lists/List/List.H +++ b/src/OpenFOAM/containers/Lists/List/List.H @@ -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. @@ -68,8 +68,7 @@ template<class LListBase, class T> class LList; template<class T> using SLList = LList<SLListBase, T>; -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -class DynamicList; +template<class T, int SizeMin> class DynamicList; template<class T> class SortableList; template<class T> class IndirectList; @@ -136,26 +135,25 @@ public: explicit List(const label s); //- Construct with given size and value for all elements - List(const label s, const T& a); + List(const label s, const T& val); //- Construct with given size initializing all elements to zero List(const label s, const zero); - //- Copy constructor + //- Copy constructor from list List(const List<T>& a); - //- Copy constructor from list containing another type + //- Copy constructor from list containing another type. + // This is primarily useful to convert a list of ints into floats, + // for example. template<class T2> explicit List(const List<T2>& a); - //- Construct by transferring the parameter contents - List(const Xfer<List<T>>& lst); - //- Construct as copy or re-use as specified List(List<T>& a, bool reuse); //- Construct as subset - List(const UList<T>& a, const labelUList& mapAddressing); + List(const UList<T>& lst, const labelUList& mapAddressing); //- Construct given begin/end iterators. // Uses std::distance to determine the size. @@ -181,6 +179,19 @@ public: //- Construct from an initializer list List(std::initializer_list<T> lst); + //- Transfer (move) construct + List(const Xfer<List<T>>& lst); + + //- Move construct from List + List(List<T>&& lst); + + //- Move construct from DynamicList + template<int SizeMin> + List(DynamicList<T, SizeMin>&& lst); + + //- Move construct from SortableList + List(SortableList<T>&& lst); + //- Construct from Istream List(Istream& is); @@ -210,19 +221,19 @@ public: inline void resize(const label newSize); //- Alias for setSize(const label, const T&) - inline void resize(const label newSize, const T& a); + inline void resize(const label newSize, const T& val); //- Reset size of List void setSize(const label newSize); //- Reset size of List and value for new elements - void setSize(const label newSize, const T& a); + void setSize(const label newSize, const T& val); //- Clear the list, i.e. set size to zero inline void clear(); //- Append an element at the end of the list - inline void append(const T& t); + inline void append(const T& val); //- Append a List at the end of this list inline void append(const UList<T>& lst); @@ -232,16 +243,16 @@ public: //- Transfer the contents of the argument List into this list // and annul the argument list - void transfer(List<T>& a); + void transfer(List<T>& lst); //- Transfer the contents of the argument List into this list // and annul the argument list - template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> - void transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>& a); + template<int SizeMin> + void transfer(DynamicList<T, SizeMin>& lst); //- Transfer the contents of the argument List into this list // and annul the argument list - void transfer(SortableList<T>& a); + void transfer(SortableList<T>& lst); //- Transfer contents to the Xfer container inline Xfer<List<T>> xfer(); @@ -261,7 +272,7 @@ public: void operator=(const UList<T>& a); //- Assignment operator. Takes linear time - void operator=(const List<T>& a); + void operator=(const List<T>& lst); //- Assignment to SLList operator. Takes linear time void operator=(const SLList<T>& lst); @@ -276,11 +287,21 @@ public: void operator=(std::initializer_list<T> lst); //- Assignment of all entries to the given value - inline void operator=(const T& t); + inline void operator=(const T& val); //- Assignment of all entries to zero inline void operator=(const zero); + //- Move assignment. Takes constant time + void operator=(List<T>&& lst); + + //- Move assignment. Takes constant time. + template<int SizeMin> + void operator=(DynamicList<T, SizeMin>&& lst); + + //- Move assignment. Takes constant time. + void operator=(SortableList<T>&& lst); + // Istream operator diff --git a/src/OpenFOAM/containers/Lists/List/ListI.H b/src/OpenFOAM/containers/Lists/List/ListI.H index 8aa5bc016aaad44c4cb7f46a2085aab832a2b5b0..d3549e131b18396b576f3404116017d50efc3924 100644 --- a/src/OpenFOAM/containers/Lists/List/ListI.H +++ b/src/OpenFOAM/containers/Lists/List/ListI.H @@ -89,7 +89,7 @@ inline Foam::List<T>::List alloc(); InputIterator iter = begIter; - forAll(*this, i) + for (label i = 0; i < s; ++i) { this->operator[](i) = *iter; ++iter; @@ -142,9 +142,9 @@ inline void Foam::List<T>::resize(const label newSize) template<class T> -inline void Foam::List<T>::resize(const label newSize, const T& a) +inline void Foam::List<T>::resize(const label newSize, const T& val) { - this->setSize(newSize, a); + this->setSize(newSize, val); } @@ -182,9 +182,9 @@ inline Foam::Xfer<Foam::List<T>> Foam::List<T>::xfer() template<class T> -inline void Foam::List<T>::append(const T& t) +inline void Foam::List<T>::append(const T& val) { - setSize(size()+1, t); + setSize(size()+1, val); } @@ -223,9 +223,9 @@ inline void Foam::List<T>::append(const UIndirectList<T>& lst) // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<class T> -inline void Foam::List<T>::operator=(const T& t) +inline void Foam::List<T>::operator=(const T& val) { - UList<T>::operator=(t); + UList<T>::operator=(val); } diff --git a/src/OpenFOAM/containers/Lists/List/ListLoopM.H b/src/OpenFOAM/containers/Lists/List/ListLoopM.H index 032edb3052e8024c0f28c4fcafb8c1f561d4c3b4..3a9b341837c645f6a8e94a64576d1bbd8d06abab 100644 --- a/src/OpenFOAM/containers/Lists/List/ListLoopM.H +++ b/src/OpenFOAM/containers/Lists/List/ListLoopM.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,59 +26,26 @@ Description \*---------------------------------------------------------------------------*/ -#ifndef ListLoop_H -#define ListLoop_H +#ifndef ListLoopM_H +#define ListLoopM_H // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Element access looping -#ifdef vectorMachine - -// Element access looping using [] for vector machines - -#define List_FOR_ALL(f, i) \ - const label _n##i = (f).size(); \ - for (label i=0; i<_n##i; ++i) \ - { - -#define List_END_FOR_ALL } - -// Provide current element -#define List_CELEM(f, fp, i) (fp[i]) - -// Provide current element -#define List_ELEM(f, fp, i) (fp[i]) - -#define List_ACCESS(type, f, fp) \ +// Initial non-const access to list +#define List_ACCESS(type, f, fp) \ type* const __restrict__ fp = (f).begin() -#define List_CONST_ACCESS(type, f, fp) \ +// Initial const access to list +#define List_CONST_ACCESS(type, f, fp) \ const type* const __restrict__ fp = (f).begin() -#else - -// Pointer looping for scalar machines - #define List_FOR_ALL(f, i) \ - label i = (f).size(); \ - while (i--) \ - { \ - -#define List_END_FOR_ALL } - -// Provide current element without incrementing pointer -#define List_CELEM(f, fp, i) (*fp) - -// Provide current element and increment pointer -#define List_ELEM(f, fp, i) (*fp++) - -#define List_ACCESS(type, f, fp) \ - type* __restrict__ fp = (f).begin() - -#define List_CONST_ACCESS(type, f, fp) \ - const type* __restrict__ fp = (f).begin() - -#endif + const label _n##i = (f).size(); \ + for (label i=0; i<_n##i; ++i) +// Current element (non-const access) +#define List_ELEM(fp, i) (fp[i]) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C index bf5af3080db498a0029df0febd19c72ce8d3f7b1..641aa4ade0eeb4d8e811bfcaeb5b0d604452ce10 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C @@ -890,7 +890,7 @@ void Foam::inplaceReverseList(ListType& list) label elemI = 0; while (elemI < nIterations) { - Swap(list[elemI], list[lastIndex - elemI]); + Foam::Swap(list[elemI], list[lastIndex - elemI]); elemI++; } diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C index 4b01a43dd61ecff39fb00d54168ea8af5f37589b..543c5b855843521d521ef93079106683bc03ebb0 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C @@ -92,13 +92,15 @@ bool Foam::PackedBoolList::bitorPrepare template<class LabelListType> Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices) { - // no better information, just guess something about the size - reserve(indices.size()); + const label len = indices.size(); + + // No better information, just guess something from the size + reserve(len); label cnt = 0; - forAll(indices, elemI) + for (label i = 0; i < len; ++i) { - if (set(indices[elemI])) + if (set(indices[i])) { ++cnt; } @@ -112,9 +114,10 @@ template<class LabelListType> Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices) { label cnt = 0; - forAll(indices, elemI) + const label len = indices.size(); + for (label i = 0; i < len; ++i) { - if (unset(indices[elemI])) + if (unset(indices[i])) { ++cnt; } @@ -127,29 +130,30 @@ Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices) template<class LabelListType> Foam::label Foam::PackedBoolList::subsetIndices(const LabelListType& indices) { - // handle trivial case - if (empty() || indices.empty()) + const label len = indices.size(); + + // Handle trivial case + if (empty() || !len) { clear(); return 0; } - // normal case - PackedBoolList anded; - anded.reserve(size()); + PackedBoolList result; + result.reserve(size()); label cnt = 0; - forAll(indices, elemI) + for (label i = 0; i < len; ++i) { - const label& index = indices[elemI]; - if (operator[](index)) + const label index = indices[i]; + if (get(index)) { - anded.set(index); + result.set(index); ++cnt; } } - transfer(anded); + transfer(result); return cnt; } @@ -176,7 +180,7 @@ void Foam::PackedBoolList::set(const PackedList<1>& lst) StorageList& lhs = this->storage(); const StorageList& rhs = lst.storage(); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] |= rhs[i]; } @@ -209,7 +213,7 @@ void Foam::PackedBoolList::unset(const PackedList<1>& lst) // overlapping storage size const label len = min(this->packedLength(), lst.packedLength()); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] &= ~rhs[i]; } @@ -242,7 +246,7 @@ void Foam::PackedBoolList::subset(const PackedList<1>& lst) const label len = this->packedLength(); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] &= rhs[i]; } @@ -288,12 +292,13 @@ Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const void Foam::PackedBoolList::operator=(const UList<bool>& lst) { - this->setSize(lst.size()); + const label len = lst.size(); + this->setSize(len); - // overwrite with new true/false values - forAll(*this, elemI) + // Overwrite with new true/false values + for (label i = 0; i < len; ++i) { - set(elemI, lst[elemI]); + set(i, lst[i]); } } @@ -301,15 +306,15 @@ void Foam::PackedBoolList::operator=(const UList<bool>& lst) Foam::PackedBoolList& Foam::PackedBoolList::operator^=(const PackedList<1>& lst) { - // extend addressable area if needed, return maximum size possible + // Extend addressable area if needed, return maximum size possible label len = 0; const bool needTrim = bitorPrepare(lst, len); - // operate directly with the underlying storage + // Operate directly with the underlying storage StorageList& lhs = this->storage(); const StorageList& rhs = lst.storage(); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] ^= rhs[i]; } @@ -334,7 +339,7 @@ Foam::PackedBoolList Foam::operator& PackedBoolList result(lst1); result &= lst2; - // trim to bits actually used + // Trim to bits actually used result.trim(); return result; @@ -350,7 +355,7 @@ Foam::PackedBoolList Foam::operator^ PackedBoolList result(lst1); result ^= lst2; - // trim to bits actually used + // Trim to bits actually used result.trim(); return result; diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H index f98545a9bd64e3270c8d894564c5eed5f304dce1..a667e8aecf17f4d3ea49b4f3c67b242a84c22ce7 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H @@ -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. @@ -96,7 +96,7 @@ public: //- Construct from Istream PackedBoolList(Istream& is); - //- Construct with given size, initializes list to 0 + //- Construct with given size, initializes list to 0 (false) explicit inline PackedBoolList(const label size); //- Construct with given size and value for all elements @@ -114,6 +114,20 @@ public: //- Construct by transferring the parameter contents inline PackedBoolList(const Xfer<PackedList<1>>& lst); + //- Construct with given size and list of labels to set as true. + inline PackedBoolList + ( + const label size, + const labelUList& indices + ); + + //- Construct with given size and list of labels to set as true. + inline PackedBoolList + ( + const label size, + const UIndirectList<label>& indices + ); + //- Construct from a list of bools explicit inline PackedBoolList(const UList<bool>& lst); diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H index a0702f9a30e92aced06170a0feb317eb92408b2c..4c713dc005d4358aa4210ab47e3d9edf7883f869 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H @@ -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. @@ -75,23 +75,52 @@ inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedList<1>>& lst) inline Foam::PackedBoolList::PackedBoolList(const UList<bool>& lst) : - PackedList<1>() + PackedList<1>(lst.size()) { - operator=(lst); + // Set according to indices that are true + const label len = lst.size(); + + for (label i = 0; i < len; ++i) + { + if (lst[i]) + { + this->set(i, 1u); + } + } } inline Foam::PackedBoolList::PackedBoolList(const labelUList& indices) : - PackedList<1>(indices.size(), 0u) + PackedBoolList(indices.size(), indices) +{} + + +inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices) +: + PackedBoolList(indices.size(), indices) +{} + + +inline Foam::PackedBoolList::PackedBoolList +( + const label size, + const labelUList& indices +) +: + PackedList<1>(size) { set(indices); } -inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices) +inline Foam::PackedBoolList::PackedBoolList +( + const label size, + const UIndirectList<label>& indices +) : - PackedList<1>(indices.size(), 0u) + PackedList<1>(size) { set(indices); } diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H index 18720fc2ae929fc8bd697161550eae1ea68a5d87..ee03e4ad27a71fddb7a3d69d05d2b6935ceb56f0 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H @@ -48,8 +48,9 @@ Note list[1] = list[5] = list[6]; // propagates value \endcode - Using get() or the '[]' operator are similarly fast. Looping and reading - via an iterator is approx. 15% slower, but can be more flexible. + Reading via the get() or the '[]' operator are identical. + Looping and reading via an iterator is approx. 15% slower, + but can be more flexible. Using the set() operator (and the '[]' operator) are marginally slower (approx. 5%) than using an iterator, but the set() method has the @@ -157,7 +158,7 @@ protected: // Protected Member Functions //- Calculate the list length when packed - inline static label packedLength(const label); + inline static label packedLength(const label nElem); //- Read a list entry (allows for specialization) inline static unsigned int readValue(Istream& is); @@ -200,14 +201,14 @@ public: //- The max. number of bits that can be templated. // Might someday be useful for a template assert. - inline static unsigned int max_bits(); + inline static constexpr unsigned int max_bits(); //- The max. value for an entry, which simultaneously the bit-mask // eg, ((1 << 2) - 1) yields 0b0011 - inline static unsigned int max_value(); + inline static constexpr unsigned int max_value(); //- The number of entries per packed storage element - inline static unsigned int packing(); + inline static constexpr unsigned int packing(); //- Masking for all bits below the offset inline static unsigned int maskLower(unsigned offset); @@ -393,11 +394,11 @@ public: //- Remove and return the last element inline unsigned int remove(); - //- Get value at index I + //- Identical to get() - get value at index. // Never auto-vivify entries. inline unsigned int operator[](const label i) const; - //- Set value at index I. + //- Non-const access to value at index. // Returns iterator to perform the actual operation. // Does not auto-vivify entries, but will when assigned to. inline iteratorBase operator[](const label i); @@ -496,11 +497,11 @@ public: //- Disallow copy constructor from const_iterator // This would violate const-ness! - iterator(const const_iterator& iter); + iterator(const const_iterator& iter) = delete; //- Disallow assignment from const_iterator // This would violate const-ness! - void operator=(const const_iterator& iter); + void operator=(const const_iterator& iter) = delete; public: diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H index ad136b903fafd6ba25109c81b339274985f01bab..4f9c58644ad29ef91da1fbfba10b911db1196df8 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H @@ -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. @@ -25,24 +25,24 @@ License #include <climits> -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // template<unsigned nBits> -inline unsigned int Foam::PackedList<nBits>::max_bits() +inline constexpr unsigned int Foam::PackedList<nBits>::max_bits() { return sizeof(StorageType)*CHAR_BIT - 1; } template<unsigned nBits> -inline unsigned int Foam::PackedList<nBits>::max_value() +inline constexpr unsigned int Foam::PackedList<nBits>::max_value() { return (1u << nBits) - 1; } template<unsigned nBits> -inline unsigned int Foam::PackedList<nBits>::packing() +inline constexpr unsigned int Foam::PackedList<nBits>::packing() { return sizeof(StorageType)*CHAR_BIT / nBits; } @@ -65,6 +65,8 @@ inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem) } +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + namespace Foam { // Template specialization for bool entries @@ -88,13 +90,10 @@ namespace Foam if (this->get()) { os << index_; - return true; } - else - { - return false; - } + + return false; } } @@ -119,12 +118,12 @@ inline unsigned int Foam::PackedList<nBits>::readValue(Istream& is) template<unsigned nBits> inline void Foam::PackedList<nBits>::setPair(Istream& is) { - is.readBegin("Tuple2<label, unsigned int>"); + is.readBegin("Tuple2<label,unsigned int>"); const label ind = readLabel(is); const unsigned int val = readLabel(is); - is.readEnd("Tuple2<label, unsigned int>"); + is.readEnd("Tuple2<label,unsigned int>"); if (val > max_value()) { @@ -154,10 +153,8 @@ inline bool Foam::PackedList<nBits>::iteratorBase::writeIfSet(Ostream& os) const return true; } - else - { - return false; - } + + return false; } @@ -233,7 +230,8 @@ inline Foam::PackedList<nBits>::PackedList(const labelUList& lst) StorageList(packedLength(lst.size()), 0u), size_(lst.size()) { - forAll(lst, i) + const label len = lst.size(); + for (label i = 0; i < len; ++i) { set(i, lst[i]); } @@ -247,7 +245,8 @@ inline Foam::PackedList<nBits>::PackedList(const UIndirectList<label>& lst) StorageList(packedLength(lst.size()), 0u), size_(lst.size()) { - forAll(lst, i) + const label len = lst.size(); + for (label i = 0; i < len; ++i) { set(i, lst[i]); } @@ -862,16 +861,16 @@ inline void Foam::PackedList<nBits>::reserve(const label nElem) { const label len = packedLength(nElem); - // Need more capacity? + // Allocate more capacity if necessary if (len > StorageList::size()) { - // Like DynamicList with SizeInc=0, SizeMult=2, SizeDiv=1 StorageList::setSize ( max ( len, - StorageList::size()*2 + // SizeInc=0, SizeMult=2, SizeDiv=1 + 2 * StorageList::size() ), 0u ); @@ -964,27 +963,17 @@ inline unsigned int Foam::PackedList<nBits>::get(const label i) const // Lazy evaluation - return 0 for out-of-range if (i < 0 || i >= size_) { - return 0; - } - else - { - return iteratorBase(this, i).get(); + return 0u; } + + return iteratorBase(this, i).get(); } template<unsigned nBits> inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const { - // Lazy evaluation - return 0 for out-of-range - if (i < 0 || i >= size_) - { - return 0; - } - else - { - return iteratorBase(this, i).get(); - } + return get(i); } @@ -1024,10 +1013,8 @@ inline bool Foam::PackedList<nBits>::unset(const label i) { return false; } - else - { - return iteratorBase(this, i).set(0u); - } + + return iteratorBase(this, i).set(0u); } @@ -1035,11 +1022,11 @@ template<unsigned nBits> inline Foam::PackedList<nBits>& Foam::PackedList<nBits>::append(const unsigned int val) { - const label elemI = size_; - reserve(elemI + 1); + const label idx = size_; + reserve(idx + 1); size_++; - iteratorBase(this, elemI).set(val); + iteratorBase(this, idx).set(val); return *this; } @@ -1047,15 +1034,17 @@ Foam::PackedList<nBits>::append(const unsigned int val) template<unsigned nBits> inline unsigned int Foam::PackedList<nBits>::remove() { - if (!size_) + // Location of last element and simultaneously the new size + const label idx = size_ - 1; + + if (idx < 0) { FatalErrorInFunction << "List is empty" << abort(FatalError); } - label elemI = size_ - 1; - const unsigned int val = iteratorBase(this, elemI).get(); - resize(elemI); + const unsigned int val = iteratorBase(this, idx).get(); + resize(idx); return val; } diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C index a35334507aa58d979fa3263ea3ef1b4bbc3c0ef8..fac433d7d75795cf82415fabfd5d43a780b8b017 100644 --- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C +++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.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) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -33,43 +33,60 @@ inline Foam::SortableList<T>::SortableList() template<class T> -Foam::SortableList<T>::SortableList(const UList<T>& values) +inline Foam::SortableList<T>::SortableList(const label size) : - List<T>(values) -{ - sort(); -} + List<T>(size) +{} template<class T> -Foam::SortableList<T>::SortableList(const Xfer<List<T>>& values) +inline Foam::SortableList<T>::SortableList(const label size, const T& val) : - List<T>(values) -{ - sort(); -} + List<T>(size, val) +{} template<class T> -inline Foam::SortableList<T>::SortableList(const label size) +inline Foam::SortableList<T>::SortableList(const SortableList<T>& lst) : - List<T>(size) + List<T>(lst), + indices_(lst.indices()) {} template<class T> -inline Foam::SortableList<T>::SortableList(const label size, const T& val) +inline Foam::SortableList<T>::SortableList(SortableList<T>&& lst) : - List<T>(size, val) + List<T>(std::move(lst)), + indices_(std::move(lst.indices_)) {} template<class T> -Foam::SortableList<T>::SortableList(const SortableList<T>& lst) +Foam::SortableList<T>::SortableList(const UList<T>& values) : - List<T>(lst), - indices_(lst.indices()) -{} + List<T>(values) +{ + sort(); +} + + +template<class T> +Foam::SortableList<T>::SortableList(List<T>&& values) +: + List<T>(std::move(values)) +{ + sort(); +} + + +template<class T> +Foam::SortableList<T>::SortableList(const Xfer<List<T>>& values) +: + List<T>(values) +{ + sort(); +} template<class T> @@ -97,7 +114,6 @@ Foam::SortableList<T>::SortableList(std::initializer_list<T> values) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - template<class T> void Foam::SortableList<T>::clear() { @@ -119,12 +135,7 @@ void Foam::SortableList<T>::sort() { sortedOrder(*this, indices_); - List<T> lst(this->size()); - forAll(indices_, i) - { - lst[i] = this->operator[](indices_[i]); - } - + List<T> lst(*this, indices_); // Copy with indices for mapping List<T>::transfer(lst); } @@ -134,16 +145,18 @@ void Foam::SortableList<T>::reverseSort() { sortedOrder(*this, indices_, typename UList<T>::greater(*this)); - List<T> lst(this->size()); - forAll(indices_, i) - { - lst[i] = this->operator[](indices_[i]); - } - + List<T> lst(*this, indices_); // Copy with indices for mapping List<T>::transfer(lst); } +template<class T> +void Foam::SortableList<T>::swap(SortableList<T>& lst) +{ + List<T>::swap(lst); + indices_.swap(lst.indices_); +} + template<class T> Foam::Xfer<Foam::List<T>> Foam::SortableList<T>::xfer() { @@ -156,6 +169,7 @@ Foam::Xfer<Foam::List<T>> Foam::SortableList<T>::xfer() template<class T> inline void Foam::SortableList<T>::operator=(const T& val) { + indices_.clear(); UList<T>::operator=(val); } @@ -163,8 +177,8 @@ inline void Foam::SortableList<T>::operator=(const T& val) template<class T> inline void Foam::SortableList<T>::operator=(const UList<T>& lst) { - List<T>::operator=(lst); indices_.clear(); + List<T>::operator=(lst); } @@ -176,6 +190,22 @@ inline void Foam::SortableList<T>::operator=(const SortableList<T>& lst) } +template<class T> +inline void Foam::SortableList<T>::operator=(List<T>&& lst) +{ + indices_.clear(); + List<T>::operator=(std::move(lst)); +} + + +template<class T> +inline void Foam::SortableList<T>::operator=(SortableList<T>&& lst) +{ + clear(); + this->swap(lst); +} + + template<class T> inline void Foam::SortableList<T>::operator=(std::initializer_list<T> lst) { @@ -184,4 +214,13 @@ inline void Foam::SortableList<T>::operator=(std::initializer_list<T> lst) } +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template<class T> +inline void Foam::Swap(SortableList<T>& a, SortableList<T>& b) +{ + a.swap(b); +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H index cd005a09c2f42e2905ab509642627a6de5bd8fab..8ef6aefa19796ec98a2eb0c1da0ba3eefa565345 100644 --- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H +++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H @@ -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. @@ -67,13 +67,7 @@ public: //- Null constructor, sort later (eg, after assignment or transfer) inline SortableList(); - //- Construct from UList, sorting immediately - explicit SortableList(const UList<T>& values); - - //- Construct from transferred List, sorting immediately - explicit SortableList(const Xfer<List<T>>& values); - - //- Construct given size. Sort later on + //- Construct given size, sort later. // The indices remain empty until the list is sorted explicit inline SortableList(const label size); @@ -81,17 +75,29 @@ public: // The indices remain empty until the list is sorted inline SortableList(const label size, const T& val); + //- Copy construct + inline SortableList(const SortableList<T>& lst); + + //- Move construct + inline SortableList(SortableList<T>&& lst); + + //- Copy construct from UList, sorting immediately + explicit SortableList(const UList<T>& values); + + //- Move construct from List, sorting immediately + SortableList(List<T>&& values); + //- Construct given begin/end iterators. // Uses std::distance to determine the size. template<class InputIterator> inline SortableList(InputIterator begIter, InputIterator endIter); - //- Construct as copy - inline SortableList(const SortableList<T>& lst); - //- Construct from an initializer list, sorting immediately SortableList(std::initializer_list<T> values); + //- Construct from transferred List, sorting immediately + explicit SortableList(const Xfer<List<T>>& values); + // Member Functions @@ -120,26 +126,42 @@ public: //- Reverse (stable) sort the list void reverseSort(); + //- Swap content with another SortableList in constant time + inline void swap(SortableList<T>& lst); + //- Transfer contents to the Xfer container as a plain List inline Xfer<List<T>> xfer(); // Member Operators - //- Assignment of all entries to the given value + //- Assignment of all entries to the given value, removing indices. inline void operator=(const T& val); - //- Assignment to UList operator. Takes linear time + //- Assignment to UList operator, removing indices. Takes linear time inline void operator=(const UList<T>& lst); //- Assignment operator. Takes linear time inline void operator=(const SortableList<T>& lst); + //- Move assignment, removing indices. Takes linear time + inline void operator=(List<T>&& lst); + + //- Move operator. Takes linear time + inline void operator=(SortableList<T>&& lst); + //- Assignment to an initializer list void operator=(std::initializer_list<T> lst); }; +// Global Functions + +// Exchange contents of lists - see SortableList::swap(). +template<class T> +inline void Swap(SortableList<T>& a, SortableList<T>& b); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.C b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.C new file mode 100644 index 0000000000000000000000000000000000000000..931e93efb11bd8023eb3f8b9c147321599d42b32 --- /dev/null +++ b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.C @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class T> +inline Foam::label Foam::UIndirectList<T>::find +( + const T& val, + const label start +) const +{ + if (start >= 0) + { + List_CONST_ACCESS(T, completeList_, lst); + List_CONST_ACCESS(label, addressing_, addr); + + const label len = addressing_.size(); + + for (label i = start; i < len; ++i) + { + if (lst[addr[i]] == val) + { + return i; + } + } + } + + return -1; +} + + +template<class T> +inline Foam::label Foam::UIndirectList<T>::rfind +( + const T& val, + const label pos +) const +{ + List_CONST_ACCESS(T, completeList_, lst); + List_CONST_ACCESS(label, addressing_, addr); + + for + ( + label i = + ( + pos < 0 + ? (addressing_.size()-1) + : min(pos, (addressing_.size()-1)) + ); + i >= 0; + --i + ) + { + if (lst[addr[i]] == val) + { + return i; + } + } + + return -1; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.H b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.H index e39d899f899be9426ba25d2474ed11596f4492bc..61ddf3bed975b9e8b3c8678a1903511c212dde5e 100644 --- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.H +++ b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectList.H @@ -79,52 +79,70 @@ public: // Member Functions - // Access + // Access - //- Return the number of elements in the list - inline label size() const; + //- Return the number of elements in the list + inline label size() const; - //- Return true if the list is empty (ie, size() is zero). - inline bool empty() const; + //- Return true if the list is empty (ie, size() is zero). + inline bool empty() const; - //- Return the first element of the list. - inline T& first(); + //- Return the first element of the list. + inline T& first(); - //- Return first element of the list. - inline const T& first() const; + //- Return first element of the list. + inline const T& first() const; - //- Return the last element of the list. - inline T& last(); + //- Return the last element of the list. + inline T& last(); - //- Return the last element of the list. - inline const T& last() const; + //- Return the last element of the list. + inline const T& last() const; - //- Return the complete list - inline const UList<T>& completeList() const; + //- Return the complete list + inline const UList<T>& completeList() const; - //- Return the list addressing - inline const List<label>& addressing() const; + //- Return the list addressing + inline const List<label>& addressing() const; - // Member Operators + // Search - //- Return the addressed elements as a List - inline List<T> operator()() const; + //- Find index of the first occurence of the value. + // When start is specified, any occurences before start are ignored. + // Linear search. + // \return -1 if not found. + label find(const T& val, const label start=0) const; - //- Return non-const access to an element - inline T& operator[](const label i); + //- Find index of the last occurence of the value. + // When pos is specified, any occurences after pos are ignored. + // Linear search. + // \return -1 if not found. + label rfind(const T& val, const label pos=-1) const; - //- Return const access to an element - inline const T& operator[](const label i) const; + //- True if the value if found in the list. Linear search. + inline bool found(const T& val, const label start=0) const; - //- Assignment to UList of addressed elements - inline void operator=(const UList<T>& ae); - //- Assignment to UIndirectList of addressed elements - inline void operator=(const UIndirectList<T>& ae); + // Member Operators - //- Assignment of all entries to the given value - inline void operator=(const T& t); + //- Return the addressed elements as a List + inline List<T> operator()() const; + + //- Return non-const access to an element + inline T& operator[](const label i); + + //- Return const access to an element + inline const T& operator[](const label i) const; + + //- Assignment to UList of addressed elements + inline void operator=(const UList<T>& ae); + + //- Assignment to UIndirectList of addressed elements + inline void operator=(const UIndirectList<T>& ae); + + //- Assignment of all entries to the given value + inline void operator=(const T& t); // STL type definitions @@ -162,7 +180,7 @@ public: friend Ostream& operator<< <T> ( Ostream& os, - const UIndirectList<T>& L + const UIndirectList<T>& lst ); }; @@ -176,6 +194,7 @@ public: #include "UIndirectListI.H" #ifdef NoRepository + #include "UIndirectList.C" #include "UIndirectListIO.C" #endif diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListI.H b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListI.H index c26efd9ac744b91e1671010c17aaa679fc6e9976..15daa10969f02763074f05cc6cc13cbd6a1d7e0d 100644 --- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListI.H +++ b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListI.H @@ -95,6 +95,17 @@ inline const Foam::List<Foam::label>& Foam::UIndirectList<T>::addressing() const } +template<class T> +inline bool Foam::UIndirectList<T>::found +( + const T& val, + const label pos +) const +{ + return this->find(val, pos) != -1; +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<class T> diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C index 5e711c072411100c72b4f301242feaa2fe8accf7..de49fc74a0cfbba2a7ff382c4733f142716c46b3 100644 --- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C +++ b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C @@ -131,10 +131,10 @@ template<class T> Foam::Ostream& Foam::operator<< ( Foam::Ostream& os, - const Foam::UIndirectList<T>& L + const Foam::UIndirectList<T>& lst ) { - return L.writeList(os, 10); + return lst.writeList(os, 10); } diff --git a/src/OpenFOAM/containers/Lists/UList/UList.C b/src/OpenFOAM/containers/Lists/UList/UList.C index f47969874420dee885258c2eaab74473ebc9d146..b87e524b5938e22181bf980178b744f9b13a17fe 100644 --- a/src/OpenFOAM/containers/Lists/UList/UList.C +++ b/src/OpenFOAM/containers/Lists/UList/UList.C @@ -49,18 +49,18 @@ Foam::labelRange Foam::UList<T>::validateRange(const labelRange& range) const template<class T> Foam::labelRange Foam::UList<T>::validateRange ( - std::initializer_list<label> start_size_pair + std::initializer_list<label> start_size ) const { - if (start_size_pair.size() != 2) + if (start_size.size() != 2) { FatalErrorInFunction - << "range specified with " << start_size_pair.size() + << "range specified with " << start_size.size() << " elements instead of 2" << abort(FatalError); } - auto iter = start_size_pair.begin(); + auto iter = start_size.begin(); const label beg = *(iter++); const label sz = *iter; @@ -71,6 +71,56 @@ Foam::labelRange Foam::UList<T>::validateRange // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template<class T> +void Foam::UList<T>::moveFirst(const label i) +{ + checkIndex(i); + + for (label lower = 0; lower < i; ++lower) + { + Foam::Swap(this->operator[](lower), this->operator[](i)); + } +} + + +template<class T> +void Foam::UList<T>::moveLast(const label i) +{ + checkIndex(i); + + for (label upper = size()-1; upper > i; --upper) + { + Foam::Swap(this->operator[](i), this->operator[](upper)); + } +} + + +template<class T> +void Foam::UList<T>::swapFirst(const label i) +{ + checkIndex(i); + + if (i > 0) + { + Foam::Swap(this->operator[](0), this->operator[](i)); + } +} + + +template<class T> +void Foam::UList<T>::swapLast(const label i) +{ + checkIndex(i); + + const label upper = size()-1; + + if (i < upper) + { + Foam::Swap(this->operator[](i), this->operator[](upper)); + } +} + + template<class T> void Foam::UList<T>::deepCopy(const UList<T>& a) { @@ -95,8 +145,9 @@ void Foam::UList<T>::deepCopy(const UList<T>& a) List_ACCESS(T, (*this), vp); List_CONST_ACCESS(T, a, ap); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = List_ELEM(a, ap, i); - List_END_FOR_ALL + { + vp[i] = ap[i]; + } } } } @@ -125,10 +176,10 @@ const Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range) const template<class T> Foam::UList<T> Foam::UList<T>::operator[] ( - std::initializer_list<label> start_size_pair + std::initializer_list<label> start_size ) { - const labelRange slice = validateRange(start_size_pair); + const labelRange slice = validateRange(start_size); return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList } @@ -137,23 +188,24 @@ Foam::UList<T> Foam::UList<T>::operator[] template<class T> const Foam::UList<T> Foam::UList<T>::operator[] ( - std::initializer_list<label> start_size_range + std::initializer_list<label> start_size ) const { // Restricted range - const labelRange slice = validateRange(start_size_range); + const labelRange slice = validateRange(start_size); return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList } template<class T> -void Foam::UList<T>::operator=(const T& t) +void Foam::UList<T>::operator=(const T& val) { List_ACCESS(T, (*this), vp); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = t; - List_END_FOR_ALL + { + vp[i] = val; + } } @@ -162,18 +214,9 @@ void Foam::UList<T>::operator=(const zero) { List_ACCESS(T, (*this), vp); List_FOR_ALL((*this), i) - List_ELEM((*this), vp, i) = Zero; - List_END_FOR_ALL -} - - -// * * * * * * * * * * * * * * STL Member Functions * * * * * * * * * * * * // - -template<class T> -void Foam::UList<T>::swap(UList<T>& a) -{ - Swap(size_, a.size_); - Swap(v_, a.v_); + { + vp[i] = Zero; + } } @@ -194,6 +237,55 @@ std::streamsize Foam::UList<T>::byteSize() const } +template<class T> +Foam::label Foam::UList<T>::find(const T& val, const label start) const +{ + if (start >= 0) + { + List_CONST_ACCESS(T, (*this), vp); + + const label len = this->size(); + + for (label i = start; i < len; ++i) + { + if (vp[i] == val) + { + return i; + } + } + } + + return -1; +} + + +template<class T> +Foam::label Foam::UList<T>::rfind(const T& val, const label pos) const +{ + List_CONST_ACCESS(T, (*this), vp); + + for + ( + label i = + ( + pos < 0 + ? (this->size()-1) + : min(pos, this->size()-1) + ); + i >= 0; + --i + ) + { + if (vp[i] == val) + { + return i; + } + } + + return -1; +} + + template<class T> void Foam::sort(UList<T>& a) { @@ -244,9 +336,10 @@ bool Foam::UList<T>::operator==(const UList<T>& a) const List_CONST_ACCESS(T, (a), ap); List_FOR_ALL((*this), i) - equal = (List_ELEM((*this), vp, i) == List_ELEM((a), ap, i)); + { + equal = (vp[i] == ap[i]); if (!equal) break; - List_END_FOR_ALL + } return equal; } diff --git a/src/OpenFOAM/containers/Lists/UList/UList.H b/src/OpenFOAM/containers/Lists/UList/UList.H index 6b58437b36fa2bd312669c0a265384bf10784d56..23fee6ab040c78895426874a59cb4c89ddd1b589 100644 --- a/src/OpenFOAM/containers/Lists/UList/UList.H +++ b/src/OpenFOAM/containers/Lists/UList/UList.H @@ -48,6 +48,8 @@ SourceFiles #include "nullObject.H" #include "zero.H" #include "stdFoam.H" +#include "Swap.H" + #include <initializer_list> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -181,17 +183,28 @@ public: // Member Functions - // Access - //- Return the forward circular index, i.e. the next index + //- Return the forward circular index, i.e. next index // which returns to the first at the end of the list inline label fcIndex(const label i) const; - //- Return the reverse circular index, i.e. the previous index + //- Return forward circular value (ie, next value in the list) + inline const T& fcValue(const label i) const; + + //- Return forward circular value (ie, next value in the list) + inline T& fcValue(const label i); + + //- Return the reverse circular index, i.e. previous index // which returns to the last at the beginning of the list inline label rcIndex(const label i) const; + //- Return reverse circular value (ie, previous value in the list) + inline const T& rcValue(const label i) const; + + //- Return reverse circular value (ie, previous value in the list) + inline T& rcValue(const label i); + //- Return the binary size in number of characters of the UList // if the element is a primitive type // i.e. contiguous<T>() == true. @@ -234,6 +247,41 @@ public: inline void checkIndex(const label i) const; + // Search + + //- Find index of the first occurence of the value. + // When start is specified, any occurences before start are ignored. + // Linear search. + // \return -1 if not found. + label find(const T& val, const label start=0) const; + + //- Find index of the last occurence of the value. + // When pos is specified, any occurences after pos are ignored. + // Linear search. + // \return -1 if not found. + label rfind(const T& val, const label pos=-1) const; + + //- True if the value if found in the list. Linear search. + inline bool found(const T& val, const label start=0) const; + + + // Edit + + //- Move element to the first position. + void moveFirst(const label i); + + //- Move element to the last position. + void moveLast(const label i); + + //- Swap element with the first element. Fatal on an empty list. + void swapFirst(const label i); + + //- Swap element with the last element. Fatal on an empty list. + void swapLast(const label i); + + + // Copy + //- Copy the pointer held by the given UList inline void shallowCopy(const UList<T>& a); @@ -264,21 +312,21 @@ public: //- Return (start,size) subset from UList with non-const access. // The range is subsetted with the list size itself to ensure that the // result always addresses a valid section of the list. - UList<T> operator[](std::initializer_list<label> start_size_range); + UList<T> operator[](std::initializer_list<label> start_size); //- Return (start,size) subset from UList with const access. // The range is subsetted with the list size itself to ensure that the // result always addresses a valid section of the list. const UList<T> operator[] ( - std::initializer_list<label> start_size_range + std::initializer_list<label> start_size ) const; //- Allow cast to a const List<T>& inline operator const Foam::List<T>&() const; //- Assignment of all entries to the given value - void operator=(const T& t); + void operator=(const T& val); //- Assignment of all entries to zero void operator=(const zero); @@ -374,8 +422,8 @@ public: //- Return true if the UList is empty (ie, size() is zero) inline bool empty() const; - //- Swap two ULists of the same type in constant time - void swap(UList<T>& a); + //- Swap content with another UList of the same type in constant time + inline void swap(UList<T>& lst); // STL member operators @@ -429,6 +477,9 @@ public: ); }; + +// Global Functions + template<class T> void sort(UList<T>& a); @@ -446,11 +497,15 @@ void shuffle(UList<T>& a); // Reverse the first n elements of the list template<class T> -inline void reverse(UList<T>& ul, const label n); +inline void reverse(UList<T>& lst, const label n); // Reverse all the elements of the list template<class T> -inline void reverse(UList<T>& ul); +inline void reverse(UList<T>& lst); + +// Exchange contents of lists - see UList::swap(). +template<class T> +inline void Swap(UList<T>& a, UList<T>& b); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/containers/Lists/UList/UListI.H b/src/OpenFOAM/containers/Lists/UList/UListI.H index 971fa7faa0530ceadb3964ada7746733a85efa37..36c74ee28b5cb8fa2eff787723a6b093289b630a 100644 --- a/src/OpenFOAM/containers/Lists/UList/UListI.H +++ b/src/OpenFOAM/containers/Lists/UList/UListI.H @@ -61,6 +61,20 @@ inline Foam::label Foam::UList<T>::fcIndex(const label i) const } +template<class T> +inline const T& Foam::UList<T>::fcValue(const label i) const +{ + return this->operator[](this->fcIndex(i)); +} + + +template<class T> +inline T& Foam::UList<T>::fcValue(const label i) +{ + return this->operator[](this->fcIndex(i)); +} + + template<class T> inline Foam::label Foam::UList<T>::rcIndex(const label i) const { @@ -68,6 +82,20 @@ inline Foam::label Foam::UList<T>::rcIndex(const label i) const } +template<class T> +inline const T& Foam::UList<T>::rcValue(const label i) const +{ + return this->operator[](this->rcIndex(i)); +} + + +template<class T> +inline T& Foam::UList<T>::rcValue(const label i) +{ + return this->operator[](this->rcIndex(i)); +} + + template<class T> inline void Foam::UList<T>::checkStart(const label start) const { @@ -152,6 +180,13 @@ inline T* Foam::UList<T>::data() } +template<class T> +inline bool Foam::UList<T>::found(const T& val, const label start) const +{ + return (this->find(val, start) >= 0); +} + + template<class T> inline void Foam::UList<T>::shallowCopy(const UList<T>& a) { @@ -313,21 +348,37 @@ inline bool Foam::UList<T>::empty() const } +template<class T> +inline void Foam::UList<T>::swap(UList<T>& lst) +{ + Foam::Swap(size_, lst.size_); + Foam::Swap(v_, lst.v_); +} + + // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // template<class T> -inline void Foam::reverse(UList<T>& ul, const label n) +inline void Foam::reverse(UList<T>& lst, const label n) { for (int i=0; i<n/2; ++i) { - Swap(ul[i], ul[n-1-i]); + Foam::Swap(lst[i], lst[n-1-i]); } } + +template<class T> +inline void Foam::reverse(UList<T>& lst) +{ + reverse(lst, lst.size()); +} + + template<class T> -inline void Foam::reverse(UList<T>& ul) +inline void Foam::Swap(UList<T>& a, UList<T>& b) { - reverse(ul, ul.size()); + a.swap(b); } diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C index 1626319fc0f94d502991996f65efe2220bf9dde9..a18d76fc9eba32b4f30d61bf43361ceeefcbc1dd 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.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) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,32 +27,32 @@ License // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField(Istream& is) +template<class T, int SizeMin> +Foam::DynamicField<T, SizeMin>::DynamicField(Istream& is) : Field<T>(is), capacity_(Field<T>::size()) {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -Foam::tmp<Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>> -Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clone() const +template<class T, int SizeMin> +Foam::tmp<Foam::DynamicField<T, SizeMin>> +Foam::DynamicField<T, SizeMin>::clone() const { - return tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv>> + return tmp<DynamicField<T, SizeMin>> ( - new DynamicField<T, SizeInc, SizeMult, SizeDiv>(*this) + new DynamicField<T, SizeMin>(*this) ); } // * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> Foam::Ostream& Foam::operator<< ( Ostream& os, - const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst + const DynamicField<T, SizeMin>& lst ) { os << static_cast<const Field<T>&>(lst); @@ -60,11 +60,11 @@ Foam::Ostream& Foam::operator<< } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> Foam::Istream& Foam::operator>> ( Istream& is, - DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst + DynamicField<T, SizeMin>& lst ) { is >> static_cast<Field<T>&>(lst); diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H index 178dff7c256f132cd4ff069abbaaf355c20148e0..fd5b3a5486f2f295f9a9ea9359c905cc455143e0 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H @@ -46,21 +46,20 @@ namespace Foam // Forward declaration of friend functions and operators -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -class DynamicField; +template<class T, int SizeMin> class DynamicField; -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> Ostream& operator<< ( Ostream&, - const DynamicField<T, SizeInc, SizeMult, SizeDiv>& + const DynamicField<T, SizeMin>& ); -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> Istream& operator>> ( Istream&, - DynamicField<T, SizeInc, SizeMult, SizeDiv>& + DynamicField<T, SizeMin>& ); @@ -68,16 +67,12 @@ Istream& operator>> Class DynamicField Declaration \*---------------------------------------------------------------------------*/ -template<class T, unsigned SizeInc=0, unsigned SizeMult=2, unsigned SizeDiv=1> +template<class T, int SizeMin=64> class DynamicField : public Field<T> { - static_assert - ( - (SizeInc || SizeMult) && SizeDiv, - "Avoid invalid sizing parameters" - ); + static_assert(SizeMin > 0, "Invalid min size parameter"); // Private data @@ -85,17 +80,20 @@ class DynamicField label capacity_; + // Private Member Functions + + //- Copy assignment from another list + template<class ListType> + inline void assignDynField(const ListType& lst); + public: // Static Member Functions //- Return a null field - inline static const DynamicField<T, SizeInc, SizeMult, SizeDiv>& null() + inline static const DynamicField<T, SizeMin>& null() { - return *reinterpret_cast - < - DynamicField<T, SizeInc, SizeMult, SizeDiv>* - >(0); + return *reinterpret_cast<DynamicField<T, SizeMin>*>(0); } @@ -140,19 +138,19 @@ public: ); //- Construct copy - inline DynamicField(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&); + inline DynamicField(const DynamicField<T, SizeMin>&); //- Construct by transferring the Field contents inline DynamicField ( - const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv>>& + const Xfer<DynamicField<T, SizeMin>>& ); //- Construct from Istream. Size set to size of list read. explicit DynamicField(Istream&); //- Clone - tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv>> clone() const; + tmp<DynamicField<T, SizeMin>> clone() const; // Member Functions @@ -188,7 +186,7 @@ public: //- Alter the addressed list size and fill new space with a // constant. - inline void resize(const label, const T&); + inline void resize(const label, const T& val); //- Reserve allocation space for at least this size. // Never shrinks the allocated size, use setCapacity() for that. @@ -203,7 +201,7 @@ public: //- Shrink the allocated space to the number of elements used. // Returns a reference to the DynamicField. - inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& shrink(); + inline DynamicField<T, SizeMin>& shrink(); //- Transfer contents to the Xfer container as a plain List inline Xfer<List<T>> xfer(); @@ -212,16 +210,12 @@ public: // Member Operators //- Append an element at the end of the list - inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append - ( - const T& - ); + inline DynamicField<T, SizeMin>& + append(const T& val); //- Append a List at the end of this list - inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append - ( - const UList<T>& - ); + inline DynamicField<T, SizeMin>& + append(const UList<T>& lst); //- Remove and return the top element inline T remove(); @@ -236,7 +230,7 @@ public: //- Assignment to DynamicField inline void operator= ( - const DynamicField<T, SizeInc, SizeMult, SizeDiv>& + const DynamicField<T, SizeMin>& ); //- Assignment to UList diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H index b29af8958e3357ccb7cc44f69c0c37af8bd9af26..658c0b9d1cbd5f608ed17edaf0df746974df063d 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -23,18 +23,46 @@ License \*---------------------------------------------------------------------------*/ +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class T, int SizeMin> +template<class ListType> +inline void Foam::DynamicField<T, SizeMin>::assignDynField +( + const ListType& lst +) +{ + const label newSize = lst.size(); + + if (capacity_ >= newSize) + { + // Can copy w/o reallocating - adjust addressable size accordingly. + Field<T>::size(lst.size()); + Field<T>::operator=(lst); + } + else + { + // Ensure list size consistency prior to copying. + Field<T>::size(capacity_); + + Field<T>::operator=(lst); + capacity_ = Field<T>::size(); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField() +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField() : Field<T>(0), capacity_(Field<T>::size()) {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( const label nElem ) @@ -42,13 +70,13 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField Field<T>(nElem), capacity_(Field<T>::size()) { - // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv) + // We could also enforce sizing granularity Field<T>::size(0); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( const UList<T>& lst ) @@ -58,8 +86,8 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( const Xfer<List<T>>& lst ) @@ -69,8 +97,8 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( const Xfer<Field<T>>& lst ) @@ -80,8 +108,8 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( const UList<T>& mapF, const labelList& mapAddressing @@ -92,8 +120,8 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( const UList<T>& mapF, const labelListList& mapAddressing, @@ -106,8 +134,8 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField //- Construct by mapping from the given field -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( const UList<T>& mapF, const FieldMapper& map @@ -118,10 +146,10 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( - const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst + const DynamicField<T, SizeMin>& lst ) : Field<T>(lst), @@ -129,10 +157,10 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField {} -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField ( - const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv>>& lst + const Xfer<DynamicField<T, SizeMin>>& lst ) : Field<T>(lst), @@ -142,16 +170,16 @@ inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::label Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::capacity() +template<class T, int SizeMin> +inline Foam::label Foam::DynamicField<T, SizeMin>::capacity() const { return capacity_; } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setCapacity +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::setCapacity ( const label nElem ) @@ -164,107 +192,90 @@ inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setCapacity // truncate addressed sizes too nextFree = capacity_; } - // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv) + + // We could also enforce sizing granularity Field<T>::setSize(capacity_); Field<T>::size(nextFree); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::reserve +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::reserve ( const label nElem ) { - // allocate more capacity? + // Allocate more capacity if necessary if (nElem > capacity_) { -// TODO: convince the compiler that division by zero does not occur -// if (SizeInc && (!SizeMult || !SizeDiv)) -// { -// // resize with SizeInc as the granularity -// capacity_ = nElem; -// unsigned pad = SizeInc - (capacity_ % SizeInc); -// if (pad != SizeInc) -// { -// capacity_ += pad; -// } -// } -// else - { - capacity_ = max + capacity_ = max + ( + SizeMin, + max ( nElem, - label(SizeInc + capacity_ * SizeMult / SizeDiv) - ); - } + // label(SizeInc + capacity_ * SizeMult / SizeDiv) + label(2*capacity_) + ) + ); - // adjust allocated size, leave addressed size untouched - label nextFree = Field<T>::size(); + // Adjust allocated size, leave addressed size untouched + const label nextFree = Field<T>::size(); Field<T>::setSize(capacity_); Field<T>::size(nextFree); } } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::setSize ( const label nElem ) { - // allocate more capacity? + // Allocate more capacity if necessary if (nElem > capacity_) { -// TODO: convince the compiler that division by zero does not occur -// if (SizeInc && (!SizeMult || !SizeDiv)) -// { -// // resize with SizeInc as the granularity -// capacity_ = nElem; -// unsigned pad = SizeInc - (capacity_ % SizeInc); -// if (pad != SizeInc) -// { -// capacity_ += pad; -// } -// } -// else - { - capacity_ = max + capacity_ = max + ( + SizeMin, + max ( nElem, - label(SizeInc + capacity_ * SizeMult / SizeDiv) - ); - } + // label(SizeInc + capacity_ * SizeMult / SizeDiv) + label(2*capacity_) + ) + ); Field<T>::setSize(capacity_); } - // adjust addressed size + // Adjust addressed size Field<T>::size(nElem); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::setSize ( const label nElem, - const T& t + const T& val ) { label nextFree = Field<T>::size(); setSize(nElem); - // set new elements to constant value + // Set new elements to constant value while (nextFree < nElem) { - this->operator[](nextFree++) = t; + this->operator[](nextFree++) = val; } } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::resize ( const label nElem ) @@ -273,35 +284,35 @@ inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::resize ( const label nElem, - const T& t + const T& val ) { - this->setSize(nElem, t); + this->setSize(nElem, val); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clear() +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::clear() { Field<T>::size(0); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clearStorage() +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::clearStorage() { Field<T>::clear(); capacity_ = 0; } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::shrink() +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>& +Foam::DynamicField<T, SizeMin>::shrink() { label nextFree = Field<T>::size(); if (capacity_ > nextFree) @@ -318,32 +329,32 @@ Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::shrink() } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<class T, int SizeMin> inline Foam::Xfer<Foam::List<T>> -Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::xfer() +Foam::DynamicField<T, SizeMin>::xfer() { return xferMoveTo<List<T>>(*this); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>& +Foam::DynamicField<T, SizeMin>::append ( - const T& t + const T& val ) { - const label elemI = List<T>::size(); - setSize(elemI + 1); + const label idx = List<T>::size(); + setSize(idx + 1); - this->operator[](elemI) = t; + this->operator[](idx) = val; return *this; } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>& -Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>& +Foam::DynamicField<T, SizeMin>::append ( const UList<T>& lst ) @@ -365,20 +376,21 @@ Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline T Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove() +template<class T, int SizeMin> +inline T Foam::DynamicField<T, SizeMin>::remove() { - const label elemI = List<T>::size() - 1; + // Location of last element and simultaneously the new size + const label idx = List<T>::size() - 1; - if (elemI < 0) + if (idx < 0) { FatalErrorInFunction << "List is empty" << abort(FatalError); } - const T& val = List<T>::operator[](elemI); + const T& val = List<T>::operator[](idx); - List<T>::size(elemI); + List<T>::size(idx); return val; } @@ -386,8 +398,8 @@ inline T Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove() // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline T& Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator() +template<class T, int SizeMin> +inline T& Foam::DynamicField<T, SizeMin>::operator() ( const label elemI ) @@ -401,65 +413,39 @@ inline T& Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator() } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::operator= ( - const T& t + const T& val ) { - UList<T>::operator=(t); + UList<T>::operator=(val); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::operator= ( - const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst + const DynamicField<T, SizeMin>& lst ) { if (this == &lst) { FatalErrorInFunction - << "attempted assignment to self" << abort(FatalError); - } - - if (capacity_ >= lst.size()) - { - // can copy w/o reallocating, match initial size to avoid reallocation - Field<T>::size(lst.size()); - Field<T>::operator=(lst); + << "Attempted assignment to self" << abort(FatalError); } - else - { - // make everything available for the copy operation - Field<T>::size(capacity_); - Field<T>::operator=(lst); - capacity_ = Field<T>::size(); - } + assignDynField(lst); } -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator= +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::operator= ( const UList<T>& lst ) { - if (capacity_ >= lst.size()) - { - // can copy w/o reallocating, match initial size to avoid reallocation - Field<T>::size(lst.size()); - Field<T>::operator=(lst); - } - else - { - // make everything available for the copy operation - Field<T>::size(capacity_); - - Field<T>::operator=(lst); - capacity_ = Field<T>::size(); - } + assignDynField(lst); } diff --git a/src/OpenFOAM/fields/Fields/Field/FieldM.H b/src/OpenFOAM/fields/Fields/Field/FieldM.H index 28d4788c1764b58ce4aa49545629ce486fe15a54..b1682bf6d7aa6f2b5ca2a03d832ff23009bc03bd 100644 --- a/src/OpenFOAM/fields/Fields/Field/FieldM.H +++ b/src/OpenFOAM/fields/Fields/Field/FieldM.H @@ -56,7 +56,8 @@ void checkFields FatalErrorInFunction << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')' << " and Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')' - << endl << " for operation " << op + << endl + << " for operation " << op << abort(FatalError); } } @@ -76,7 +77,8 @@ void checkFields << " Field<"<<pTraits<Type1>::typeName<<"> f1("<<f1.size()<<')' << ", Field<"<<pTraits<Type2>::typeName<<"> f2("<<f2.size()<<')' << " and Field<"<<pTraits<Type3>::typeName<<"> f3("<<f3.size()<<')' - << endl << " for operation " << op + << endl + << " for operation " << op << abort(FatalError); } } @@ -107,295 +109,306 @@ void checkFields // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// member function : this f1 OP fUNC f2 +// Member function : f1 OP Func f2 #define TFOR_ALL_F_OP_FUNC_F(typeF1, f1, OP, FUNC, typeF2, f2) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2)"); \ \ - /* set access to f1, f2 and f3 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: f1 OP FUNC(f2) */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i)); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP FUNC(f2P[i]); \ + } #define TFOR_ALL_F_OP_F_FUNC(typeF1, f1, OP, typeF2, f2, FUNC) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP " f2" #FUNC); \ \ - /* set access to f1, f2 and f3 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: f1 OP f2.FUNC() */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i).FUNC(); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP (f2P[i]).FUNC(); \ + } -// member function : this field f1 OP fUNC f2, f3 +// Member function : this field f1 OP FUNC(f2, f3) -#define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3)\ +#define TFOR_ALL_F_OP_FUNC_F_F(typeF1, f1, OP, FUNC, typeF2, f2, typeF3, f3) \ \ - /* check the three fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, f3, "f1 " #OP " " #FUNC "(f2, f3)"); \ \ - /* set access to f1, f2 and f3 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ List_CONST_ACCESS(typeF3, f3, f3P); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: f1 OP FUNC(f2, f3) */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) \ - OP FUNC(List_ELEM(f2, f2P, i), List_ELEM(f3, f3P, i)); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP FUNC((f2P[i]), (f3P[i])); \ + } -// member function : this field f1 OP fUNC f2, f3 +// Member function : s OP FUNC(f1, f2) #define TFOR_ALL_S_OP_FUNC_F_F(typeS, s, OP, FUNC, typeF1, f1, typeF2, f2) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "s " #OP " " #FUNC "(f1, f2)"); \ \ - /* set access to f1 and f2 at end of each field */ \ + /* Field access */ \ List_CONST_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing s OP FUNC(f1, f2) */ \ + /* Loop: s OP FUNC(f1, f2) */ \ List_FOR_ALL(f1, i) \ - (s) OP FUNC(List_ELEM(f1, f1P, i), List_ELEM(f2, f2P, i)); \ - List_END_FOR_ALL \ + { \ + (s) OP FUNC((f1P[i]), (f2P[i])); \ + } -// member function : this f1 OP fUNC f2, s +// Member function : this f1 OP FUNC(f2, s) #define TFOR_ALL_F_OP_FUNC_F_S(typeF1, f1, OP, FUNC, typeF2, f2, typeS, s) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP " " #FUNC "(f2, s)"); \ \ - /* set access to f1, f2 and f3 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: f1 OP FUNC(f2, s) */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP FUNC(List_ELEM(f2, f2P, i), (s)); \ - List_END_FOR_ALL + { \ + (f1P[i]) OP FUNC((f2P[i]), (s)); \ + } -// member function : s1 OP fUNC f, s2 +// Member function : s1 OP FUNC(f, s2) #define TFOR_ALL_S_OP_FUNC_F_S(typeS1, s1, OP, FUNC, typeF, f, typeS2, s2) \ \ - /* set access to f at end of field */ \ + /* Field access */ \ List_CONST_ACCESS(typeF, f, fP); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: s1 OP FUNC(f, s2) */ \ List_FOR_ALL(f, i) \ - (s1) OP FUNC(List_ELEM(f, fP, i), (s2)); \ - List_END_FOR_ALL \ + { \ + (s1) OP FUNC((fP[i]), (s2)); \ + } -// member function : this f1 OP fUNC s, f2 +// Member function : this f1 OP FUNC(s, f2) #define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP " " #FUNC "(s, f2)"); \ \ - /* set access to f1, f2 and f3 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: f1 OP1 f2 OP2 f3 */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP FUNC((s), List_ELEM(f2, f2P, i)); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP FUNC((s), (f2P[i])); \ + } -// member function : this f1 OP fUNC s, f2 +// Member function : this f1 OP FUNC(s1, s2) -#define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2)\ +#define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2) \ \ - /* set access to f1 at end of field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ \ - /* loop through fields performing f1 OP1 FUNC(s1, s2) */ \ + /* Loop: f1 OP FUNC(s1, s2) */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP FUNC((s1), (s2)); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP FUNC((s1), (s2)); \ + } -// member function : this f1 OP1 f2 OP2 FUNC s +// Member function : this f1 OP f2 FUNC(s) #define TFOR_ALL_F_OP_F_FUNC_S(typeF1, f1, OP, typeF2, f2, FUNC, typeS, s) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP " f2 " #FUNC "(s)"); \ \ - /* set access to f1, f2 and f3 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: f1 OP f2 FUNC(s) */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i) FUNC((s)); \ - List_END_FOR_ALL \ - + { \ + (f1P[i]) OP (f2P[i]) FUNC((s)); \ + } -// define high performance macro functions for Field<Type> operations -// member operator : this field f1 OP1 f2 OP2 f3 +// Member operator : this field f1 OP1 f2 OP2 f3 #define TFOR_ALL_F_OP_F_OP_F(typeF1, f1, OP1, typeF2, f2, OP2, typeF3, f3) \ \ - /* check the three fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, f3, "f1 " #OP1 " f2 " #OP2 " f3"); \ \ - /* set access to f1, f2 and f3 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ List_CONST_ACCESS(typeF3, f3, f3P); \ \ - /* loop through fields performing f1 OP1 f2 OP2 f3 */ \ + /* Loop: f1 OP1 f2 OP2 f3 */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i) \ - OP2 List_ELEM(f3, f3P, i); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP1 (f2P[i]) OP2 (f3P[i]); \ + } -// member operator : this field f1 OP1 s OP2 f2 +// Member operator : this field f1 OP1 s OP2 f2 #define TFOR_ALL_F_OP_S_OP_F(typeF1, f1, OP1, typeS, s, OP2, typeF2, f2) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP1 " s " #OP2 " f2"); \ \ - /* set access to f1 and f2 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 s OP2 f2 */ \ + /* Loop: f1 OP1 s OP2 f2 */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP1 (s) OP2 List_ELEM(f2, f2P, i); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP1 (s) OP2 (f2P[i]); \ + } -// member operator : this field f1 OP1 f2 OP2 s +// Member operator : this field f1 OP1 f2 OP2 s #define TFOR_ALL_F_OP_F_OP_S(typeF1, f1, OP1, typeF2, f2, OP2, typeS, s) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP1 " f2 " #OP2 " s"); \ \ - /* set access to f1 and f2 at end of each field */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 s OP2 f2 */ \ + /* Loop f1 OP1 s OP2 f2 */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP1 List_ELEM(f2, f2P, i) OP2 (s); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP1 (f2P[i]) OP2 (s); \ + } -// member operator : this field f1 OP f2 +// Member operator : this field f1 OP f2 #define TFOR_ALL_F_OP_F(typeF1, f1, OP, typeF2, f2) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, "f1 " #OP " f2"); \ \ - /* set pointer to f1P at end of f1 and */ \ - /* f2.p at end of f2 */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP f2 */ \ + /* Loop: f1 OP f2 */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP List_ELEM(f2, f2P, i); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP (f2P[i]); \ + } -// member operator : this field f1 OP1 OP2 f2 +// Member operator : this field f1 OP1 OP2 f2 #define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2) \ \ - /* check the two fields have same Field<Type> mesh */ \ + /* Check fields have same size */ \ checkFields(f1, f2, #OP1 " " #OP2 " f2"); \ \ - /* set pointer to f1P at end of f1 and */ \ - /* f2.p at end of f2 */ \ + /* Field access */ \ List_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through fields performing f1 OP1 OP2 f2 */ \ + /* Loop: f1 OP1 OP2 f2 */ \ List_FOR_ALL(f1, i) \ - List_ELEM(f1, f1P, i) OP1 OP2 List_ELEM(f2, f2P, i); \ - List_END_FOR_ALL \ + { \ + (f1P[i]) OP1 OP2 (f2P[i]); \ + } -// member operator : this field f OP s +// Member operator : this field f OP s #define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s) \ \ - /* set access to f at end of field */ \ + /* Field access */ \ List_ACCESS(typeF, f, fP); \ \ - /* loop through field performing f OP s */ \ + /* Loop: f OP s */ \ List_FOR_ALL(f, i) \ - List_ELEM(f, fP, i) OP (s); \ - List_END_FOR_ALL \ + { \ + (fP[i]) OP (s); \ + } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// define high performance macro functions for Field<Type> friend functions -// friend operator function : s OP f, allocates storage for s +// Friend operator function : s OP f, allocates storage for s #define TFOR_ALL_S_OP_F(typeS, s, OP, typeF, f) \ \ - /* set access to f at end of field */ \ + /* Field access */ \ List_CONST_ACCESS(typeF, f, fP); \ \ - /* loop through field performing s OP f */ \ + /* Loop: s OP f */ \ List_FOR_ALL(f, i) \ - (s) OP List_ELEM(f, fP, i); \ - List_END_FOR_ALL + { \ + (s) OP (fP[i]); \ + } -// friend operator function : s OP1 f1 OP2 f2, allocates storage for s +// Friend operator function : s OP1 f1 OP2 f2, allocates storage for s #define TFOR_ALL_S_OP_F_OP_F(typeS, s, OP1, typeF1, f1, OP2, typeF2, f2) \ \ - /* set access to f1 and f2 at end of each field */ \ + /* Field access */ \ List_CONST_ACCESS(typeF1, f1, f1P); \ List_CONST_ACCESS(typeF2, f2, f2P); \ \ - /* loop through field performing s OP f */ \ + /* Loop: s OP f */ \ List_FOR_ALL(f1, i) \ - (s) OP1 List_ELEM(f1, f1P, i) OP2 List_ELEM(f2, f2P, i); \ - List_END_FOR_ALL + { \ + (s) OP1 (f1P[i]) OP2 (f2P[i]); \ + } -// friend operator function : s OP FUNC(f), allocates storage for s +// Friend operator function : s OP FUNC(f), allocates storage for s #define TFOR_ALL_S_OP_FUNC_F(typeS, s, OP, FUNC, typeF, f) \ \ - /* set access to f at end of field */ \ + /* Field access */ \ List_CONST_ACCESS(typeF, f, fP); \ \ - /* loop through field performing s OP f */ \ + /* Loop: s OP FUNC(f) */ \ List_FOR_ALL(f, i) \ - (s) OP FUNC(List_ELEM(f, fP, i)); \ - List_END_FOR_ALL + { \ + (s) OP FUNC(fP[i]); \ + } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/include/stdFoam.H b/src/OpenFOAM/include/stdFoam.H index 59b0d9f704a8463605ead378ed254d83868f04dd..3141c38351233067ba8c00706920a6e13dc8bceb 100644 --- a/src/OpenFOAM/include/stdFoam.H +++ b/src/OpenFOAM/include/stdFoam.H @@ -25,12 +25,13 @@ Namespace stdFoam Description - Includes some global templates and macros used by OpenFOAM. + Some global templates and macros used by OpenFOAM and some standard + C++ headers. - Some of the templates are defined here correspond to useful + Some of the templates defined here correspond to useful std templates that are part of future C++ standards, or that are in a state of change. Defining them here provides some additional - control over which definition are used within the OpenFOAM code-base. + control over which definitions are used within the OpenFOAM code-base. SeeAlso - http://en.cppreference.com/w/cpp/iterator/end @@ -42,6 +43,7 @@ SeeAlso #define StdFoam_H #include <initializer_list> +#include <utility> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -114,12 +116,12 @@ constexpr auto cend(const C& c) -> decltype(c.end()) // } // \endcode // \sa forAllConstIters, forAllIter, forAllConstIters -#define forAllIters(container,it) \ +#define forAllIters(container,iter) \ for \ ( \ - auto it = stdFoam::begin(container); \ - it != stdFoam::end(container); \ - ++it \ + auto iter = stdFoam::begin(container); \ + iter != stdFoam::end(container); \ + ++iter \ ) @@ -132,12 +134,12 @@ constexpr auto cend(const C& c) -> decltype(c.end()) // } // \endcode // \sa forAllIters, forAllIter, forAllConstIter -#define forAllConstIters(container,cit) \ +#define forAllConstIters(container,iter) \ for \ ( \ - auto cit = stdFoam::cbegin(container); \ - cit != stdFoam::cend(container); \ - ++cit \ + auto iter = stdFoam::cbegin(container); \ + iter != stdFoam::cend(container); \ + ++iter \ ) diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edge.H b/src/OpenFOAM/meshes/meshShapes/edge/edge.H index aecb9a9c2e416c1acc4b055fcf1c4ff12e162b17..dabdc197efa866c56d3c5818af7682019c346e42 100644 --- a/src/OpenFOAM/meshes/meshShapes/edge/edge.H +++ b/src/OpenFOAM/meshes/meshShapes/edge/edge.H @@ -28,7 +28,7 @@ Description An edge is a list of two point labels. The functionality it provides supports the discretisation on a 2-D flat mesh. - The edge is implemented as a FixedList of labels. + The edge is implemented as a Pair/FixedList of labels. As well as geometrically relevant methods, it also provides methods similar to HashSet for additional convenience. Valid point labels are always non-negative (since they correspond to @@ -37,6 +37,7 @@ Description can be filled with a HashSet-like functionality. SourceFiles + edge.C edgeI.H \*---------------------------------------------------------------------------*/ @@ -44,10 +45,9 @@ SourceFiles #ifndef edge_H #define edge_H -#include "FixedList.H" #include "labelPair.H" -#include "pointField.H" #include "linePointRef.H" +#include "pointField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -60,7 +60,7 @@ namespace Foam class edge : - public FixedList<label, 2> + public labelPair { // Private Member Functions @@ -93,19 +93,19 @@ public: //- Construct null with invalid point labels (-1) inline edge(); - //- Construct from components + //- Construct from two point labels inline edge(const label from, const label to); - //- Construct, optionally sorted with start less-than end - inline edge(const label from, const label to, const bool doSort); - - //- Construct from two labels + //- Construct from pair of labels inline edge(const labelPair& pair); - //- Construct from FixedList + //- Construct from list inline edge(const FixedList<label, 2>& lst); - //- Construct, optionally sorted with start less-than end + //- Construct from two point labels, sorted with first less-than second + inline edge(const label from, const label to, const bool doSort); + + //- Construct from list, sorted with first less-than second inline edge(const FixedList<label, 2>& lst, const bool doSort); //- Construct from Istream @@ -116,16 +116,26 @@ public: // Access - //- Return start vertex label + //- Return first vertex label + using labelPair::first; + + //- Return last (second) vertex label + using labelPair::last; + + //- Return second (last) vertex label + using labelPair::second; + + + //- Return start (first) vertex label inline label start() const; - //- Return start vertex label + //- Return start (first) vertex label inline label& start(); - //- Return end vertex label + //- Return end (last/second) vertex label inline label end() const; - //- Return end vertex label + //- Return end (last/second) vertex label inline label& end(); //- Return reverse edge as copy. @@ -143,10 +153,6 @@ public: // No special handling of negative point labels. inline label maxVertex() const; - //- True if start() is less-than end() - // No special handling of negative point labels. - inline bool sorted() const; - //- Return true if point label is found in edge. // Always false for a negative label. inline bool found(const label pointLabel) const; @@ -175,14 +181,6 @@ public: // Return the effective size after collapsing. inline label collapse(); - //- Flip the edge in-place. - // No special handling of negative point labels. - inline void flip(); - - //- Sort so that start() is less-than end() - // No special handling of negative point labels. - inline void sort(); - // Hash-like functions @@ -211,8 +209,8 @@ public: // Returns true on success. Negative labels never insert. // Return the number of slots filled. // Similar to a HashTable::insert(). - template<unsigned AnySize> - inline label insert(const FixedList<label, AnySize>& lst); + template<unsigned Size> + inline label insert(const FixedList<label, Size>& lst); //- Fill open slots with the indices if they did not previously exist. // Returns true on success. Negative labels never insert. @@ -231,8 +229,8 @@ public: //- Remove existing indices from the edge and set locations to '-1'. // Returns the number of changes. - template<unsigned AnySize> - inline label erase(const FixedList<label, AnySize>& lst); + template<unsigned Size> + inline label erase(const FixedList<label, Size>& lst); //- Remove existing indices from the edge and set locations to '-1'. // Returns the number of changes. @@ -265,7 +263,7 @@ public: // Comparison //- Compare edges - // Returns: + // \return // - 0: different // - +1: identical values and order used // - -1: identical values, but in different order @@ -274,7 +272,14 @@ public: }; -// Global Operators +// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * // + +//- Return reverse of an edge +inline edge reverse(const edge& e) +{ + return edge(e.second(), e.first()); +} + //- Compare edges for equal content, ignoring orientation inline bool operator==(const edge& a, const edge& b); @@ -290,15 +295,15 @@ inline unsigned Hash<edge>::operator()(const edge& e, unsigned seed) const { unsigned val = seed; - if (e[0] < e[1]) + if (e.first() < e.second()) { - val = Hash<label>()(e[0], val); - val = Hash<label>()(e[1], val); + val = Hash<label>()(e.first(), val); + val = Hash<label>()(e.second(), val); } else { - val = Hash<label>()(e[1], val); - val = Hash<label>()(e[0], val); + val = Hash<label>()(e.second(), val); + val = Hash<label>()(e.first(), val); } return val; @@ -313,7 +318,7 @@ inline unsigned Hash<edge>::operator()(const edge& e) const return Hash<edge>()(e, 0); } - +// Edges are a pair of labels - thus contiguous template<> inline bool contiguous<edge>() {return true;} diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H index e4ca81e9386f6abb51f0abc14ba2035222656268..db939da2aac5c7670af599319bf2c63d453f64e6 100644 --- a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H +++ b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H @@ -24,24 +24,12 @@ License \*---------------------------------------------------------------------------*/ #include "IOstreams.H" -#include "Swap.H" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // inline int Foam::edge::compare(const edge& a, const edge& b) { - if (a[0] == b[0] && a[1] == b[1]) - { - return 1; - } - else if (a[0] == b[1] && a[1] == b[0]) - { - return -1; - } - else - { - return 0; - } + return labelPair::compare(a, b); } @@ -56,7 +44,7 @@ inline Foam::label Foam::edge::insertMultiple { // Available slots. // Don't use count() since it has special treatment for duplicates - const int maxChange = (start() < 0 ? 1 : 0) + (end() < 0 ? 1 : 0); + const int maxChange = (first() < 0 ? 1 : 0) + (second() < 0 ? 1 : 0); int changed = 0; if (maxChange) @@ -86,7 +74,7 @@ inline Foam::label Foam::edge::eraseMultiple { // Occupied slots. // Don't use count() since it has special treatment for duplicates - const int maxChange = (start() >= 0 ? 1 : 0) + (end() >= 0 ? 1 : 0); + const int maxChange = (first() >= 0 ? 1 : 0) + (second() >= 0 ? 1 : 0); int changed = 0; if (maxChange) @@ -109,64 +97,43 @@ inline Foam::label Foam::edge::eraseMultiple inline Foam::edge::edge() : - FixedList<label, 2>(-1) + labelPair(-1, -1) {} inline Foam::edge::edge(const label from, const label to) -{ - start() = from; - end() = to; -} - - -inline Foam::edge::edge(const label from, const label to, const bool doSort) -{ - if (doSort && from > to) - { - start() = to; - end() = from; - } - else - { - start() = from; - end() = to; - } -} +: + labelPair(from, to) +{} inline Foam::edge::edge(const labelPair& pair) -{ - start() = pair.first(); - end() = pair.second(); -} +: + labelPair(pair.first(), pair.second()) +{} inline Foam::edge::edge(const FixedList<label, 2>& lst) -{ - start() = lst[0]; - end() = lst[1]; -} +: + labelPair(lst.first(), lst.last()) +{} + + +inline Foam::edge::edge(const label from, const label to, const bool doSort) +: + labelPair(from, to, doSort) +{} inline Foam::edge::edge(const FixedList<label, 2>& lst, const bool doSort) -{ - if (doSort && lst[0] > lst[1]) - { - start() = lst[1]; - end() = lst[0]; - } - else - { - start() = lst[0]; - end() = lst[1]; - } -} +: + labelPair(lst, doSort) +{} inline Foam::edge::edge(Istream& is) : - FixedList<label, 2>(is) + labelPair(is) {} @@ -174,42 +141,47 @@ inline Foam::edge::edge(Istream& is) inline Foam::label Foam::edge::start() const { - return operator[](0); + return first(); } inline Foam::label& Foam::edge::start() { - return operator[](0); + return first(); } inline Foam::label Foam::edge::end() const { - return operator[](1); + return second(); } + inline Foam::label& Foam::edge::end() { - return operator[](1); + return second(); } inline Foam::label Foam::edge::minVertex() const { - return (start() < end() ? start() : end()); + return (first() < second() ? first() : second()); } inline Foam::label Foam::edge::maxVertex() const { - return (start() > end() ? start() : end()); + return (first() > second() ? first() : second()); } inline bool Foam::edge::found(const label pointLabel) const { // -1: always false - return (pointLabel >= 0 && (pointLabel == start() || pointLabel == end())); + return + ( + pointLabel >= 0 + && (pointLabel == first() || pointLabel == second()) + ); } @@ -218,11 +190,11 @@ inline Foam::label Foam::edge::which(const label pointLabel) const // -1: always false if (pointLabel >= 0) { - if (pointLabel == start()) + if (pointLabel == first()) { return 0; } - if (pointLabel == end()) + if (pointLabel == second()) { return 1; } @@ -233,43 +205,39 @@ inline Foam::label Foam::edge::which(const label pointLabel) const inline bool Foam::edge::connects(const edge& other) const { - return (other.found(start()) || other.found(end())); + return (other.found(first()) || other.found(second())); } inline Foam::label Foam::edge::commonVertex(const edge& other) const { - if (other.found(start())) - { - return start(); - } - else if (other.found(end())) + if (other.found(first())) { - return end(); + return first(); } - else + if (other.found(second())) { - // No shared vertex. - return -1; + return second(); } + + // No shared vertex. + return -1; } inline Foam::label Foam::edge::otherVertex(const label index) const { - if (index == start()) - { - return end(); - } - else if (index == end()) + if (index == first()) { - return start(); + return second(); } - else + if (index == second()) { - // The given vertex is not on the edge in the first place. - return -1; + return first(); } + + // The given vertex is not on the edge in the first place. + return -1; } @@ -280,12 +248,12 @@ inline Foam::label Foam::edge::collapse() // catch any '-1' (eg, if called multiple times) label n = 2; - if (start() == end() || end() < 0) + if (first() == second() || second() < 0) { - end() = -1; + second() = -1; --n; } - if (start() < 0) + if (first() < 0) { --n; } @@ -294,48 +262,27 @@ inline Foam::label Foam::edge::collapse() } -inline bool Foam::edge::sorted() const -{ - return (start() < end()); -} - - -inline void Foam::edge::sort() -{ - if (start() > end()) - { - flip(); - } -} - - -inline void Foam::edge::flip() -{ - Swap(operator[](0), operator[](1)); -} - - inline Foam::edge Foam::edge::reverseEdge() const { - return edge(end(), start()); + return edge(second(), first()); } inline void Foam::edge::clear() { - start() = -1; - end() = -1; + first() = -1; + second() = -1; } inline Foam::label Foam::edge::count() const { label n = 2; - if (start() == end() || end() < 0) + if (first() == second() || second() < 0) { --n; } - if (start() < 0) + if (first() < 0) { --n; } @@ -346,7 +293,7 @@ inline Foam::label Foam::edge::count() const inline bool Foam::edge::empty() const { - return (start() < 0 && end() < 0); + return (first() < 0 && second() < 0); } @@ -358,21 +305,21 @@ inline bool Foam::edge::insert(const label index) return false; } - if (start() < 0) + if (first() < 0) { - // Store at [0], if not duplicate of [1] - if (index != end()) + // Store at first, if not duplicate of second + if (index != second()) { - start() = index; + first() = index; return true; } } - else if (end() < 0) + else if (second() < 0) { - // Store at [1], if not duplicate of [0] - if (index != start()) + // Store at second, if not duplicate of first + if (index != first()) { - end() = index; + second() = index; return true; } } @@ -387,8 +334,8 @@ inline Foam::label Foam::edge::insert(const UList<label>& lst) } -template<unsigned AnySize> -inline Foam::label Foam::edge::insert(const FixedList<label, AnySize>& lst) +template<unsigned Size> +inline Foam::label Foam::edge::insert(const FixedList<label, Size>& lst) { return insertMultiple(lst.begin(), lst.end()); } @@ -409,16 +356,16 @@ inline Foam::label Foam::edge::erase(const label index) } label n = 0; - if (index == start()) + if (index == first()) { - start() = -1; + first() = -1; ++n; } // Automatically handle duplicates, which should not have been there anyhow - if (index == end()) + if (index == second()) { - end() = -1; + second() = -1; ++n; } @@ -432,8 +379,8 @@ inline Foam::label Foam::edge::erase(const UList<label>& lst) } -template<unsigned AnySize> -inline Foam::label Foam::edge::erase(const FixedList<label, AnySize>& lst) +template<unsigned Size> +inline Foam::label Foam::edge::erase(const FixedList<label, Size>& lst) { return eraseMultiple(lst.begin(), lst.end()); } @@ -450,7 +397,7 @@ inline Foam::label Foam::edge::erase(std::initializer_list<label> lst) inline Foam::point Foam::edge::centre(const UList<point>& pts) const { #ifdef FULLDEBUG - if (start() < 0 || end() < 0) + if (first() < 0 || second() < 0) { FatalErrorInFunction << "negative point index on edge " << *this @@ -458,14 +405,14 @@ inline Foam::point Foam::edge::centre(const UList<point>& pts) const } #endif - return 0.5*(pts[start()] + pts[end()]); + return 0.5*(pts[first()] + pts[second()]); } inline Foam::vector Foam::edge::vec(const UList<point>& pts) const { #ifdef FULLDEBUG - if (start() < 0 || end() < 0) + if (first() < 0 || second() < 0) { FatalErrorInFunction << "negative point index on edge " << *this @@ -473,14 +420,14 @@ inline Foam::vector Foam::edge::vec(const UList<point>& pts) const } #endif - return pts[end()] - pts[start()]; + return pts[second()] - pts[first()]; } inline Foam::vector Foam::edge::unitVec(const UList<point>& pts) const { #ifdef FULLDEBUG - if (start() < 0 || end() < 0) + if (first() < 0 || second() < 0) { FatalErrorInFunction << "negative point index on edge " << *this @@ -488,7 +435,7 @@ inline Foam::vector Foam::edge::unitVec(const UList<point>& pts) const } #endif - Foam::vector v = pts[end()] - pts[start()]; + Foam::vector v = pts[second()] - pts[first()]; v /= ::Foam::mag(v) + VSMALL; return v; @@ -504,7 +451,7 @@ inline Foam::scalar Foam::edge::mag(const UList<point>& pts) const inline Foam::linePointRef Foam::edge::line(const UList<point>& pts) const { #ifdef FULLDEBUG - if (start() < 0 || end() < 0) + if (first() < 0 || second() < 0) { FatalErrorInFunction << "negative point index on edge " << *this @@ -512,7 +459,7 @@ inline Foam::linePointRef Foam::edge::line(const UList<point>& pts) const } #endif - return linePointRef(pts[start()], pts[end()]); + return linePointRef(pts[first()], pts[second()]); } diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.C b/src/OpenFOAM/meshes/meshShapes/face/face.C index 9900b4e6f3a926dca1f453fc26c718612664a17a..6f44cb0314a258fa76ac943622f80a31e4195cf8 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/face.C +++ b/src/OpenFOAM/meshes/meshShapes/face/face.C @@ -773,14 +773,14 @@ int Foam::face::edgeDirection(const edge& e) const { forAll(*this, i) { - if (operator[](i) == e.start()) + if (operator[](i) == e.first()) { - if (operator[](rcIndex(i)) == e.end()) + if (operator[](rcIndex(i)) == e.second()) { // Reverse direction return -1; } - else if (operator[](fcIndex(i)) == e.end()) + else if (operator[](fcIndex(i)) == e.second()) { // Forward direction return 1; @@ -789,14 +789,14 @@ int Foam::face::edgeDirection(const edge& e) const // No match return 0; } - else if (operator[](i) == e.end()) + else if (operator[](i) == e.second()) { - if (operator[](rcIndex(i)) == e.start()) + if (operator[](rcIndex(i)) == e.first()) { // Forward direction return 1; } - else if (operator[](fcIndex(i)) == e.start()) + else if (operator[](fcIndex(i)) == e.first()) { // Reverse direction return -1; diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H index 822e3c4f9a6fc3f146480ee1ada390afb311497f..0866a7eead9e80ce723a10b370b90b17a9885bca 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/face.H +++ b/src/OpenFOAM/meshes/meshShapes/face/face.H @@ -50,6 +50,7 @@ SourceFiles #include "faceListFwd.H" #include "intersection.H" #include "pointHit.H" +#include "FixedList.H" #include "ListListOps.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -62,8 +63,7 @@ namespace Foam class face; class triFace; -template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> -class DynamicList; +template<class T, int SizeMin> class DynamicList; inline Istream& operator>>(Istream& is, face& f); @@ -107,15 +107,15 @@ class face //- Enumeration listing the modes for split() enum splitMode { - COUNTTRIANGLE, // count if split into triangles - COUNTQUAD, // count if split into triangles&quads - SPLITTRIANGLE, // split into triangles - SPLITQUAD // split into triangles&quads + COUNTTRIANGLE, //!< count if split into triangles + COUNTQUAD, //!< count if split into triangles and quads + SPLITTRIANGLE, //!< split into triangles + SPLITQUAD //!< split into triangles and quads }; - //- Split face into triangles or triangles&quads. + //- Split face into triangles or triangles and quads. // Stores results quadFaces[quadI], triFaces[triI] - // Returns number of new faces created + // \return number of new faces created label split ( const splitMode mode, @@ -153,12 +153,19 @@ public: //- Construct from list of labels explicit inline face(const labelUList& lst); + //- Construct from list of labels + template<unsigned Size> + explicit inline face(const FixedList<label, Size>& lst); + //- Construct from an initializer list of labels explicit inline face(std::initializer_list<label> lst); - //- Construct by transferring the parameter contents + //- Transfer (move) construct explicit inline face(const Xfer<labelList>& lst); + //- Move construct + explicit inline face(labelList&& lst); + //- Copy construct from triFace face(const triFace& f); @@ -312,8 +319,8 @@ public: //- Return n-th face edge inline edge faceEdge(const label n) const; - //- Return the edge direction on the face - // Returns: + //- The edge direction on the face + // \return // - 0: edge not found on the face // - +1: forward (counter-clockwise) on the face // - -1: reverse (clockwise) on the face @@ -344,11 +351,11 @@ public: //- Split into triangles using existing points. // Append to DynamicList. // Returns number of faces created. - template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> + template<int SizeMin> label triangles ( const UList<point>& points, - DynamicList<face, SizeInc, SizeMult, SizeDiv>& triFaces + DynamicList<face, SizeMin>& triFaces ) const; //- Number of triangles and quads after splitting @@ -374,9 +381,10 @@ public: ) const; //- Compare faces - // 0: different - // +1: identical - // -1: same face, but different orientation + // \return + // - 0: different + // - +1: identical + // - -1: same face, but different orientation static int compare(const face& a, const face& b); //- Return true if the faces have the same vertices diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceI.H b/src/OpenFOAM/meshes/meshShapes/face/faceI.H index d312560843c35033a0246ebfae1255704dda80b7..0ec413433d5916517114ef130aa9cefc878a6a96 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/faceI.H +++ b/src/OpenFOAM/meshes/meshShapes/face/faceI.H @@ -57,6 +57,13 @@ inline Foam::face::face(const labelUList& lst) {} +template<unsigned Size> +inline Foam::face::face(const FixedList<label, Size>& lst) +: + labelList(lst) +{} + + inline Foam::face::face(std::initializer_list<label> lst) : labelList(lst) @@ -69,6 +76,12 @@ inline Foam::face::face(const Xfer<labelList>& lst) {} +inline Foam::face::face(labelList&& lst) +: + labelList(std::move(lst)) +{} + + inline Foam::face::face(Istream& is) { is >> *this; @@ -87,9 +100,10 @@ inline Foam::pointField Foam::face::points // For each point in list, set it to the point in 'pnts' addressed // by 'labs' - forAll(p, i) + label i = 0; + for (const label pointi : *this) { - p[i] = meshPoints[operator[](i)]; + p[i++] = meshPoints[pointi]; } // Return list @@ -124,13 +138,13 @@ inline bool Foam::face::found(const label globalIndex) const inline Foam::label Foam::face::nextLabel(const label i) const { - return operator[](fcIndex(i)); + return this->fcValue(i); } inline Foam::label Foam::face::prevLabel(const label i) const { - return operator[](rcIndex(i)); + return this->rcValue(i); } diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C b/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C index 112a5703fbe6b7803dd133252aa9190974698f9f..9f9bb58844ea96b96fc5483a3c32bf51e61f3407 100644 --- a/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C +++ b/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C @@ -28,11 +28,11 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +template<int SizeMin> Foam::label Foam::face::triangles ( const UList<point>& points, - DynamicList<face, SizeInc, SizeMult, SizeDiv>& triFaces + DynamicList<face, SizeMin>& triFaces ) const { label triI = triFaces.size(); diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H index 301b845d112a82499420b4de2eeddd3daf6f4477..ea18b760194a8d3708a028dd8eeaacd1c40e7e6c 100644 --- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H +++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H @@ -86,7 +86,7 @@ public: const label c ); - //- Construct from a list of 3 labels. + //- Copy construct from a list of 3 labels. explicit inline triFace(const labelUList& lst); //- Construct from an initializer list of 3 labels @@ -223,14 +223,14 @@ public: inline edge faceEdge(const label n) const; //- Return the edge direction on the face - // Returns: + // \return // - +1: forward (counter-clockwise) on the face // - -1: reverse (clockwise) on the face // - 0: edge not found on the face inline int edgeDirection(const edge& e) const; //- Compare triFaces - // Returns: + // \return: // - 0: different // - +1: identical // - -1: same face, but different orientation diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H index ae2545a7aa233e8542a9e4e644e1f098bd6b3c09..bc99e45518cd599c81015c72f062e54ca3b4bf56 100644 --- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H +++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H @@ -147,13 +147,7 @@ inline Foam::pointField Foam::triFace::points(const UList<point>& points) const inline Foam::face Foam::triFace::triFaceFace() const { - Foam::face f(3); - - f[0] = operator[](0); - f[1] = operator[](1); - f[2] = operator[](2); - - return f; + return Foam::face(*this); } @@ -342,14 +336,14 @@ inline Foam::edgeList Foam::triFace::edges() const { edgeList e(3); - e[0].start() = operator[](0); - e[0].end() = operator[](1); + e[0].first() = operator[](0); + e[0].second() = operator[](1); - e[1].start() = operator[](1); - e[1].end() = operator[](2); + e[1].first() = operator[](1); + e[1].second() = operator[](2); - e[2].start() = operator[](2); - e[2].end() = operator[](0); + e[2].first() = operator[](2); + e[2].second() = operator[](0); return e; } @@ -369,18 +363,18 @@ inline int Foam::triFace::edgeDirection(const edge& e) const { if ( - (operator[](0) == e.start() && operator[](1) == e.end()) - || (operator[](1) == e.start() && operator[](2) == e.end()) - || (operator[](2) == e.start() && operator[](0) == e.end()) + (operator[](0) == e.first() && operator[](1) == e.second()) + || (operator[](1) == e.first() && operator[](2) == e.second()) + || (operator[](2) == e.first() && operator[](0) == e.second()) ) { return 1; } else if ( - (operator[](0) == e.end() && operator[](1) == e.start()) - || (operator[](1) == e.end() && operator[](2) == e.start()) - || (operator[](2) == e.end() && operator[](0) == e.start()) + (operator[](0) == e.second() && operator[](1) == e.first()) + || (operator[](1) == e.second() && operator[](2) == e.first()) + || (operator[](2) == e.second() && operator[](0) == e.first()) ) { return -1; diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C b/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C index ee160048be8d0b8c34f8c21f4e85cfc340f27081..5603bda172b218c329a10cd7a710ebec8cd01b43 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshFromShapeMesh.C @@ -38,8 +38,7 @@ Foam::labelListList Foam::polyMesh::cellShapePointCells const cellShapeList& c ) const { - List<DynamicList<label, primitiveMesh::cellsPerPoint_>> - pc(points().size()); + List<DynamicList<label>> pc(points().size()); // For each cell forAll(c, i) @@ -51,8 +50,7 @@ Foam::labelListList Foam::polyMesh::cellShapePointCells { // Set working point label label curPoint = labels[j]; - DynamicList<label, primitiveMesh::cellsPerPoint_>& curPointCells = - pc[curPoint]; + DynamicList<label>& curPointCells = pc[curPoint]; // Enter the cell label in the point's cell list curPointCells.append(i); diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellEdges.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellEdges.C index 1b56bd5268ca01d3b74768cd3e82cd90927aff15..f130c8975bb0c6c798f540f2716c0988e5dd7dad 100644 --- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellEdges.C +++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellEdges.C @@ -60,7 +60,7 @@ void Foam::primitiveMesh::calcCellEdges() const else { // Set up temporary storage - List<DynamicList<label, edgesPerCell_>> ce(nCells()); + List<DynamicList<label>> ce(nCells()); // Get reference to faceCells and faceEdges @@ -71,7 +71,7 @@ void Foam::primitiveMesh::calcCellEdges() const // loop through the list again and add edges; checking for duplicates forAll(own, facei) { - DynamicList<label, edgesPerCell_>& curCellEdges = ce[own[facei]]; + DynamicList<label>& curCellEdges = ce[own[facei]]; const labelList& curEdges = fe[facei]; @@ -87,7 +87,7 @@ void Foam::primitiveMesh::calcCellEdges() const forAll(nei, facei) { - DynamicList<label, edgesPerCell_>& curCellEdges = ce[nei[facei]]; + DynamicList<label>& curCellEdges = ce[nei[facei]]; const labelList& curEdges = fe[facei]; diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/line.H b/src/OpenFOAM/meshes/primitiveShapes/line/line.H index 778a843ba75740616ef5922d017b94747f6a839a..a3ccc2319f24d7254408f18d1ed083dcf747432a 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/line/line.H +++ b/src/OpenFOAM/meshes/primitiveShapes/line/line.H @@ -57,10 +57,10 @@ class Ostream; template<class Point, class PointRef> class line; template<class Point, class PointRef> -inline Istream& operator>>(Istream&, line<Point, PointRef>&); +inline Istream& operator>>(Istream& is, line<Point, PointRef>& l); template<class Point, class PointRef> -inline Ostream& operator<<(Ostream&, const line<Point, PointRef>&); +inline Ostream& operator<<(Ostream& os, const line<Point, PointRef>& l); /*---------------------------------------------------------------------------*\ @@ -72,7 +72,11 @@ class line { // Private data - PointRef a_, b_; + //- First point + PointRef a_; + + //- Second point + PointRef b_; public: @@ -86,7 +90,7 @@ public: // The indices could be from edge etc. inline line ( - const UList<Point>&, + const UList<Point>& points, const FixedList<label, 2>& indices ); @@ -96,56 +100,62 @@ public: // Member functions - // Access + // Access + + //- Return first point + inline PointRef first() const; - //- Return first point - inline PointRef start() const; + //- Return second point + inline PointRef second() const; - //- Return second point - inline PointRef end() const; + //- Return first point + inline PointRef start() const; + //- Return second point + inline PointRef end() const; - // Properties - //- Return centre (centroid) - inline Point centre() const; + // Properties - //- Return scalar magnitude - inline scalar mag() const; + //- Return centre (centroid) + inline Point centre() const; - //- Return start-to-end vector - inline Point vec() const; + //- Return scalar magnitude + inline scalar mag() const; - //- Return the unit vector (start-to-end) - inline Point unitVec() const; + //- Return start-to-end vector + inline Point vec() const; - //- Return nearest distance to line from a given point - // If the nearest point is on the line, return a hit - PointHit<Point> nearestDist(const Point& p) const; + //- Return the unit vector (start-to-end) + inline Point unitVec() const; - //- Return nearest distance from line to line. Returns distance - // and sets both points (one on *this, one on the provided - // linePointRef. - scalar nearestDist - ( - const line<Point, const Point&>& edge, - Point& thisPoint, - Point& edgePoint - ) const; + //- Return nearest distance to line from a given point + // If the nearest point is on the line, return a hit + PointHit<Point> nearestDist(const Point& p) const; + + //- Return nearest distance from line to line. Returns distance + // and sets both points (one on *this, one on the provided + // linePointRef. + scalar nearestDist + ( + const line<Point, const Point&>& edge, + Point& thisPoint, + Point& edgePoint + ) const; // Ostream operator friend Istream& operator>> <Point, PointRef> ( - Istream&, - line& + Istream& is, + line& l ); friend Ostream& operator<< <Point, PointRef> ( - Ostream&, - const line& + Ostream& os, + const line& l ); }; diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H index 034f86878034c75a7e60b95cf812206f05b6ebd9..b2ee4d40ea132bfc26517b1b77617546e237aa19 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H +++ b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H @@ -57,18 +57,32 @@ inline Foam::line<Point, PointRef>::line(Istream& is) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class Point, class PointRef> -inline PointRef Foam::line<Point, PointRef>::start() const +inline PointRef Foam::line<Point, PointRef>::first() const { return a_; } + template<class Point, class PointRef> -inline PointRef Foam::line<Point, PointRef>::end() const +inline PointRef Foam::line<Point, PointRef>::second() const { return b_; } +template<class Point, class PointRef> +inline PointRef Foam::line<Point, PointRef>::start() const +{ + return first(); +} + +template<class Point, class PointRef> +inline PointRef Foam::line<Point, PointRef>::end() const +{ + return second(); +} + + template<class Point, class PointRef> inline Point Foam::line<Point, PointRef>::centre() const { @@ -110,21 +124,21 @@ Foam::PointHit<Point> Foam::line<Point, PointRef>::nearestDist Point w(p - a_); - scalar c1 = v & w; + const scalar c1 = v & w; if (c1 <= 0) { return PointHit<Point>(false, a_, Foam::mag(p - a_), true); } - scalar c2 = v & v; + const scalar c2 = v & v; if (c2 <= c1) { return PointHit<Point>(false, b_, Foam::mag(p - b_), true); } - scalar b = c1/c2; + const scalar b = c1/c2; Point pb(a_ + b*v); diff --git a/src/OpenFOAM/primitives/Pair/Pair.H b/src/OpenFOAM/primitives/Pair/Pair.H index 73b99e5c15d9bc1063b9c77ec1941d6bfa9eae46..3209f4d9421b844872c18447af9666c6fe161272 100644 --- a/src/OpenFOAM/primitives/Pair/Pair.H +++ b/src/OpenFOAM/primitives/Pair/Pair.H @@ -28,6 +28,9 @@ Description An ordered pair of two objects of type \<T\> with first() and second() elements. +SourceFiles + PairI.H + See also Foam::Tuple2 for storing two objects of dissimilar types. @@ -48,10 +51,10 @@ namespace Foam Class Pair Declaration \*---------------------------------------------------------------------------*/ -template<class Type> +template<class T> class Pair : - public FixedList<Type, 2> + public FixedList<T, 2> { public: @@ -59,131 +62,96 @@ public: // Constructors //- Null constructor - inline Pair() - {} + inline Pair(); //- Construct from components - inline Pair(const Type& f, const Type& s) - { - first() = f; - second() = s; - } + inline Pair(const T& f, const T& s); //- Construct from FixedList - inline Pair(const FixedList<Type, 2>& lst) - : - FixedList<Type, 2>(lst) - {} + inline Pair(const FixedList<T, 2>& lst); + + //- Construct, optionally sorted with first less-than second + inline Pair(const T& f, const T& s, const bool doSort); + + //- Construct, optionally sorted with first less-than second + inline Pair(const FixedList<T, 2>& lst, const bool doSort); //- Construct from Istream - inline Pair(Istream& is) - : - FixedList<Type, 2>(is) - {} + inline Pair(Istream& is); // Member Functions - //- Return first - inline const Type& first() const - { - return this->operator[](0); - } - - //- Return first - inline Type& first() - { - return this->operator[](0); - } - - //- Return second - inline const Type& second() const - { - return this->operator[](1); - } - - //- Return second - inline Type& second() - { - return this->operator[](1); - } - - //- Return other - inline const Type& other(const Type& a) const - { - if (first() == second()) - { - FatalErrorInFunction - << "Call to other only valid for Pair with differing" - << " elements:" << *this << abort(FatalError); - } - else if (first() == a) - { - return second(); - } - else - { - if (second() != a) - { - FatalErrorInFunction - << "Pair " << *this - << " does not contain " << a << abort(FatalError); - } - return first(); - } - } + // Access + + //- Return first element + using FixedList<T, 2>::first; + + //- Return last element + using FixedList<T, 2>::last; + + //- Return second element, which is also the last element + inline const T& second() const; + + //- Return second element, which is also the last element + inline T& second(); + + //- Return other element + inline const T& other(const T& a) const; + + + // Queries + + //- True if first() is less-than second() + inline bool sorted() const; + + + // Editing + + //- Flip the Pair in-place. + inline void flip(); + + //- Sort so that first() is less-than second() + inline void sort(); // Comparison //- Compare Pairs - // Returns: + // \return // - 0: different // - +1: identical values and order used // - -1: identical values, but in reversed order - static inline int compare(const Pair<Type>& a, const Pair<Type>& b) - { - if (a[0] == b[0] && a[1] == b[1]) - { - return 1; - } - else if (a[0] == b[1] && a[1] == b[0]) - { - return -1; - } - else - { - return 0; - } - } + static inline int compare(const Pair<T>& a, const Pair<T>& b); }; // * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * // -template<class Type> -Pair<Type> reverse(const Pair<Type>& p) +//- Return reverse of a Pair +template<class T> +Pair<T> reverse(const Pair<T>& p) { - return Pair<Type>(p.second(), p.first()); + return Pair<T>(p.second(), p.first()); } -template<class Type> -bool operator==(const Pair<Type>& a, const Pair<Type>& b) +template<class T> +bool operator==(const Pair<T>& a, const Pair<T>& b) { return (a.first() == b.first() && a.second() == b.second()); } -template<class Type> -bool operator!=(const Pair<Type>& a, const Pair<Type>& b) +template<class T> +bool operator!=(const Pair<T>& a, const Pair<T>& b) { return !(a == b); } -template<class Type> -bool operator<(const Pair<Type>& a, const Pair<Type>& b) +template<class T> +bool operator<(const Pair<T>& a, const Pair<T>& b) { return ( @@ -197,22 +165,22 @@ bool operator<(const Pair<Type>& a, const Pair<Type>& b) } -template<class Type> -bool operator<=(const Pair<Type>& a, const Pair<Type>& b) +template<class T> +bool operator<=(const Pair<T>& a, const Pair<T>& b) { return !(b < a); } -template<class Type> -bool operator>(const Pair<Type>& a, const Pair<Type>& b) +template<class T> +bool operator>(const Pair<T>& a, const Pair<T>& b) { return (b < a); } -template<class Type> -bool operator>=(const Pair<Type>& a, const Pair<Type>& b) +template<class T> +bool operator>=(const Pair<T>& a, const Pair<T>& b) { return !(a < b); } @@ -224,6 +192,10 @@ bool operator>=(const Pair<Type>& a, const Pair<Type>& b) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +#include "PairI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + #endif // ************************************************************************* // diff --git a/src/OpenFOAM/primitives/Pair/PairI.H b/src/OpenFOAM/primitives/Pair/PairI.H new file mode 100644 index 0000000000000000000000000000000000000000..2f489a03804ee19f403ecf845d9ca2ce5718dd6d --- /dev/null +++ b/src/OpenFOAM/primitives/Pair/PairI.H @@ -0,0 +1,165 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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/>. + +\*---------------------------------------------------------------------------*/ + +#include "Swap.H" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +template<class T> +inline int Foam::Pair<T>::compare(const Pair<T>& a, const Pair<T>& b) +{ + if (a.first() == b.first() && a.second() == b.second()) + { + return 1; + } + if (a.first() == b.second() && a.second() == b.first()) + { + return -1; + } + + return 0; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class T> +inline Foam::Pair<T>::Pair() +{} + + +template<class T> +inline Foam::Pair<T>::Pair(const T& f, const T& s) +{ + first() = f; + second() = s; +} + + +template<class T> +inline Foam::Pair<T>::Pair(const FixedList<T, 2>& lst) +: + FixedList<T, 2>(lst) +{} + + +template<class T> +inline Foam::Pair<T>::Pair(const T& f, const T& s, const bool doSort) +{ + if (doSort && f < s) + { + first() = s; + second() = f; + } + else + { + first() = f; + second() = s; + } +} + + +template<class T> +inline Foam::Pair<T>::Pair(const FixedList<T, 2>& lst, const bool doSort) +: + Pair<T>(lst.first(), lst.last(), doSort) +{} + + + +template<class T> +inline Foam::Pair<T>::Pair(Istream& is) +: + FixedList<T, 2>(is) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class T> +inline const T& Foam::Pair<T>::second() const +{ + return last(); +} + + +template<class T> +inline T& Foam::Pair<T>::second() +{ + return last(); +} + + +template<class T> +inline const T& Foam::Pair<T>::other(const T& a) const +{ + if (first() == second()) + { + FatalErrorInFunction + << "Call to other only valid for Pair with differing" + << " elements:" << *this << abort(FatalError); + } + else if (a == first()) + { + return second(); + } + else + { + if (a != second()) + { + FatalErrorInFunction + << "Pair " << *this + << " does not contain " << a << abort(FatalError); + } + return first(); + } +} + + +template<class T> +inline bool Foam::Pair<T>::sorted() const +{ + return (first() < second()); +} + + +template<class T> +inline void Foam::Pair<T>::flip() +{ + Foam::Swap(first(), second()); +} + + +template<class T> +inline void Foam::Pair<T>::sort() +{ + if (second() < first()) + { + flip(); + } +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/Swap/Swap.H b/src/OpenFOAM/primitives/Swap/Swap.H index 85b0c7316da4cf3e85fae59e92e456e269feb66c..0c2b20b1d4d282ff61e59c5a702fc6bdfe164622 100644 --- a/src/OpenFOAM/primitives/Swap/Swap.H +++ b/src/OpenFOAM/primitives/Swap/Swap.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,28 +25,56 @@ InNamespace Foam Description - Swap its arguments + Swap arguments as per std::swap, but in Foam namespace. \*---------------------------------------------------------------------------*/ #ifndef Swap_H #define Swap_H +#include <type_traits> +#include <utility> + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - +//- Swap non-array types as per std::swap example, but in Foam namespace. +// \sa http://www.cplusplus.com/reference/utility/swap/ template<class T> -inline void Swap(T& a, T& b) +void Swap(T& a, T& b) +{ + // compile-time resolution with std::enable_if not yet working + if (std::is_fundamental<T>::value || std::is_pointer<T>::value) + { + // Use copy/assign for simple types + const T tmp = a; + a = b; + b = tmp; + } + else + { + // Use move/assignment + T tmp(std::move(a)); + a = std::move(b); + b = std::move(tmp); + } +} + + +//- Swap array types as per std::swap example, but in Foam namespace. +// \sa http://www.cplusplus.com/reference/utility/swap/ +template<class T, size_t N> +void Swap(T (&a)[N], T (&b)[N]) { - T tmp = a; - a = b; - b = tmp; + for (size_t i = 0; i < N; ++i) + { + Foam::Swap(a[i], b[i]); + } } + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/primitives/Tuple2/Tuple2.H b/src/OpenFOAM/primitives/Tuple2/Tuple2.H index bf911ebc56bfc42ca40e2fdc66e558a7d9fee582..195f74044ce0ec9e1d21e40f26590a514b68e060 100644 --- a/src/OpenFOAM/primitives/Tuple2/Tuple2.H +++ b/src/OpenFOAM/primitives/Tuple2/Tuple2.H @@ -144,7 +144,7 @@ public: }; -//- Return reverse of a tuple2 +//- Return reverse of a Tuple2 template<class Type1, class Type2> inline Tuple2<Type2, Type1> reverse(const Tuple2<Type1, Type2>& t) { diff --git a/src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatchPointPoints.C b/src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatchPointPoints.C index c0f8dd6fa7d18fd8f987b080dbd5eb768e30e607..7a04712c0272a27b9bd573cd8641bf7bd7ab8cb7 100644 --- a/src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatchPointPoints.C +++ b/src/dynamicMesh/slidingInterface/enrichedPatch/enrichedPatchPointPoints.C @@ -46,8 +46,7 @@ void Foam::enrichedPatch::calcPointPoints() const // Go through all faces and add the previous and next point as the // neighbour for each point. While inserting points, reject the // duplicates (as every internal edge will be visited twice). - List<DynamicList<label, primitiveMesh::edgesPerPoint_>> - pp(meshPoints().size()); + List<DynamicList<label>> pp(meshPoints().size()); const faceList& lf = localFaces(); @@ -59,8 +58,7 @@ void Foam::enrichedPatch::calcPointPoints() const forAll(curFace, pointi) { - DynamicList<label, primitiveMesh::edgesPerPoint_>& - curPp = pp[curFace[pointi]]; + DynamicList<label>& curPp = pp[curFace[pointi]]; // Do next label label next = curFace.nextLabel(pointi); diff --git a/src/meshTools/searchableSurfaces/searchableBox/searchableBox.C b/src/meshTools/searchableSurfaces/searchableBox/searchableBox.C index dfe684bb4daf2a0a127e5212e2b03965eed0c628..9a5f3a49842c1616f249026156474a0afac1d57b 100644 --- a/src/meshTools/searchableSurfaces/searchableBox/searchableBox.C +++ b/src/meshTools/searchableSurfaces/searchableBox/searchableBox.C @@ -503,7 +503,7 @@ void Foam::searchableBox::findLineAll info.setSize(start.size()); // Work array - DynamicList<pointIndexHit, 1, 1> hits; + DynamicList<pointIndexHit> hits; // Tolerances: // To find all intersections we add a small vector to the last intersection diff --git a/src/meshTools/searchableSurfaces/searchableRotatedBox/searchableRotatedBox.C b/src/meshTools/searchableSurfaces/searchableRotatedBox/searchableRotatedBox.C index ffb8dc9c5dcda4a1b0a6bb3e7008463dfaff9e4e..ab2329e744a2c2a442fbd4965acc3ceb28927e89 100644 --- a/src/meshTools/searchableSurfaces/searchableRotatedBox/searchableRotatedBox.C +++ b/src/meshTools/searchableSurfaces/searchableRotatedBox/searchableRotatedBox.C @@ -301,7 +301,7 @@ void Foam::searchableRotatedBox::findLineAll info.setSize(start.size()); // Work array - DynamicList<pointIndexHit, 1, 1> hits; + DynamicList<pointIndexHit> hits; // Tolerances: // To find all intersections we add a small vector to the last intersection diff --git a/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H b/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H index 110ee7944b29bb1a71696612e4899bd58b5a15d1..54af373a33dc3ffab6be29320c76232cf2faf997 100644 --- a/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H +++ b/src/meshTools/searchableSurfaces/triSurfaceMesh/triSurfaceMesh.H @@ -131,7 +131,7 @@ class triSurfaceMesh const point& start, const point& end, const vector& smallVec, - DynamicList<pointIndexHit, 1, 1>& hits + DynamicList<pointIndexHit>& hits ); //- Disallow default bitwise copy construct diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C index 40edce3f2c34a62d0e49af9ac6251ebf0e6dcf70..fe6990565473bd13b3833e96afac497523d2b2bd 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C @@ -33,7 +33,7 @@ License bool Foam::triSurfaceSearch::checkUniqueHit ( const pointIndexHit& currHit, - const DynamicList<pointIndexHit, 1, 1>& hits, + const UList<pointIndexHit>& hits, const vector& lineVec ) const { @@ -387,7 +387,7 @@ void Foam::triSurfaceSearch::findLineAll indexedOctree<treeDataTriSurface>::perturbTol() = tolerance(); // Work array - DynamicList<pointIndexHit, 1, 1> hits; + DynamicList<pointIndexHit> hits; DynamicList<label> shapeMask; diff --git a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H index b46e758985789b1233e6f671510238cf1ad52f81..d42806a563932ac684a64bb1bfce84af32c8adc9 100644 --- a/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H +++ b/src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.H @@ -80,7 +80,7 @@ class triSurfaceSearch bool checkUniqueHit ( const pointIndexHit& currHit, - const DynamicList<pointIndexHit, 1, 1>& hits, + const UList<pointIndexHit>& hits, const vector& lineVec ) const; diff --git a/src/surfMesh/triSurface/triSurface.C b/src/surfMesh/triSurface/triSurface.C index b67da2ec63fd75c6a4cee034b884c3d33f390d0f..6a7b60da3f747c897a904371572277b8e98441e9 100644 --- a/src/surfMesh/triSurface/triSurface.C +++ b/src/surfMesh/triSurface/triSurface.C @@ -937,7 +937,7 @@ void Foam::triSurface::triFaceFaces(List<face>& plainFaces) const forAll(*this, facei) { - plainFaces[facei] = operator[](facei).triFaceFace(); + plainFaces[facei] = this->operator[](facei); } } diff --git a/wmake/rules/linux64GccKNL/c b/wmake/rules/linux64GccKNL/c index a1cd9d6613efd2c4ddfe410727baaad07d036a90..d0eb3eab5709d94f814ba8f71aba33eab0757700 100644 --- a/wmake/rules/linux64GccKNL/c +++ b/wmake/rules/linux64GccKNL/c @@ -2,7 +2,7 @@ SUFFIXES += .c cWARN = -Wall -cc = gcc -m64 -march=knl -DvectorMachine -DKNL +cc = gcc -m64 -march=knl include $(DEFAULT_RULES)/c$(WM_COMPILE_OPTION) diff --git a/wmake/rules/linux64GccKNL/c++ b/wmake/rules/linux64GccKNL/c++ index cdc820c556896b2f4ba81cd885941e2bf5be424b..199d72c0fdcb490b1508c8751c47d220c6c64cd7 100644 --- a/wmake/rules/linux64GccKNL/c++ +++ b/wmake/rules/linux64GccKNL/c++ @@ -6,7 +6,7 @@ c++WARN = -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-para # Suppress some warnings for flex++ and CGAL c++LESSWARN = -Wno-old-style-cast -Wno-unused-local-typedefs -Wno-array-bounds -CC = g++ -std=c++11 -m64 -march=knl -DvectorMachine +CC = g++ -std=c++11 -m64 -march=knl include $(DEFAULT_RULES)/c++$(WM_COMPILE_OPTION) diff --git a/wmake/rules/linux64IccKNL/c++ b/wmake/rules/linux64IccKNL/c++ index f0938a4da25c6cc8fe6dba81a3acf3fdfe3a91bb..9b047d22caf3cfaf543a4bc938d2c2f377a3464b 100644 --- a/wmake/rules/linux64IccKNL/c++ +++ b/wmake/rules/linux64IccKNL/c++ @@ -6,7 +6,7 @@ c++WARN = -Wall -Wextra -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invali # Suppress some warnings for flex++ and CGAL c++LESSWARN = -diag-disable 1224,2026,2305 -CC = icpc -std=c++11 -xmic-avx512 -DvectorMachine -fp-trap=common -fp-model precise -fp-speculation=safe +CC = icpc -std=c++11 -xmic-avx512 -fp-trap=common -fp-model precise -fp-speculation=safe include $(DEFAULT_RULES)/c++$(WM_COMPILE_OPTION)