diff --git a/applications/test/IndirectList2/IndirectList2.H b/applications/test/IndirectList2/IndirectList2.H
new file mode 100644
index 0000000000..9ce440695a
--- /dev/null
+++ b/applications/test/IndirectList2/IndirectList2.H
@@ -0,0 +1,162 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 1991-2010 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 .
+
+Class
+ Foam::IndirectList2
+
+Description
+ A List with indirect addressing.
+
+SourceFiles
+ IndirectListI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IndirectList2_H
+#define IndirectList2_H
+
+#include "UIndirectList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class IndirectListAddressing Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A helper class for storing addresses.
+class IndirectListAddressing
+{
+ // Private data
+
+ //- Storage for the list addressing
+ List addressing_;
+
+
+ // Private Member Functions
+
+ //- Disallow default bitwise copy construct
+ IndirectListAddressing(const IndirectListAddressing&);
+
+ //- Disallow default bitwise assignment
+ void operator=(const IndirectListAddressing&);
+
+protected:
+
+ // Constructors
+
+ //- Construct by copying the addressing array
+ explicit inline IndirectListAddressing(const UList& addr);
+
+ //- Construct by transferring addressing array
+ explicit inline IndirectListAddressing(const Xfer >& addr);
+
+
+ // Member Functions
+
+ // Access
+
+ //- Return the list addressing
+ inline const List& addressing() const;
+
+ // Edit
+
+ //- Reset addressing
+ inline void resetAddressing(const UList&);
+ inline void resetAddressing(const Xfer >&);
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+ Class IndirectList2 Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class IndirectList2
+:
+ private IndirectListAddressing,
+ public UIndirectList
+{
+ // Private Member Functions
+
+ //- Disable default assignment operator
+ void operator=(const IndirectList2&);
+
+ //- Disable assignment from UIndirectList
+ void operator=(const UIndirectList&);
+
+public:
+
+ // Constructors
+
+ //- Construct given the complete list and the addressing array
+ inline IndirectList2(const UList&, const UList&);
+
+ //- Construct given the complete list and by transferring addressing
+ inline IndirectList2(const UList&, const Xfer >&);
+
+ //- Copy constructor
+ inline IndirectList2(const IndirectList2&);
+
+ //- Construct from UIndirectList
+ explicit inline IndirectList2(const UIndirectList&);
+
+
+ // Member Functions
+
+
+ // Access
+
+ //- Return the list addressing
+ using UIndirectList::addressing;
+
+ // Edit
+
+ //- Reset addressing
+ using IndirectListAddressing::resetAddressing;
+
+
+ // Member Operators
+
+ //- Assignment operator
+ using UIndirectList::operator=;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "IndirectList2I.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/test/IndirectList2/IndirectList2I.H b/applications/test/IndirectList2/IndirectList2I.H
new file mode 100644
index 0000000000..66b4e0de84
--- /dev/null
+++ b/applications/test/IndirectList2/IndirectList2I.H
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 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 .
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+
+inline Foam::IndirectListAddressing::IndirectListAddressing
+(
+ const UList& addr
+)
+:
+ addressing_(addr)
+{}
+
+
+inline Foam::IndirectListAddressing::IndirectListAddressing
+(
+ const Xfer >& addr
+)
+:
+ addressing_(addr)
+{}
+
+
+template
+inline Foam::IndirectList2::IndirectList2
+(
+ const UList& completeList,
+ const UList& addr
+)
+:
+ IndirectListAddressing(addr),
+ UIndirectList
+ (
+ completeList,
+ IndirectListAddressing::addressing()
+ )
+{}
+
+
+template
+inline Foam::IndirectList2::IndirectList2
+(
+ const UList& completeList,
+ const Xfer >& addr
+)
+:
+ IndirectListAddressing(addr),
+ UIndirectList
+ (
+ completeList,
+ IndirectListAddressing::addressing()
+ )
+{}
+
+
+template
+inline Foam::IndirectList2::IndirectList2
+(
+ const IndirectList2& lst
+)
+:
+ IndirectListAddressing(lst.addressing()),
+ UIndirectList
+ (
+ lst.completeList(),
+ IndirectListAddressing::addressing()
+ )
+{}
+
+
+template
+inline Foam::IndirectList2::IndirectList2
+(
+ const UIndirectList& lst
+)
+:
+ IndirectListAddressing(lst.addressing()),
+ UIndirectList
+ (
+ lst.completeList(),
+ IndirectListAddressing::addressing()
+ )
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+inline const Foam::List&
+Foam::IndirectListAddressing::addressing() const
+{
+ return addressing_;
+}
+
+
+inline void Foam::IndirectListAddressing::resetAddressing
+(
+ const UList& addr
+)
+{
+ addressing_ = addr;
+}
+
+
+inline void Foam::IndirectListAddressing::resetAddressing
+(
+ const Xfer >& addr
+)
+{
+ addressing_.transfer(addr());
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/IndirectList2/IndirectListTest2.C b/applications/test/IndirectList2/IndirectListTest2.C
new file mode 100644
index 0000000000..14d7d4dbae
--- /dev/null
+++ b/applications/test/IndirectList2/IndirectListTest2.C
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 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 .
+
+Description
+
+\*---------------------------------------------------------------------------*/
+
+#include "IndirectList2.H"
+#include "IOstreams.H"
+
+using namespace Foam;
+
+template
+void printInfo(const ListType& lst)
+{
+ Info<< "addr: " << lst.addressing() << nl
+ << "list: " << lst << nl
+ << endl;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+ List completeList(10);
+
+ forAll(completeList, i)
+ {
+ completeList[i] = 0.1*i;
+ }
+
+ Info<< "raw : " << completeList << nl << endl;
+
+
+ List addresses(5);
+ addresses[0] = 1;
+ addresses[1] = 0;
+ addresses[2] = 7;
+ addresses[3] = 8;
+ addresses[4] = 5;
+
+ IndirectList2 idl1(completeList, addresses);
+
+ printInfo(idl1);
+
+ addresses[4] = 1;
+ addresses[3] = 0;
+ addresses[2] = 7;
+ addresses[1] = 8;
+ addresses[0] = 5;
+
+ idl1.resetAddressing(addresses.xfer());
+
+ printInfo(idl1);
+
+ // test copying
+ UIndirectList uidl1(idl1);
+ IndirectList2 idl2(uidl1);
+ IndirectList2 idl3(idl2);
+
+ printInfo(uidl1);
+
+ idl1.resetAddressing(List());
+// idl2.resetAddressing(List());
+
+ Info<<"after resetAddressing:" << nl << endl;
+
+ printInfo(uidl1);
+ printInfo(idl1);
+ printInfo(idl2);
+ printInfo(idl3);
+
+ Info<< "End\n" << endl;
+
+ return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/IndirectList2/Make/files b/applications/test/IndirectList2/Make/files
new file mode 100644
index 0000000000..c6dab96e20
--- /dev/null
+++ b/applications/test/IndirectList2/Make/files
@@ -0,0 +1,3 @@
+IndirectListTest2.C
+
+EXE = $(FOAM_USER_APPBIN)/IndirectListTest2
diff --git a/applications/test/IndirectList2/Make/options b/applications/test/IndirectList2/Make/options
new file mode 100644
index 0000000000..6a9e9810b3
--- /dev/null
+++ b/applications/test/IndirectList2/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/PackedList/PackedListTest.C b/applications/test/PackedList/PackedListTest.C
index ad5c7b3342..7d47532f1b 100644
--- a/applications/test/PackedList/PackedListTest.C
+++ b/applications/test/PackedList/PackedListTest.C
@@ -166,7 +166,7 @@ int main(int argc, char *argv[])
if (args.optionFound("info"))
{
- packLst.print(Info);
+ packLst.printInfo(Info);
}
Info<< nl;
diff --git a/applications/test/PackedList1/PackedListTest1.C b/applications/test/PackedList1/PackedListTest1.C
index 4ee366854b..e26b08e804 100644
--- a/applications/test/PackedList1/PackedListTest1.C
+++ b/applications/test/PackedList1/PackedListTest1.C
@@ -42,42 +42,42 @@ int main(int argc, char *argv[])
Info<< "\ntest allocation with value\n";
PackedList<3> list1(5,1);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest assign uniform value\n";
list1 = 3;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest assign uniform value (with overflow)\n";
list1 = -1;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest zero\n";
list1 = 0;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest set() with default argument (max_value)\n";
list1.set(1);
list1.set(3);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest unset() with in-range and out-of-range\n";
list1.unset(3);
list1.unset(100000);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest assign between references\n";
list1[2] = 3;
list1[4] = list1[2];
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest assign between references, with chaining\n";
list1[0] = list1[4] = 1;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest assign between references, with chaining and auto-vivify\n";
list1[1] = list1[8] = list1[10] = list1[14] = 2;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest operator== between references\n";
@@ -126,7 +126,7 @@ int main(int argc, char *argv[])
{
const PackedList<3>& constLst = list1;
Info<< "\ntest operator[] const with out-of-range index\n";
- constLst.print(Info);
+ constLst.printInfo(Info, true);
if (constLst[20])
{
Info<< "[20] is true (unexpected)\n";
@@ -136,7 +136,7 @@ int main(int argc, char *argv[])
Info<< "[20] is false (expected) list size should be unchanged "
<< "(const)\n";
}
- constLst.print(Info);
+ constLst.printInfo(Info, true);
Info<< "\ntest operator[] non-const with out-of-range index\n";
if (list1[20])
@@ -148,7 +148,7 @@ int main(int argc, char *argv[])
Info<< "[20] is false (expected) but list was resized?? "
<< "(non-const)\n";
}
- list1.print(Info);
+ list1.printInfo(Info, true);
}
@@ -157,85 +157,85 @@ int main(int argc, char *argv[])
{
Info<< "[20] is false, as expected\n";
}
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest resize with value (without reallocation)\n";
list1.resize(8, list1.max_value());
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest flip() function\n";
list1.flip();
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\nre-flip()\n";
list1.flip();
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest set() function\n";
list1.set(1, 5);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest assign bool\n";
list1 = false;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest assign bool\n";
list1 = true;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest resize without value (with reallocation)\n";
list1.resize(12);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest resize with value (with reallocation)\n";
list1.resize(25, list1.max_value());
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest resize smaller (should not touch allocation)\n";
list1.resize(8);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest append() operation\n";
list1.append(2);
list1.append(3);
list1.append(4);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest reserve() operation\n";
list1.reserve(32);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest shrink() operation\n";
list1.shrink();
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest setCapacity() operation\n";
list1.setCapacity(15);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest setCapacity() operation\n";
list1.setCapacity(100);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest operator[] assignment\n";
list1[16] = 5;
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest operator[] assignment with auto-vivify\n";
list1[36] = list1.max_value();
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest setCapacity smaller\n";
list1.setCapacity(24);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest resize much smaller\n";
list1.resize(150);
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest trim\n";
list1.trim();
- list1.print(Info);
+ list1.printInfo(Info, true);
// add in some misc values
list1[31] = 1;
@@ -245,40 +245,40 @@ int main(int argc, char *argv[])
Info<< "\ntest iterator\n";
PackedList<3>::iterator iter = list1.begin();
Info<< "begin():";
- iter.print(Info) << "\n";
+ iter.printInfo(Info) << "\n";
Info<< "iterator:" << iter() << "\n";
iter() = 5;
- iter.print(Info);
- list1.print(Info);
+ iter.printInfo(Info);
+ list1.printInfo(Info, true);
iter = list1[31];
Info<< "iterator:" << iter() << "\n";
- iter.print(Info);
+ iter.printInfo(Info);
Info<< "\ntest get() method\n";
Info<< "get(10):" << list1.get(10) << " and list[10]:" << list1[10] << "\n";
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest iterator indexing\n";
Info<< "cend() ";
- list1.cend().print(Info) << "\n";
+ list1.cend().printInfo(Info) << "\n";
{
Info<< "\ntest assignment of iterator\n";
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "cend()\n";
- list1.end().print(Info);
+ list1.end().printInfo(Info);
PackedList<3>::iterator cit = list1[100];
Info<< "out-of-range: ";
- cit.print(Info);
+ cit.printInfo(Info);
cit = list1[15];
Info<< "in-range: ";
- cit.print(Info);
+ cit.printInfo(Info);
Info<< "out-of-range: ";
cit = list1[1000];
- cit.print(Info);
+ cit.printInfo(Info);
}
@@ -289,7 +289,7 @@ int main(int argc, char *argv[])
++cit
)
{
- cit.print(Info);
+ cit.printInfo(Info);
}
Info<< "\ntest operator[] auto-vivify\n";
@@ -304,16 +304,16 @@ int main(int argc, char *argv[])
Info<< "size after write:" << list1.size() << "\n";
Info<< "list[45]:" << list1[45] << "\n";
list1[49] = list1[100];
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "\ntest copy constructor + append\n";
PackedList<3> list2(list1);
list2.append(4);
Info<< "source list:\n";
- list1.print(Info);
+ list1.printInfo(Info, true);
Info<< "destination list:\n";
- list2.print(Info);
+ list2.printInfo(Info, true);
Info<< "\ntest pattern that fills all bits\n";
PackedList<4> list3(8, 8);
@@ -323,29 +323,50 @@ int main(int argc, char *argv[])
list3[pos--] = list3.max_value();
list3[pos--] = 0;
list3[pos--] = list3.max_value();
- list3.print(Info);
+ list3.printInfo(Info, true);
Info<< "removed final value: " << list3.remove() << endl;
- list3.print(Info);
+ list3.printInfo(Info, true);
+
+ Info<<"list: " << list3 << endl;
- List list4(4, true);
+ List list4(16, false);
{
- const List& constLst = list4;
+ // fill with some values
+ forAll(list4, i)
+ {
+ list4[i] = i % 3;
+ }
+
+ const UList& constLst = list4;
Info<< "\ntest operator[] const with out-of-range index\n";
Info<< constLst << endl;
- if (constLst[20])
+ if (constLst[100])
{
- Info<< "[20] is true (unexpected)\n";
+ Info<< "[100] is true (unexpected)\n";
}
else
{
- Info<< "[20] is false (expected) list size should be unchanged "
- << "(const)\n";
+ Info<< "[100] is false (expected) "
+ << "list size should be unchanged (const)\n";
}
Info<< constLst << endl;
}
+
+ PackedBoolList listb(list4);
+
+ Info<< "copied from bool list " << endl;
+ listb.printInfo(Info, true);
+
+ {
+ labelList indices = listb.used();
+
+ Info<< "indices: " << indices << endl;
+ }
+
+
Info<< "\n\nDone.\n";
return 0;
diff --git a/applications/test/PackedList3/PackedListTest3.C b/applications/test/PackedList3/PackedListTest3.C
index 5ff6ee8644..7b27ffda09 100644
--- a/applications/test/PackedList3/PackedListTest3.C
+++ b/applications/test/PackedList3/PackedListTest3.C
@@ -33,7 +33,6 @@ Description
#include "StaticHashTable.H"
#include "cpuTime.H"
#include
-#include "PackedList.H"
#include "PackedBoolList.H"
using namespace Foam;
@@ -57,7 +56,7 @@ int main(int argc, char *argv[])
{
if ((i % nReport) == 0 && i)
{
- Info<< "i:" << i << " in " << timer.cpuTimeIncrement() << " s"
+ Info<< "i:" << i << " in " << timer.cpuTimeIncrement() << " s"
< .
+
+Application
+
+Description
+
+\*---------------------------------------------------------------------------*/
+
+#include "uLabel.H"
+#include "IOstreams.H"
+#include "PackedBoolList.H"
+#include "IStringStream.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+ PackedBoolList list1(20);
+ // set every third one on
+ forAll(list1, i)
+ {
+ list1[i] = !(i % 3);
+ }
+
+ Info<< "\nalternating bit pattern\n";
+ list1.printInfo(Info, true);
+
+ PackedBoolList list2 = ~list1;
+
+ Info<< "\ncomplementary bit pattern\n";
+ list2.printBits(Info);
+
+ // set every other on
+ forAll(list2, i)
+ {
+ list2[i] = !(i % 2);
+ }
+
+ Info<< "\nalternating bit pattern\n";
+ list2.printBits(Info);
+
+ list2.resize(28, false);
+ list2.resize(34, true);
+ list2.resize(40, false);
+ for (label i=0; i < 4; ++i)
+ {
+ list2[i] = true;
+ }
+
+ Info<< "\nresized with false, 6 true + 6 false, bottom 4 bits true\n";
+ list2.printInfo(Info, true);
+
+ labelList list2Labels = list2.used();
+
+ Info<< "\noperator|\n";
+
+ list1.printBits(Info);
+ list2.printBits(Info);
+ Info<< "==\n";
+ (list1 | list2).printBits(Info);
+
+ Info<< "\noperator& : does trim\n";
+ (list1 & list2).printBits(Info);
+
+ Info<< "\noperator^\n";
+ (list1 ^ list2).printBits(Info);
+
+
+ Info<< "\noperator|=\n";
+ {
+ PackedBoolList list3 = list1;
+ (list3 |= list2).printBits(Info);
+ }
+
+ Info<< "\noperator|= with UList\n";
+ {
+ PackedBoolList list3 = list1;
+ (list3 |= list2Labels).printBits(Info);
+ }
+
+ Info<< "\noperator&=\n";
+ {
+ PackedBoolList list3 = list1;
+ (list3 &= list2).printBits(Info);
+ }
+
+ Info<< "\noperator+=\n";
+ {
+ PackedBoolList list3 = list1;
+ (list3 += list2).printBits(Info);
+ }
+
+ Info<< "\noperator+= with UList\n";
+ {
+ PackedBoolList list3 = list1;
+ (list3 += list2Labels).printBits(Info);
+ }
+
+ Info<< "\noperator-=\n";
+ {
+ PackedBoolList list3 = list1;
+ (list3 -= list2).printBits(Info);
+ }
+
+ Info<< "\noperator-= with UList\n";
+ {
+ PackedBoolList list3 = list1;
+ (list3 -= list2Labels).printBits(Info);
+ }
+
+ PackedBoolList list4
+ (
+ IStringStream
+ (
+ "(1 n 1 n 1 n 1 1 off 0 0 f f 0 y yes y true y false on t)"
+ )()
+ );
+
+ Info<< "\ntest Istream constructor\n";
+
+ list4.printInfo(Info, true);
+ Info<< list4 << " indices: " << list4.used()() < boolLst(list4.size());
+ forAll(list4, i)
+ {
+ boolLst[i] = list4[i];
+ }
+
+ Info<< "List: " << boolLst < pl2
+ (
+ IStringStream
+ (
+ "{(0 3)(1 3)(2 3)(3 3)(12 3)(13 3)(14 3)(19 3)(20 3)(21 3)}"
+ )()
+ );
+
+ Info<< "roundabout assignment: " << pl2 << endl;
+
+ list4.clear();
+ forAll(pl2, i)
+ {
+ list4[i] = pl2[i];
+ }
+
+ list4.write(Info, true) << endl;
+
+ list4.writeEntry("PackedBoolList", Info);
+
+ return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/bin/doxyFilt b/bin/tools/doxyFilter
similarity index 89%
rename from bin/doxyFilt
rename to bin/tools/doxyFilter
index 7f337e539c..c49851a502 100755
--- a/bin/doxyFilt
+++ b/bin/tools/doxyFilter
@@ -23,7 +23,7 @@
# along with OpenFOAM. If not, see .
#
# Script
-# doxyFilt
+# doxyFilter
#
# Description
# pass-through filter for doxygen
@@ -43,19 +43,19 @@ then
dirName=${filePath%/[^/]*}
fileName=${filePath##*/}
- awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt.awk
+ awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilter.awk
case "$1" in
*/applications/solvers/*.C | */applications/utilities/*.C )
- awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt-top.awk
+ awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilter-top.awk
;;
# */applications/solvers/*.H | */applications/utilities/*.H )
-# awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt-ignore.awk
+# awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilter-ignore.awk
# ;;
esac
awk -f $awkScript $1 | \
- sed -f $WM_PROJECT_DIR/bin/tools/doxyFilt.sed \
+ sed -f $WM_PROJECT_DIR/bin/tools/doxyFilter.sed \
-e s@%filePath%@$filePath@g \
-e s@%fileName%@$fileName@g \
-e s@%dirName%@$dirName@g
diff --git a/bin/tools/doxyFilt-ignore.awk b/bin/tools/doxyFilter-ignore.awk
similarity index 98%
rename from bin/tools/doxyFilt-ignore.awk
rename to bin/tools/doxyFilter-ignore.awk
index ebbacc7177..0d85702b34 100644
--- a/bin/tools/doxyFilt-ignore.awk
+++ b/bin/tools/doxyFilter-ignore.awk
@@ -22,7 +22,7 @@
# along with OpenFOAM. If not, see .
#
# Script
-# doxyFilt-ignore.awk
+# doxyFilter-ignore.awk
#
# Description
# - Prefix file contents with doxygen @file tag and %filePath% tag
diff --git a/bin/tools/doxyFilt-top.awk b/bin/tools/doxyFilter-top.awk
similarity index 98%
rename from bin/tools/doxyFilt-top.awk
rename to bin/tools/doxyFilter-top.awk
index 97b96ff7b4..856e6621d4 100644
--- a/bin/tools/doxyFilt-top.awk
+++ b/bin/tools/doxyFilter-top.awk
@@ -22,7 +22,7 @@
# along with OpenFOAM. If not, see .
#
# Script
-# doxyFilt-top.awk
+# doxyFilter-top.awk
#
# Description
# Only output the first /* ... */ comment section found in the file
diff --git a/bin/tools/doxyFilt.awk b/bin/tools/doxyFilter.awk
similarity index 99%
rename from bin/tools/doxyFilt.awk
rename to bin/tools/doxyFilter.awk
index da65c3ded7..1e37d0e33b 100644
--- a/bin/tools/doxyFilt.awk
+++ b/bin/tools/doxyFilter.awk
@@ -22,7 +22,7 @@
# along with OpenFOAM. If not, see .
#
# Script
-# doxyFilt.awk
+# doxyFilter.awk
#
# Description
# Converts cocoon style sentinel strings into doxygen style strings
diff --git a/bin/tools/doxyFilt.sed b/bin/tools/doxyFilter.sed
similarity index 99%
rename from bin/tools/doxyFilt.sed
rename to bin/tools/doxyFilter.sed
index 4aaa7adb0e..45a15019e1 100644
--- a/bin/tools/doxyFilt.sed
+++ b/bin/tools/doxyFilter.sed
@@ -1,6 +1,6 @@
# -----------------------------------------------------------------------------
# Script
-# doxyFilt.sed
+# doxyFilter.sed
#
# Description
# Transform human-readable tags such as 'Description' into the Doxygen
diff --git a/bin/tools/pre-commit-hook b/bin/tools/pre-commit-hook
index 7d41b2e11c..b0ca86f020 100755
--- a/bin/tools/pre-commit-hook
+++ b/bin/tools/pre-commit-hook
@@ -45,6 +45,9 @@
# Note
# Using "git commit --no-verify" it is possible to override the hook.
#
+# By supplying arguments to the hook, it can also be used to manually
+# test the specified files/directories for standards conformance.
+#
#------------------------------------------------------------------------------
die()
{
@@ -52,13 +55,14 @@ die()
echo '-----------------------' 1>&2
echo '' 1>&2
echo "$@" 1>&2
+ echo '' 1>&2
exit 1
}
#-----------------------------------------------------------------------------
# Check content that will be added by this commit.
-if git rev-parse --verify -q HEAD > /dev/null
+if git rev-parse --verify HEAD > /dev/null 2>&1
then
against=HEAD
else
@@ -66,10 +70,30 @@ else
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
-# list of all files
-fileList=$(git diff-index --name-only $against --)
-unset badFiles
+# called manually with arguments for the files/directories to be tested?
+if [ "$#" -gt 0 ]
+then
+ case "$1" in
+ -h | -help)
+ die "interactive usage: supply list of files/directories to check"
+ ;;
+ esac
+ # obtain list of all specified files/directories
+ fileList=$(git ls-files -- $@ 2>/dev/null)
+else
+ # list of all files to be committed
+ fileList=$(git diff-index --cached --name-only $against --)
+fi
+
+#
+# no files changed: can skip all the checks
+# this usage can correspond to a 'git commit --amend'
+#
+[ -n "$fileList" ] || exit 0
+
+
+unset badFiles
# join list of files with this amount of space
Indent=" "
@@ -97,16 +121,18 @@ dieOnBadFiles()
#
checkIllegalCode()
{
+ echo "pre-commit: check bad strings/characters etc ..." 1>&2
+
reBad="(N""abla|"$'\t'")"
msgBad="N""abla or "
badFiles=$(
for f in $fileList
do
- # parse line numbers from this:
- # path/fileName:: contents
- lines=$(git grep --cached -n -E -e "$reBad" -- "$f" |
- sed -e 's@^[^:]*:\([0-9]*\):.*@\1@' |
+ # parse line numbers from grep output:
+ # : contents
+ lines=$(git grep --cached -E -hn -e "$reBad" -- "$f" |
+ sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -123,18 +149,22 @@ checkIllegalCode()
checkCopyright()
{
year=$(date +%Y)
+ echo "pre-commit: check copyright ..." 1>&2
badFiles=$(
for f in $fileList
do
- # parse line numbers from this:
- # path/fileName:: contents
- # for Copyright lines without the current year
- lines=$(git grep --cached -n -e Copyright -- "$f" |
- sed -n \
- -e '/OpenCFD/{ ' \
- -e "/$year/b" \
- -e 's@^[^:]*:\([0-9]*\):.*@\1@p }' |
+ # NB: need to have OpenCFD on a separate line to prevent
+ # this check being caught by itself!
+ #
+ # parse line numbers from grep output:
+ # : contents
+ #
+ lines=$(git grep --cached -F -hn -e Copyright \
+ --and -e OpenCFD \
+ --and --not -e "$year" \
+ -- "$f" |
+ sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -150,16 +180,18 @@ checkCopyright()
#
checkLineLength()
{
+ echo "pre-commit: check line lengths ..." 1>&2
+
badFiles=$(
for f in $fileList
do
# limit to *.[CH] files
case "$f" in
(*.[CH])
- # parse line numbers from this:
- # path/fileName:: contents
- lines=$(git grep --cached -n -e ".\{81,\}" -- "$f" |
- sed -e 's@^[^:]*:\([0-9]*\):.*@\1@' |
+ # parse line numbers from grep output:
+ # : contents
+ lines=$(git grep --cached -hn -e '^.\{81,\}' -- "$f" |
+ sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -177,18 +209,20 @@ checkLineLength()
#
checkLineLengthNonComments()
{
+ echo "pre-commit: check line lengths ..." 1>&2
+
badFiles=$(
for f in $fileList
do
# limit to *.[CH] files
case "$f" in
(*.[CH])
- # parse line numbers from this (strip comment lines):
- # path/fileName:: contents
- lines=$(git grep --cached -n -e ".\{81,\}" -- "$f" |
- sed -n \
- -e '\@^[^:]*:[^:]*: *//.*@b' \
- -e 's@^[^:]*:\([0-9]*\):.*@\1@p' |
+ # parse line numbers from grep output:
+ # : contents
+ lines=$(git grep --cached -hn -e '^.\{81,\}' \
+ --and --not -e "^ *//" \
+ -- "$f" |
+ sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -205,18 +239,20 @@ checkLineLengthNonComments()
#
checkLineLengthNonDirective()
{
+ echo "pre-commit: check line lengths ..." 1>&2
+
badFiles=$(
for f in $fileList
do
# limit to *.[CH] files
case "$f" in
(*.[CH])
- # parse line numbers from this (strip comment lines):
- # path/fileName:: contents
- lines=$(git grep --cached -n -e ".\{81,\}" -- "$f" |
- sed -n \
- -e '\@^[^:]*:[^:]*: *#.*@b' \
- -e 's@^[^:]*:\([0-9]*\):.*@\1@p' |
+ # parse line numbers from grep output:
+ # : contents
+ lines=$(git grep --cached -hn -e '^.\{81,\}' \
+ --and --not -e "^ *#" \
+ -- "$f" |
+ sed -e 's@:.*@@' |
tr '\n' ' '
)
[ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
diff --git a/doc/Doxygen/Doxyfile b/doc/Doxygen/Doxyfile
index 68ff8430b2..79bc3b71cf 100644
--- a/doc/Doxygen/Doxyfile
+++ b/doc/Doxygen/Doxyfile
@@ -567,7 +567,7 @@ IMAGE_PATH =
# to standard output. If FILTER_PATTERNS is specified, this tag will be
# ignored.
-INPUT_FILTER = doxyFilt
+INPUT_FILTER = $(WM_PROJECT_DIR)/bin/tools/doxyFilter
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index 1b1f98598f..1445ad0bc2 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -669,7 +669,7 @@ IMAGE_PATH =
# If FILTER_PATTERNS is specified, this tag will be
# ignored.
-INPUT_FILTER = doxyFilt
+INPUT_FILTER = $(WM_PROJECT_DIR)/bin/tools/doxyFilter
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis.
diff --git a/doc/tools/find-trailingspace b/doc/tools/find-trailingspace
new file mode 100755
index 0000000000..a04ee94d46
--- /dev/null
+++ b/doc/tools/find-trailingspace
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Script
+# find-trailingspace
+#
+# Description
+# Search for files with trailing whitesapce
+#
+# -----------------------------------------------------------------------------
+set -x
+cd $WM_PROJECT_DIR || exit 1
+
+tab=$'\t'
+
+git grep -c -E "[ $tab]+"'$' -- $@
+
+#------------------------------------------------------------------ end-of-file
diff --git a/src/OSspecific/POSIX/regExp.H b/src/OSspecific/POSIX/regExp.H
index edc8ddd6c0..cd140fe852 100644
--- a/src/OSspecific/POSIX/regExp.H
+++ b/src/OSspecific/POSIX/regExp.H
@@ -157,7 +157,7 @@ public:
// The begin-of-line (^) and end-of-line ($) anchors are implicit
bool match(const string&, List& groups) const;
- //- Return true if the regex was found in within string
+ //- Return true if the regex was found within string
bool search(const std::string& str) const
{
return std::string::npos != find(str);
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 599d30fa09..d9548b67b1 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -52,8 +52,8 @@ $(strings)/word/word.C
$(strings)/word/wordIO.C
$(strings)/fileName/fileName.C
$(strings)/fileName/fileNameIO.C
-$(strings)/keyType/keyTypeIO.C
-$(strings)/wordRe/wordReIO.C
+$(strings)/keyType/keyType.C
+$(strings)/wordRe/wordRe.C
primitives/hashes/Hasher/Hasher.C
@@ -66,7 +66,8 @@ primitives/random/Random.C
containers/HashTables/HashTable/HashTableCore.C
containers/HashTables/StaticHashTable/StaticHashTableCore.C
containers/Lists/SortableList/ParSortableListName.C
-containers/Lists/PackedList/PackedListName.C
+containers/Lists/PackedList/PackedListCore.C
+containers/Lists/PackedList/PackedBoolList.C
containers/Lists/ListOps/ListOps.C
containers/LinkedLists/linkTypes/SLListBase/SLListBase.C
containers/LinkedLists/linkTypes/DLListBase/DLListBase.C
@@ -328,7 +329,7 @@ $(cellShape)/cellShapeEqual.C
$(cellShape)/cellShapeIO.C
$(cellShape)/cellShapeIOList.C
-meshes/patchIdentifier/patchIdentifier.C
+meshes/Identifiers/patch/patchIdentifier.C
polyMesh = meshes/polyMesh
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
index 4831b98106..fdf1a3c931 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
@@ -180,13 +180,22 @@ public:
// Member Operators
//- Append an element at the end of the list
- inline void append(const T&);
+ inline DynamicList& append
+ (
+ const T&
+ );
//- Append a List at the end of this list
- inline void append(const UList&);
+ inline DynamicList& append
+ (
+ const UList&
+ );
//- Append a UIndirectList at the end of this list
- inline void append(const UIndirectList&);
+ inline DynamicList& append
+ (
+ const UIndirectList&
+ );
//- Remove and return the top element
inline T remove();
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
index f6ff8e9969..bbe24d11c2 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
@@ -305,7 +305,8 @@ Foam::DynamicList::xfer()
template
-inline void Foam::DynamicList::append
+inline Foam::DynamicList&
+Foam::DynamicList::append
(
const T& t
)
@@ -314,11 +315,13 @@ inline void Foam::DynamicList::append
setSize(elemI + 1);
this->operator[](elemI) = t;
+ return *this;
}
template
-inline void Foam::DynamicList::append
+inline Foam::DynamicList&
+Foam::DynamicList::append
(
const UList& lst
)
@@ -339,11 +342,13 @@ inline void Foam::DynamicList::append
{
this->operator[](nextFree++) = lst[elemI];
}
+ return *this;
}
template
-inline void Foam::DynamicList::append
+inline Foam::DynamicList&
+Foam::DynamicList::append
(
const UIndirectList& lst
)
@@ -355,6 +360,7 @@ inline void Foam::DynamicList::append
{
this->operator[](nextFree++) = lst[elemI];
}
+ return *this;
}
diff --git a/src/OpenFOAM/containers/Lists/List/ListIO.C b/src/OpenFOAM/containers/Lists/List/ListIO.C
index 984971ecc4..a70cc8f9e6 100644
--- a/src/OpenFOAM/containers/Lists/List/ListIO.C
+++ b/src/OpenFOAM/containers/Lists/List/ListIO.C
@@ -135,7 +135,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List& L)
<< exit(FatalIOError);
}
- // Putback the openning bracket
+ // Putback the opening bracket
is.putBack(firstToken);
// Now read as a singly-linked list
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C
new file mode 100644
index 0000000000..79a383a685
--- /dev/null
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C
@@ -0,0 +1,375 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "PackedBoolList.H"
+#include "IOstreams.H"
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+bool Foam::PackedBoolList::bitorPrepare
+(
+ const PackedList<1>& lst,
+ label& maxPackLen
+)
+{
+ const StorageList& lhs = this->storage();
+ const StorageList& rhs = lst.storage();
+
+ const label packLen1 = this->packedLength();
+ const label packLen2 = lst.packedLength();
+
+
+ // check how the lists interact and if bit trimming is needed
+ bool needTrim = false;
+ maxPackLen = packLen1;
+
+ if (packLen1 == packLen2)
+ {
+ // identical packed lengths - only resize if absolutely necessary
+ if
+ (
+ this->size() != lst.size()
+ && maxPackLen
+ && rhs[maxPackLen-1] > lhs[maxPackLen-1]
+ )
+ {
+ // second list has a higher bit set
+ // extend addressable area and use trim
+ resize(lst.size());
+ needTrim = true;
+ }
+ }
+ else if (packLen2 < packLen1)
+ {
+ // second list is shorter, this limits the or
+ maxPackLen = packLen2;
+ }
+ else
+ {
+ // second list is longer, find the highest bit set
+ for (label storeI = packLen1; storeI < packLen2; ++storeI)
+ {
+ if (rhs[storeI])
+ {
+ maxPackLen = storeI+1;
+ }
+ }
+
+ // the upper limit moved - resize for full coverage and trim later
+ if (maxPackLen > packLen1)
+ {
+ resize(maxPackLen * packing());
+ needTrim = true;
+ }
+ }
+
+ return needTrim;
+}
+
+
+template
+Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices)
+{
+ // no better information, just guess something about the size
+ reserve(indices.size());
+
+ label cnt = 0;
+ forAll(indices, elemI)
+ {
+ if (set(indices[elemI]))
+ {
+ ++cnt;
+ }
+ }
+
+ return cnt;
+}
+
+
+template
+Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices)
+{
+ label cnt = 0;
+ forAll(indices, elemI)
+ {
+ if (unset(indices[elemI]))
+ {
+ ++cnt;
+ }
+ }
+
+ return cnt;
+}
+
+
+template
+Foam::label Foam::PackedBoolList::subsetIndices(const LabelListType& indices)
+{
+ // handle trivial case
+ if (empty() || indices.empty())
+ {
+ clear();
+ return 0;
+ }
+
+ // normal case
+ PackedBoolList anded;
+ anded.reserve(size());
+
+ label cnt = 0;
+ forAll(indices, elemI)
+ {
+ const label& index = indices[elemI];
+ if (operator[](index))
+ {
+ anded.set(index);
+ ++cnt;
+ }
+ }
+
+ transfer(anded);
+ return cnt;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::PackedBoolList::PackedBoolList(Istream& is)
+:
+ PackedList<1>()
+{
+ is >> *this;
+}
+
+
+// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
+
+void Foam::PackedBoolList::set(const PackedList<1>& lst)
+{
+ // extend addressable area if needed, return maximum size possible
+ label len = 0;
+ const bool needTrim = bitorPrepare(lst, len);
+
+ // operate directly with the underlying storage
+ StorageList& lhs = this->storage();
+ const StorageList& rhs = lst.storage();
+
+ for (label i=0; i < len; ++i)
+ {
+ lhs[i] |= rhs[i];
+ }
+
+ if (needTrim)
+ {
+ trim();
+ }
+}
+
+
+Foam::label Foam::PackedBoolList::set(const UList& indices)
+{
+ return setIndices(indices);
+}
+
+
+Foam::label Foam::PackedBoolList::set(const UIndirectList& indices)
+{
+ return setIndices(indices);
+}
+
+
+void Foam::PackedBoolList::unset(const PackedList<1>& lst)
+{
+ // operate directly with the underlying storage
+ StorageList& lhs = this->storage();
+ const StorageList& rhs = lst.storage();
+
+ // overlapping storage size
+ const label len = min(this->packedLength(), lst.packedLength());
+
+ for (label i=0; i < len; ++i)
+ {
+ lhs[i] &= ~rhs[i];
+ }
+}
+
+
+Foam::label Foam::PackedBoolList::unset(const UList& indices)
+{
+ return unsetIndices(indices);
+}
+
+
+Foam::label Foam::PackedBoolList::unset(const UIndirectList& indices)
+{
+ return unsetIndices(indices);
+}
+
+
+void Foam::PackedBoolList::subset(const PackedList<1>& lst)
+{
+ // shrink addressable area if needed
+ if (this->size() > lst.size())
+ {
+ this->resize(lst.size());
+ }
+
+ // operate directly with the underlying storage
+ StorageList& lhs = this->storage();
+ const StorageList& rhs = lst.storage();
+
+ const label len = this->packedLength();
+
+ for (label i=0; i < len; ++i)
+ {
+ lhs[i] &= rhs[i];
+ }
+}
+
+
+Foam::label Foam::PackedBoolList::subset(const UList& indices)
+{
+ return subsetIndices(indices);
+}
+
+
+Foam::label Foam::PackedBoolList::subset(const UIndirectList& indices)
+{
+ return subsetIndices(indices);
+}
+
+
+Foam::Xfer Foam::PackedBoolList::used() const
+{
+ labelList lst(this->count());
+
+ if (lst.size())
+ {
+ label nElem = 0;
+
+ forAll(*this, elemI)
+ {
+ if (get(elemI))
+ {
+ lst[nElem++] = elemI;
+ }
+ }
+
+ lst.setSize(nElem);
+ }
+
+ return lst.xfer();
+}
+
+
+// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
+
+Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const UList& lst)
+{
+ this->setSize(lst.size());
+
+ // overwrite with new true/false values
+ forAll(*this, elemI)
+ {
+ set(elemI, lst[elemI]);
+ }
+
+ return *this;
+}
+
+
+Foam::PackedBoolList&
+Foam::PackedBoolList::operator^=(const PackedList<1>& lst)
+{
+ // extend addressable area if needed, return maximum size possible
+ label len = 0;
+ const bool needTrim = bitorPrepare(lst, len);
+
+ // operate directly with the underlying storage
+ StorageList& lhs = this->storage();
+ const StorageList& rhs = lst.storage();
+
+ for (label i=0; i < len; ++i)
+ {
+ lhs[i] ^= rhs[i];
+ }
+
+ if (needTrim)
+ {
+ trim();
+ }
+
+ return *this;
+}
+
+
+// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * //
+
+Foam::PackedBoolList Foam::operator&
+(
+ const PackedBoolList& lst1,
+ const PackedBoolList& lst2
+)
+{
+ PackedBoolList result(lst1);
+ result &= lst2;
+
+ // trim to bits actually used
+ result.trim();
+
+ return result;
+}
+
+
+Foam::PackedBoolList Foam::operator^
+(
+ const PackedBoolList& lst1,
+ const PackedBoolList& lst2
+)
+{
+ PackedBoolList result(lst1);
+ result ^= lst2;
+
+ // trim to bits actually used
+ result.trim();
+
+ return result;
+}
+
+
+Foam::PackedBoolList Foam::operator|
+(
+ const PackedBoolList& lst1,
+ const PackedBoolList& lst2
+)
+{
+ PackedBoolList result(lst1);
+ result |= lst2;
+ return result;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H
new file mode 100644
index 0000000000..2058d4eb93
--- /dev/null
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H
@@ -0,0 +1,296 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 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 .
+
+Class
+ Foam::PackedBoolList
+
+Description
+ A bit-packed bool list.
+
+ In addition to the obvious memory advantage over using a
+ List\, this class also provides a number of bit-like
+ operations.
+
+SourceFiles
+ PackedBoolListI.H
+ PackedBoolList.C
+
+SeeAlso
+ Foam::PackedList
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef PackedBoolList_H
+#define PackedBoolList_H
+
+#include "PackedList.H"
+#include "UIndirectList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class PackedBoolList Declaration
+\*---------------------------------------------------------------------------*/
+
+class PackedBoolList
+:
+ public PackedList<1>
+{
+ // Private Member Functions
+
+ //- Preparation, resizing before a bitor operation
+ // returns true if the later result needs trimming
+ bool bitorPrepare(const PackedList<1>& lst, label& maxPackLen);
+
+ //- Set the listed indices. Return number of elements changed.
+ // Does auto-vivify for non-existent entries.
+ template
+ label setIndices(const LabelListType& indices);
+
+ //- Unset the listed indices. Return number of elements changed.
+ // Never auto-vivify entries.
+ template
+ label unsetIndices(const LabelListType& indices);
+
+ //- Subset with the listed indices. Return number of elements subsetted.
+ template
+ label subsetIndices(const LabelListType& indices);
+
+public:
+
+ // Constructors
+
+ //- Construct null
+ inline PackedBoolList();
+
+ //- Construct from Istream
+ PackedBoolList(Istream&);
+
+ //- Construct with given size, initializes list to 0
+ explicit inline PackedBoolList(const label size);
+
+ //- Construct with given size and value for all elements
+ inline PackedBoolList(const label size, const bool val);
+
+ //- Copy constructor
+ inline PackedBoolList(const PackedBoolList&);
+
+ //- Copy constructor
+ explicit inline PackedBoolList(const PackedList<1>&);
+
+ //- Construct by transferring the parameter contents
+ inline PackedBoolList(const Xfer&);
+
+ //- Construct by transferring the parameter contents
+ inline PackedBoolList(const Xfer >&);
+
+ //- Construct from a list of bools
+ explicit inline PackedBoolList(const UList&);
+
+ //- Construct from a list of labels
+ // using the labels as indices to indicate which bits are set
+ explicit inline PackedBoolList(const UList& indices);
+
+ //- Construct from a list of labels
+ // using the labels as indices to indicate which bits are set
+ explicit inline PackedBoolList(const UIndirectList& indices);
+
+ //- Clone
+ inline autoPtr clone() const;
+
+
+ // Member Functions
+
+ // Access
+
+ using PackedList<1>::set;
+ using PackedList<1>::unset;
+
+ //- Set specified bits.
+ void set(const PackedList<1>&);
+
+ //- Set the listed indices. Return number of elements changed.
+ // Does auto-vivify for non-existent entries.
+ label set(const UList& indices);
+
+ //- Set the listed indices. Return number of elements changed.
+ // Does auto-vivify for non-existent entries.
+ label set(const UIndirectList& indices);
+
+ //- Unset specified bits.
+ void unset(const PackedList<1>&);
+
+ //- Unset the listed indices. Return number of elements changed.
+ // Never auto-vivify entries.
+ label unset(const UList& indices);
+
+ //- Unset the listed indices. Return number of elements changed.
+ // Never auto-vivify entries.
+ label unset(const UIndirectList& indices);
+
+ //- Subset with the specified list.
+ void subset(const PackedList<1>&);
+
+ //- Subset with the listed indices.
+ // Return number of elements subsetted.
+ label subset(const UList& indices);
+
+ //- Subset with the listed indices.
+ // Return number of elements subsetted.
+ label subset(const UIndirectList& indices);
+
+
+ //- Return indices of the used (true) elements as a list of labels
+ Xfer used() const;
+
+
+ // Edit
+
+ //- Transfer the contents of the argument list into this list
+ // and annul the argument list.
+ inline void transfer(PackedBoolList&);
+
+ //- Transfer the contents of the argument list into this list
+ // and annul the argument list.
+ inline void transfer(PackedList<1>&);
+
+ //- Transfer contents to the Xfer container
+ inline Xfer xfer();
+
+
+ // Member Operators
+
+ //- Assignment of all entries to the given value.
+ inline PackedBoolList& operator=(const bool val);
+
+ //- Assignment operator.
+ inline PackedBoolList& operator=(const PackedBoolList&);
+
+ //- Assignment operator.
+ inline PackedBoolList& operator=(const PackedList<1>&);
+
+ //- Assignment operator.
+ PackedBoolList& operator=(const UList&);
+
+ //- Assignment operator,
+ // using the labels as indices to indicate which bits are set
+ inline PackedBoolList& operator=(const UList& indices);
+
+ //- Assignment operator,
+ // using the labels as indices to indicate which bits are set
+ inline PackedBoolList& operator=(const UIndirectList&);
+
+ //- Complement operator
+ inline PackedBoolList operator~() const;
+
+ //- And operator (lists may be dissimilar sizes)
+ inline PackedBoolList& operator&=(const PackedList<1>&);
+
+ //- And operator (lists may be dissimilar sizes)
+ // using the labels as indices to indicate which bits are set
+ inline PackedBoolList& operator&=(const UList& indices);
+
+ //- And operator (lists may be dissimilar sizes)
+ // using the labels as indices to indicate which bits are set
+ inline PackedBoolList& operator&=(const UIndirectList&);
+
+ //- Xor operator (lists may be dissimilar sizes)
+ // Retains unique entries
+ PackedBoolList& operator^=(const PackedList<1>&);
+
+ //- Or operator (lists may be dissimilar sizes)
+ inline PackedBoolList& operator|=(const PackedList<1>&);
+
+ //- Or operator (lists may be dissimilar sizes),
+ // using the labels as indices to indicate which bits are set
+ inline PackedBoolList& operator|=(const UList& indices);
+
+ //- Or operator (lists may be dissimilar sizes),
+ // using the labels as indices to indicate which bits are set
+ inline PackedBoolList& operator|=(const UIndirectList&);
+
+
+ //- Add entries to this list, synonymous with the or operator
+ inline PackedBoolList& operator+=(const PackedList<1>&);
+
+ //- Add entries to this list, synonymous with the or operator
+ inline PackedBoolList& operator+=(const UList& indices);
+
+ //- Add entries to this list, synonymous with the or operator
+ inline PackedBoolList& operator+=(const UIndirectList&);
+
+ //- Remove entries from this list - unset the specified bits
+ inline PackedBoolList& operator-=(const PackedList<1>&);
+
+ //- Remove entries from this list - unset the specified bits
+ inline PackedBoolList& operator-=(const UList& indices);
+
+ //- Remove entries from this list - unset the specified bits
+ inline PackedBoolList& operator-=(const UIndirectList&);
+
+};
+
+
+// Global Operators
+
+//- Intersect lists - the result is trimmed to the smallest intersecting size
+PackedBoolList operator&
+(
+ const PackedBoolList& lst1,
+ const PackedBoolList& lst2
+);
+
+
+//- Combine to form a unique list (xor)
+// The result is trimmed to the smallest intersecting size
+PackedBoolList operator^
+(
+ const PackedBoolList& lst1,
+ const PackedBoolList& lst2
+);
+
+
+//- Combine lists
+PackedBoolList operator|
+(
+ const PackedBoolList& lst1,
+ const PackedBoolList& lst2
+);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "PackedBoolListI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H
new file mode 100644
index 0000000000..edbbc8d007
--- /dev/null
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H
@@ -0,0 +1,277 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2010-2010 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 .
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+inline Foam::PackedBoolList::PackedBoolList()
+:
+ PackedList<1>()
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const label size)
+:
+ PackedList<1>(size)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList
+(
+ const label size,
+ const bool val
+)
+:
+ PackedList<1>(size, (val ? 1u : 0u))
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const PackedBoolList& lst)
+:
+ PackedList<1>(lst)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const PackedList<1>& lst)
+:
+ PackedList<1>(lst)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const Xfer& lst)
+:
+ PackedList<1>()
+{
+ transfer(lst());
+}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const Xfer >& lst)
+:
+ PackedList<1>(lst)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const UList& lst)
+:
+ PackedList<1>()
+{
+ operator=(lst);
+}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const UList& indices)
+:
+ PackedList<1>(indices.size(), 0u)
+{
+ set(indices);
+}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const UIndirectList& indices)
+:
+ PackedList<1>(indices.size(), 0u)
+{
+ set(indices);
+}
+
+
+inline Foam::autoPtr
+Foam::PackedBoolList::clone() const
+{
+ return autoPtr(new PackedBoolList(*this));
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+inline void Foam::PackedBoolList::transfer(PackedBoolList& lst)
+{
+ PackedList<1>::transfer(static_cast&>(lst));
+}
+
+
+inline void Foam::PackedBoolList::transfer(PackedList<1>& lst)
+{
+ PackedList<1>::transfer(lst);
+}
+
+
+inline Foam::Xfer Foam::PackedBoolList::xfer()
+{
+ return xferMove(*this);
+}
+
+
+
+// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const bool val)
+{
+ PackedList<1>::operator=(val);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const PackedBoolList& lst)
+{
+ PackedList<1>::operator=(lst);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const PackedList<1>& lst)
+{
+ PackedList<1>::operator=(lst);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const UList& indices)
+{
+ clear();
+ set(indices);
+
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const UIndirectList& indices)
+{
+ clear();
+ set(indices);
+
+ return *this;
+}
+
+
+inline Foam::PackedBoolList
+Foam::PackedBoolList::operator~() const
+{
+ PackedBoolList result(*this);
+ result.flip();
+
+ return result;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator&=(const PackedList<1>& lst)
+{
+ subset(lst);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator&=(const UList& indices)
+{
+ subset(indices);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator&=(const UIndirectList& indices)
+{
+ subset(indices);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
+{
+ set(lst);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator|=(const UList& indices)
+{
+ set(indices);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator|=(const UIndirectList& indices)
+{
+ set(indices);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator+=(const PackedList<1>& lst)
+{
+ return operator|=(lst);
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator+=(const UList& indices)
+{
+ return operator|=(indices);
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator+=(const UIndirectList& indices)
+{
+ return operator|=(indices);
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator-=(const PackedList<1>& lst)
+{
+ unset(lst);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator-=(const UList& indices)
+{
+ unset(indices);
+ return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator-=(const UIndirectList& indices)
+{
+ unset(indices);
+ return *this;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
index 6bc8d79ead..98a6d2740a 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
@@ -24,35 +24,11 @@ License
\*---------------------------------------------------------------------------*/
#include "PackedList.H"
-
-// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
-
-template
-Foam::PackedList::PackedList(const label size, const unsigned int val)
-:
- StorageList(packedLength(size), 0u),
- size_(size)
-{
- operator=(val);
-}
-
-
-template
-Foam::PackedList::PackedList(const UList& lst)
-:
- StorageList(packedLength(lst.size()), 0u),
- size_(lst.size())
-{
- forAll(lst, i)
- {
- set(i, lst[i]);
- }
-}
+#include "IOstreams.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
-
#if (UINT_MAX == 0xFFFFFFFF)
// 32-bit counting, Hamming weight method
# define COUNT_PACKEDBITS(sum, x) \
@@ -82,25 +58,10 @@ unsigned int Foam::PackedList::count() const
if (size_)
{
- // mask value for complete segments
- unsigned int mask = maskLower(packing());
-
- const unsigned int endSeg = size_ / packing();
- const unsigned int endOff = size_ % packing();
-
- // count bits in complete segments
- for (unsigned i = 0; i < endSeg; ++i)
+ const label packLen = packedLength();
+ for (label i = 0; i < packLen; ++i)
{
- register unsigned int bits = StorageList::operator[](i) & mask;
- COUNT_PACKEDBITS(c, bits);
- }
-
- // count bits in partial segment
- if (endOff)
- {
- mask = maskLower(endOff);
-
- register unsigned int bits = StorageList::operator[](endSeg) & mask;
+ register unsigned int bits = StorageList::operator[](i);
COUNT_PACKEDBITS(c, bits);
}
}
@@ -117,64 +78,60 @@ bool Foam::PackedList::trim()
return false;
}
- // mask value for complete segments
- unsigned int mask = maskLower(packing());
-
- label currElem = packedLength(size_) - 1;
- unsigned int endOff = size_ % packing();
-
- // clear trailing bits on final segment
- if (endOff)
+ const label oldSize = size_;
+ for (label storeI = packedLength()-1; storeI >= 0; --storeI)
{
- StorageList::operator[](currElem) &= maskLower(endOff);
- }
+ size_ = storeI * packing();
+ unsigned int bits = StorageList::operator[](storeI);
- // test entire segment
- while (currElem > 0 && !(StorageList::operator[](currElem) &= mask))
- {
- currElem--;
- }
-
- // test segment
- label newsize = (currElem + 1) * packing();
-
- // mask for the final segment
- mask = max_value() << (nBits * (packing() - 1));
-
- for (endOff = packing(); endOff >= 1; --endOff, --newsize)
- {
- if (StorageList::operator[](currElem) & mask)
+ // found some bits
+ if (bits)
{
+ while (bits)
+ {
+ bits >>= nBits;
+ ++size_;
+ }
break;
}
-
- mask >>= nBits;
}
- if (size_ == newsize)
- {
- return false;
- }
-
- size_ = newsize;
- return false;
+ return (size_ != oldSize);
}
template
void Foam::PackedList::flip()
{
- label packLen = packedLength(size_);
-
- for (label i=0; i < packLen; i++)
+ if (!size_)
{
- StorageList::operator[](i) = ~StorageList::operator[](i);
+ return;
+ }
+
+ // mask value for complete segments
+ const unsigned int mask = maskLower(packing());
+
+ const label packLen = packedLength();
+ for (label i=0; i < packLen; ++i)
+ {
+ StorageList::operator[](i) = mask & ~StorageList::operator[](i);
+ }
+
+ // mask off the final partial segment
+ {
+ const unsigned int off = size_ % packing();
+ if (off)
+ {
+ const unsigned int seg = size_ / packing();
+
+ StorageList::operator[](seg) &= maskLower(off);
+ }
}
}
template
-Foam::labelList Foam::PackedList::values() const
+Foam::Xfer Foam::PackedList::values() const
{
labelList elems(size_);
@@ -182,12 +139,16 @@ Foam::labelList Foam::PackedList::values() const
{
elems[i] = get(i);
}
- return elems;
+
+ return elems.xfer();
}
template
-Foam::Ostream& Foam::PackedList::iteratorBase::print(Ostream& os) const
+Foam::Ostream& Foam::PackedList::iteratorBase::printInfo
+(
+ Ostream& os
+) const
{
os << "iterator<" << label(nBits) << "> ["
<< this->index_ << "]"
@@ -201,78 +162,381 @@ Foam::Ostream& Foam::PackedList::iteratorBase::print(Ostream& os) const
template
-Foam::Ostream& Foam::PackedList::print(Ostream& os) const
+Foam::Ostream& Foam::PackedList::printBits
+(
+ Ostream& os,
+ const bool fullOutput
+) const
{
- const label packLen = packedLength(size_);
-
- os << "PackedList<" << nBits << ">"
- << " max_value:" << max_value()
- << " packing:" << packing() << nl
- << " count: " << count() << nl
- << " size/capacity: " << size_ << "/" << capacity() << nl
- << " storage/capacity: " << packLen << "/" << StorageList::size()
- << "\n(\n";
+ const label packLen = packedLength();
// mask value for complete segments
unsigned int mask = maskLower(packing());
+ const label outputLen = fullOutput ? StorageList::size() : packLen;
- for (label i=0; i < packLen; i++)
+ os << "(\n";
+ for (label i=0; i < outputLen; ++i)
{
const StorageType& rawBits = StorageList::operator[](i);
// the final segment may not be full, modify mask accordingly
- if (i+1 == packLen)
+ if (i == packLen-1)
{
- unsigned int endOff = size_ % packing();
+ const unsigned int off = size_ % packing();
- if (endOff)
+ if (off)
{
- mask = maskLower(endOff);
- }
- else
- {
- continue;
+ mask = maskLower(off);
}
}
+ else if (i == packLen)
+ {
+ // no mask for unaddressed bit
+ mask = 0u;
+ }
+
for (unsigned int testBit = (1u << max_bits()); testBit; testBit >>= 1)
{
if (mask & testBit)
{
+ // addressable region
if (rawBits & testBit)
{
- os << '1';
+ os << '1';
}
else
{
- os << '-';
+ os << '-';
}
}
else
{
- os << 'x';
+ if (rawBits & testBit)
+ {
+ os << '!';
+ }
+ else
+ {
+ os << '.';
+ }
}
}
- os << '\n';
+ os << '\n';
}
- os << ")\n";
+ os << ")\n";
return os;
}
+template
+Foam::Ostream& Foam::PackedList::printInfo
+(
+ Ostream& os,
+ const bool fullOutput
+) const
+{
+ os << "PackedList<" << nBits << ">"
+ << " max_value:" << max_value()
+ << " packing:" << packing() << nl
+ << " count: " << count() << nl
+ << " size/capacity: " << size_ << "/" << capacity() << nl
+ << " storage/capacity: "
+ << packedLength() << "/" << StorageList::size()
+ << "\n";
+
+ return printBits(os, fullOutput);
+}
+
+
+template
+Foam::Istream& Foam::PackedList::read(Istream& is)
+{
+ PackedList& lst = *this;
+
+ lst.clear();
+ is.fatalCheck("PackedList::read(Istream&)");
+
+ token firstTok(is);
+ is.fatalCheck
+ (
+ "PackedList::read(Istream&) : "
+ "reading first token"
+ );
+
+ if (firstTok.isLabel())
+ {
+ const label sz = firstTok.labelToken();
+
+ // Set list length to that read
+ lst.resize(sz);
+
+ // Read list contents depending on data format
+ if (is.format() == IOstream::ASCII)
+ {
+ // Read beginning of contents
+ const char delimiter = is.readBeginList("PackedList");
+
+ if (sz)
+ {
+ if (delimiter == token::BEGIN_LIST)
+ {
+ for (register label i=0; i::read(Istream&) : "
+ "reading entry"
+ );
+ }
+ }
+ else if (delimiter == token::BEGIN_BLOCK)
+ {
+ // assign for all entries
+ lst = lst.readValue(is);
+
+ is.fatalCheck
+ (
+ "PackedList::read(Istream&) : "
+ "reading the single entry"
+ );
+ }
+ else
+ {
+ FatalIOErrorIn
+ (
+ "PackedList::read(Istream&)",
+ is
+ )
+ << "incorrect list token, expected '(' or '{', found "
+ << firstTok.info()
+ << exit(FatalIOError);
+ }
+ }
+
+ // Read end of contents
+ is.readEndList("PackedList");
+ }
+ else
+ {
+ if (sz)
+ {
+ is.read
+ (
+ reinterpret_cast(lst.storage().data()),
+ lst.byteSize()
+ );
+
+ is.fatalCheck
+ (
+ "PackedList::read(Istream&) : "
+ "reading the binary block"
+ );
+ }
+ }
+ }
+ else if (firstTok.isPunctuation())
+ {
+ if (firstTok.pToken() == token::BEGIN_LIST)
+ {
+ token nextTok(is);
+ is.fatalCheck("PackedList::read(Istream&)");
+
+ while
+ (
+ !( nextTok.isPunctuation()
+ && nextTok.pToken() == token::END_LIST
+ )
+ )
+ {
+ is.putBack(nextTok);
+ lst.append(lst.readValue(is));
+
+ is >> nextTok;
+ is.fatalCheck("PackedList::read(Istream&)");
+ }
+ }
+ else if (firstTok.pToken() == token::BEGIN_BLOCK)
+ {
+ token nextTok(is);
+ is.fatalCheck("PackedList::read(Istream&)");
+
+ while
+ (
+ !( nextTok.isPunctuation()
+ && nextTok.pToken() == token::END_BLOCK
+ )
+ )
+ {
+ is.putBack(nextTok);
+ lst.setPair(is);
+
+ is >> nextTok;
+ is.fatalCheck("PackedList::read(Istream&)");
+ }
+ }
+ else
+ {
+ FatalIOErrorIn
+ (
+ "PackedList::read(Istream&)",
+ is
+ )
+ << "incorrect first token, expected '(', found "
+ << firstTok.info()
+ << exit(FatalIOError);
+ }
+ }
+ else
+ {
+ FatalIOErrorIn
+ (
+ "PackedList::read(Istream&)",
+ is
+ )
+ << "incorrect first token, expected , '(' or '{', found "
+ << firstTok.info()
+ << exit(FatalIOError);
+ }
+
+ return is;
+}
+
+
+template
+Foam::Ostream& Foam::PackedList::write
+(
+ Ostream& os,
+ const bool indexedOutput
+) const
+{
+ const PackedList& lst = *this;
+ const label sz = lst.size();
+
+ // Write list contents depending on data format
+ if (os.format() == IOstream::ASCII)
+ {
+ bool uniform = false;
+
+ if (sz > 1 && !indexedOutput)
+ {
+ uniform = true;
+
+ forAll(lst, i)
+ {
+ if (lst[i] != lst[0])
+ {
+ uniform = false;
+ break;
+ }
+ }
+ }
+
+ if (uniform)
+ {
+ // uniform values:
+ os << sz << token::BEGIN_BLOCK << lst[0] << token::END_BLOCK;
+ }
+ else if (indexedOutput)
+ {
+ // indexed output
+ os << nl << token::BEGIN_BLOCK << nl;
+
+ for
+ (
+ typename PackedList::const_iterator iter = lst.cbegin();
+ iter != lst.cend();
+ ++iter
+ )
+ {
+ if (iter.writeIfSet(os))
+ {
+ os << nl;
+ }
+ }
+
+ os << token::END_BLOCK << nl;
+ }
+ else if (sz < 11)
+ {
+ // short list:
+ os << sz << token::BEGIN_LIST;
+ forAll(lst, i)
+ {
+ if (i)
+ {
+ os << token::SPACE;
+ }
+ os << lst[i];
+ }
+ os << token::END_LIST;
+ }
+ else
+ {
+ // longer list:
+ os << nl << sz << nl << token::BEGIN_LIST;
+ forAll(lst, i)
+ {
+ os << nl << lst[i];
+ }
+ os << nl << token::END_LIST << nl;
+ }
+ }
+ else
+ {
+ os << nl << sz << nl;
+ if (sz)
+ {
+ os.write
+ (
+ reinterpret_cast(lst.storage().cdata()),
+ lst.byteSize()
+ );
+ }
+ }
+
+ return os;
+}
+
+
+template
+void Foam::PackedList::writeEntry(Ostream& os) const
+{
+ os << *this;
+}
+
+
+template
+void Foam::PackedList::writeEntry
+(
+ const word& keyword,
+ Ostream& os
+) const
+{
+ os.writeKeyword(keyword);
+ writeEntry(os);
+ os << token::END_STATEMENT << endl;
+}
+
+
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template
-void Foam::PackedList::operator=(const PackedList& lst)
+Foam::PackedList&
+Foam::PackedList::operator=(const PackedList& lst)
{
StorageList::operator=(lst);
size_ = lst.size();
+ return *this;
}
template
-void Foam::PackedList::operator=(const UList& lst)
+Foam::PackedList&
+Foam::PackedList::operator=(const UList& lst)
{
setCapacity(lst.size());
size_ = lst.size();
@@ -281,19 +545,39 @@ void Foam::PackedList::operator=(const UList& lst)
{
set(i, lst[i]);
}
+ return *this;
}
-// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
+template
+Foam::PackedList&
+Foam::PackedList::operator=(const UIndirectList& lst)
+{
+ setCapacity(lst.size());
+ size_ = lst.size();
-//template
-//Foam::Ostream& ::Foam::operator<<(Ostream& os, const PackedList& lst)
-//{
-// os << lst();
-// return os;
-//}
+ forAll(lst, i)
+ {
+ set(i, lst[i]);
+ }
+ return *this;
+}
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
+
+template
+Foam::Istream& Foam::operator>>(Istream& is, PackedList& lst)
+{
+ return lst.read(is);
+}
+
+
+template
+Foam::Ostream& Foam::operator<<(Ostream& os, const PackedList& lst)
+{
+ return lst.write(os, false);
+}
+
// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
index 76c0e97b80..f4cdce7aab 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
@@ -72,6 +72,23 @@ Note
list[8] = 1;
@endcode
+ Also note that all unused internal storage elements are guaranteed to
+ always be bit-wise zero. This property must not be violated by any
+ inheriting classes.
+
+ In addition to the normal output format, PackedList also supports a
+ compact ASCII format that may be convenient for user input in some
+ situations. The general format is a group of index/value pairs:
+ @verbatim
+ { (index1 value1) (index2 value2) (index3 value3) }
+ @endverbatim
+ The bool specialization just uses the indices corresponding to
+ non-zero entries instead of a index/value pair:
+ @verbatim
+ { index1 index2 index3 }
+ @endverbatim
+ In both cases, the supplied indices can be randomly ordered.
+
SeeAlso
Foam::DynamicList
@@ -85,6 +102,7 @@ SourceFiles
#define PackedList_H
#include "labelList.H"
+#include "UIndirectList.H"
#include "StaticAssert.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -92,18 +110,34 @@ SourceFiles
namespace Foam
{
+// Forward declaration of classes
+class Istream;
+class Ostream;
+
// Forward declaration of friend functions and operators
template class PackedList;
-// template
-// Ostream& operator<<(Ostream&, const PackedList&);
+template
+Istream& operator>>(Istream&, PackedList&);
+template
+Ostream& operator<<(Ostream&, const PackedList&);
/*---------------------------------------------------------------------------*\
- Class PackedListName Declaration
+ Class PackedListCore Declaration
\*---------------------------------------------------------------------------*/
-TemplateName(PackedList);
+//- Template-invariant bits for PackedList
+struct PackedListCore
+{
+ //- Construct null
+ PackedListCore()
+ {}
+
+ //- Define template name and debug
+ ClassName("PackedList");
+};
+
/*---------------------------------------------------------------------------*\
Class PackedList Declaration
@@ -112,26 +146,40 @@ TemplateName(PackedList);
template
class PackedList
:
+ public PackedListCore,
private List
{
+protected:
+
typedef unsigned int StorageType;
typedef List StorageList;
- //- nBits must be positive (non-zero) and fit within the storage
- // For simplicity, assume 8-bit bytes
- StaticAssert(nBits && nBits < (sizeof(StorageType) << 3));
+ // Protected Member Functions
+
+ //- Calculate the list length when packed
+ inline static label packedLength(const label);
+
+ //- Read a list entry (allows for specialization)
+ inline static unsigned int readValue(Istream&);
+
+ //- Read an index/value pair and set accordingly.
+ // For bool specialization, read a single index value
+ inline void setPair(Istream&);
+
+private:
+
+ //- nBits must be positive (non-zero) and fit within the storage.
+ // For efficiency, however, require packing at least 2 items otherwise
+ // it is more efficient to use a normal list.
+ // Thus max nBits is 1/2 of the base storage size.
+ // For simplicity, assume 8-bit bytes in the assert.
+ StaticAssert(nBits && nBits <= (sizeof(StorageType) << 2));
// Private data
//- Number of nBits entries
label size_;
- // Private Member Functions
-
- //- Calculate the list length when packed
- inline static label packedLength(const label);
-
-
public:
// Public data
@@ -163,20 +211,26 @@ public:
//- Null constructor
inline PackedList();
- //- Construct with given size, initializes list to 0.
+ //- Construct with given size, initializes list to 0
explicit inline PackedList(const label size);
- //- Construct with given size and value for all elements.
- PackedList(const label size, const unsigned val);
+ //- Construct with given size and value for all elements
+ inline PackedList(const label size, const unsigned val);
- //- Copy constructor.
+ //- Construct from Istream
+ inline PackedList(Istream&);
+
+ //- Copy constructor
inline PackedList(const PackedList&);
//- Construct by transferring the parameter contents
inline PackedList(const Xfer >&);
//- Construct from a list of labels
- explicit PackedList(const UList&);
+ explicit inline PackedList(const UList&);
+
+ //- Construct from an indirect list of labels
+ explicit inline PackedList(const UIndirectList&);
//- Clone
inline autoPtr< PackedList > clone() const;
@@ -209,30 +263,52 @@ public:
inline bool unset(const label);
//- Return the underlying packed storage
+ // Manipulate with utmost caution
inline List& storage();
//- Return the underlying packed storage
inline const List& storage() const;
+ //- The list length when packed
+ inline label packedLength() const;
+
+ //- Return the binary size in number of characters
+ // used in the underlying storage
+ inline label byteSize() const;
+
//- Count number of bits set, O(log(n))
// Uses the Hamming weight (population count) method
// http://en.wikipedia.org/wiki/Hamming_weight
unsigned int count() const;
- //- Return the values as a labelList
- labelList values() const;
+ //- Return the values as a list of labels
+ Xfer values() const;
+
+ //- Print bit patterns, optionally output unused elements
+ //
+ // addressable bits:
+ // on: '1', off: '-'
+ //
+ // non-addressable bits:
+ // on: '!', off: '.'
+ //
+ Ostream& printBits(Ostream&, const bool fullOutput=false) const;
+
+ //- Print information and bit patterns (with printBits)
+ Ostream& printInfo(Ostream&, const bool fullOutput=false) const;
- //- Print values and information
- Ostream& print(Ostream&) const;
// Edit
//- Trim any trailing zero elements
bool trim();
- //- Invert the bits in the addressable region.
+ //- Invert the bits in the addressable region
void flip();
+ //- Clear all bits
+ inline void reset();
+
//- Alter the size of the underlying storage.
// The addressed size will be truncated if needed to fit, but will
// remain otherwise untouched.
@@ -240,10 +316,10 @@ public:
//- Reset addressable list size, does not shrink the allocated size.
// Optionally specify a value for new elements.
- inline void resize(const label, const unsigned int& val = 0);
+ inline void resize(const label, const unsigned int& val = 0u);
//- Alias for resize()
- inline void setSize(const label, const unsigned int& val = 0);
+ inline void setSize(const label, const unsigned int& val = 0u);
//- Reserve allocation space for at least this size.
// Never shrinks the allocated size.
@@ -269,10 +345,43 @@ public:
inline Xfer > xfer();
+ // IO
+
+ //- Clear list and read from stream
+ Istream& read(Istream&);
+
+ //- Write, optionally with indexedOutput
+ //
+ // The indexed output may be convenient in some situations.
+ // The general format is a group of index/value pairs:
+ // @verbatim
+ // { (index1 value1) (index2 value2) (index3 value3) }
+ // @endverbatim
+ // The bool specialization just uses the indices corresponding to
+ // non-zero entries instead of a index/value pair:
+ // @verbatim
+ // { index1 index2 index3 }
+ // @endverbatim
+ //
+ // Note the indexed output is only supported for ASCII streams.
+ Ostream& write
+ (
+ Ostream&,
+ const bool indexedOutput=false
+ ) const;
+
+
+ //- Write as a dictionary entry
+ void writeEntry(Ostream&) const;
+
+ //- Write as a dictionary entry with keyword
+ void writeEntry(const word& keyword, Ostream&) const;
+
+
// Member operators
//- Append a value at the end of the list
- inline void append(const unsigned int val);
+ inline PackedList& append(const unsigned int val);
//- Remove and return the last element
inline unsigned int remove();
@@ -287,23 +396,16 @@ public:
inline iteratorBase operator[](const label);
//- Assignment of all entries to the given value. Takes linear time.
- inline void operator=(const unsigned int val);
+ inline PackedList