ENH: several improvements for linked-lists

- support move construct/assignment for linked-lists themselves
  and when moving into a 'normal' list

- better consistency with begin/end signatures and the various
  iterators.

- for indirect linked-lists, provide iterator access to the underlying
  data element address:   iter.get()  vs  &(iter())

- add standard '->' indirection for iterators (as per normal STL
  definitions)
This commit is contained in:
Mark Olesen
2017-11-27 14:11:25 +01:00
parent 3a4b92c4b2
commit cc5f30f25e
53 changed files with 3147 additions and 2043 deletions

View File

@ -28,20 +28,39 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "OSspecific.H" #include "OSspecific.H"
#include "IOstreams.H" #include "IOstreams.H"
#include "DLList.H" #include "DLList.H"
#include "List.H"
#include "FlatOutput.H"
#include "ListOps.H"
using namespace Foam; using namespace Foam;
template<class T>
void printAddress(const UList<T>& list)
{
Info<< "list addr: " << long(&list)
<< " data addr: " << long(list.cdata()) << nl;
}
template<class T>
void printAddresses(const DLList<List<T>>& sll)
{
for (const auto& elem : sll)
{
printAddress(elem);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
DLList<scalar> myList; DLList<scalar> myList{2.1, 3.4};
myList = {2.1, 3.4, 4.3};
Info<< "DLList<scalar>" << nl;
for (int i = 0; i<10; i++) for (int i = 0; i<10; i++)
{ {
@ -51,58 +70,165 @@ int main(int argc, char *argv[])
myList.append(100.3); myList.append(100.3);
myList.append(500.3); myList.append(500.3);
forAllConstIters(myList, iter) Info<< "DLList<scalar>" << nl;
Info<< nl << "flat-output: " << flatOutput(myList) << nl;
Info<< nl << "range-for:" << nl;
for (const auto& val : myList)
{ {
Info<< "element:" << *iter << endl; Info<< " " << val << nl;
} }
Info<< nl << "And again using the same STL iterator: " << nl << endl; Info<< nl << "const_iterator:" << nl;
forAllConstIters(myList, iter)
{
Info<< " " << *iter << endl;
}
// Test bi-directional movement
{
const label n2 = myList.size()/2;
Info<< nl << "test movement through " << flatOutput(myList) << nl;
DLList<scalar>::const_iterator citer = myList.begin();
for (label i=0; i<n2; ++i)
{
Info<< " forward " << i << " " << *citer << nl;
++citer;
}
for (label i=0; i<n2; ++i)
{
Info<< " backward " << i << " " << *citer << nl;
--citer;
}
// Verify - does not compile since it uses a delete method (good!)
DLList<scalar>::iterator iter = myList.begin();
++iter;
++iter;
++iter;
Info<<" now with " << *iter << nl;
myList.remove(iter);
Info<<" after remove " << *iter << nl;
++iter;
Info<<" after incr " << *iter << nl;
--iter;
--iter;
Info<<" after 2x decr " << *iter << nl;
}
Info<< nl << "const_reverse_iterator:" << nl;
forAllConstReverseIters(myList, iter)
{
Info<< " " << *iter << endl;
}
Info<< nl << "Remove elements:" << nl;
forAllIters(myList, iter) forAllIters(myList, iter)
{ {
Info<< "Removing " << myList.remove(iter) << endl; Info<< " remove " << *iter;
myList.remove(iter);
Info<< " => " << flatOutput(myList) << nl;
} }
myList.append(500.3); myList.append(500.3);
myList.append(200.3); myList.append(200.3);
myList.append(100.3); myList.append(100.3);
Info<< nl << "Using range-based for: " << nl << endl; Info<< nl << "Testing swapUp and swapDown:" << nl;
for (auto val : myList) Info<< " => " << flatOutput(myList) << nl;
{ {
Info<< "element:" << val << endl; myList.swapUp(myList.DLListBase::first());
myList.swapUp(myList.DLListBase::last());
Info<< nl << "swapUp => " << flatOutput(myList) << nl;
} }
Info<< nl << "Testing swapUp and swapDown: " << endl;
Info<< nl << "swapUp" << endl;
myList.swapUp(myList.DLListBase::first());
myList.swapUp(myList.DLListBase::last());
for (auto val : myList)
{ {
Info<< "element:" << val << endl; myList.swapDown(myList.DLListBase::first());
myList.swapDown(myList.DLListBase::last());
Info<< nl << "swapDown => " << flatOutput(myList) << nl;
} }
Info<< nl << "swapDown" << endl;
myList.swapDown(myList.DLListBase::first()); Info<< nl << "Transfer: " << nl;
myList.swapDown(myList.DLListBase::last()); Info<< "original: " << flatOutput(myList) << endl;
for (auto val : myList)
{
Info<< "element:" << val << endl;
}
Info<< nl << "Testing transfer: " << nl << nl
<< "original: " << myList << endl;
DLList<scalar> newList; DLList<scalar> newList;
newList.transfer(myList); newList.transfer(myList);
Info<< nl << "source: " << myList << nl Info<< nl
<< nl << "target: " << newList << endl; << "source: " << flatOutput(myList) << nl
<< "target: " << flatOutput(newList) << nl;
Info<< nl << "Move Construct: " << nl;
DLList<scalar> list2(std::move(newList));
Info<< nl
<< "in : " << flatOutput(newList) << nl
<< "out: " << flatOutput(list2) << nl;
// Move back
Info<< nl << "Move Assignment: " << nl;
newList = std::move(list2);
Info<< nl
<< "in : " << flatOutput(newList) << nl
<< "out: " << flatOutput(list2) << nl;
// Try delete data recovery
{
DLList<List<label>> labList;
for (int i = 0; i<5; i++)
{
labList.append(identity(6));
}
Info<< nl
<< "DLList<labelList> : " << labList << nl;
printAddresses(labList);
auto elem = labList.removeHead();
Info<< " removed head" << nl;
printAddress(elem);
elem = labList.removeHead();
Info<< " removed head" << nl;
printAddress(elem);
List<label> content1 = identity(10);
Info<< nl
<< " move append ";
printAddress(content1);
labList.append(std::move(content1));
Info<< " content " << flatOutput(content1) << nl
<< " list" << labList << nl;
printAddresses(labList);
// labList.append(content1);
}
Info<< nl << "Done." << endl; Info<< nl << "Done." << endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,9 +28,12 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "OSspecific.H" #include "OSspecific.H"
#include "IOstreams.H" #include "IOstreams.H"
#include "ISLList.H" #include "ISLList.H"
#include "List.H"
#include "FlatOutput.H"
#include "ListOps.H"
#include "OSspecific.H"
using namespace Foam; using namespace Foam;
@ -66,7 +69,7 @@ public:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
ISLList<Scalar> myList; ISLList<Scalar> myList(new Scalar(0));
for (int i = 0; i<10; i++) for (int i = 0; i<10; i++)
{ {
@ -76,31 +79,74 @@ int main(int argc, char *argv[])
myList.append(new Scalar(100.3)); myList.append(new Scalar(100.3));
myList.append(new Scalar(500.3)); myList.append(new Scalar(500.3));
Info<< nl << "And again using STL iterator: " << nl << endl; Info<< "ISLList<scalar>" << myList << nl;
Info<< nl << "flat-output: " << flatOutput(myList) << nl;
forAllIters(myList, iter) Info<< nl << "range-for:" << nl;
for (const auto& val : myList)
{ {
Info<< "element:" << *iter << endl; Info<< " " << val << nl;
// Info<<" is " << typeid(val).name() << endl;
} }
Info<< nl << "And again using STL const_iterator: " << nl << endl; Info<< nl << "const_iterator:" << nl;
const ISLList<Scalar>& const_myList = myList; const ISLList<Scalar>& const_myList = myList;
forAllConstIters(const_myList, iter) forAllConstIters(const_myList, iter)
{ {
Info<< "element:" << *iter << endl; Info<< " " << *iter << endl;
}
{
Info<< nl << "Remove element:" << nl;
Scalar *iter = myList.removeHead();
Info<< " remove " << *iter;
Info<< " => " << flatOutput(myList) << nl;
delete iter;
} }
Info<< nl << "Testing transfer: " << nl << endl; Info<< nl << "Transfer: " << nl;
Info<< "original: " << myList << endl; Info<< "original: " << flatOutput(myList) << endl;
ISLList<Scalar> newList; ISLList<Scalar> newList;
newList.transfer(myList); newList.transfer(myList);
Info<< nl << "source: " << myList << nl Info<< nl
<< nl << "target: " << newList << endl; << "source: " << flatOutput(myList) << nl
<< "target: " << flatOutput(newList) << endl;
myList.swap(newList);
Info<< nl << "swap: " << nl;
Info<< nl
<< "source: " << flatOutput(myList) << nl
<< "target: " << flatOutput(newList) << endl;
myList.swap(newList);
Info<< nl << "Move Construct: " << nl;
ISLList<Scalar> list2(std::move(newList));
Info<< nl
<< "in : " << flatOutput(newList) << nl
<< "out: " << flatOutput(list2) << nl;
// Move back
Info<< nl << "Move Assignment: " << nl;
newList = std::move(list2);
Info<< nl << "move assign: " << nl;
Info<< nl
<< "source: " << flatOutput(list2) << nl
<< "target: " << flatOutput(newList) << endl;
Info<< nl << "Bye." << endl; Info<< nl << "Bye." << endl;
return 0; return 0;

View File

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

View File

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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-List3
Description
Test list construction
\*---------------------------------------------------------------------------*/
#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 T>
void printAddress(const UList<T>& list)
{
Info<< "list addr: " << long(&list)
<< " data addr: " << long(list.cdata()) << nl;
}
template<class T>
void printAddress(const SLList<T>& list)
{
Info<< "list addr: " << long(&list)
<< " data addr: ???" << nl;
}
template<class T>
void printAddresses(const List<List<T>>& list)
{
for (const auto& elem : list)
{
printAddress(elem);
}
}
template<class T>
void printAddresses(const SLList<List<T>>& list)
{
for (const auto& elem : list)
{
printAddress(elem);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addBoolOption("labelListList");
argList args(argc, argv, false);
if (args.options().empty())
{
Info<< nl << "Specify an option! " << nl << endl;
}
if (args.optionFound("labelListList"))
{
for (label argi=1; argi < args.size(); ++argi)
{
if (true)
{
IFstream is(args[argi]);
Info<< nl << nl
<< "read from " << is.name() << nl << endl;
SLList<List<label>> sll(is);
Info<< "read " << sll.size() << " entries" << nl;
Info<< "sll" << nl;
for (const auto& elem : sll)
{
printAddress(elem);
}
// List<List<label>> list(std::move(sll));
List<List<label>> list;
Info<< "move to List" << nl;
list = std::move(sll);
Info<< "sll" << nl;
for (const auto& elem : sll)
{
printAddress(elem);
}
Info<< "list" << nl;
printAddresses(list);
}
if (true)
{
IFstream is(args[argi]);
Info<< nl << nl
<< "read from " << is.name() << nl << endl;
List<List<label>> list(is);
Info<< "list" << nl;
for (const auto& elem : list)
{
printAddress(elem);
}
}
}
}
Info<< nl << "Done" << nl << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,8 @@
// List of labelList
(
(1 2 3 4)
(5 6 7 8)
(15 16 17 18)
)

View File

@ -32,6 +32,8 @@ Description
#include "scalar.H" #include "scalar.H"
#include "IOstreams.H" #include "IOstreams.H"
#include "PtrList.H" #include "PtrList.H"
#include "DLPtrList.H"
#include "SLPtrList.H"
#include "plane.H" #include "plane.H"
#include "DynamicList.H" #include "DynamicList.H"
@ -80,6 +82,36 @@ int main(int argc, char *argv[])
PtrList<Scalar> list2(15); PtrList<Scalar> list2(15);
PtrList<Scalar> listApp; PtrList<Scalar> listApp;
{
DLPtrList<Scalar> llist1;
llist1.insert(new Scalar(100));
llist1.insert(new Scalar(200));
llist1.insert(new Scalar(300));
DLPtrList<Scalar>::const_iterator citer = llist1.begin();
Info<< *citer << endl;
Info<< typeid(*citer).name() << endl;
++citer;
++citer;
--citer;
Info<< typeid(llist1.begin()).name() << endl;
forAllIters(llist1, it)
{
Info<< typeid(*it).name() << endl;
Info<< "reversed: " << *it << endl;
}
for (const auto& it : llist1)
{
Info<< typeid(it).name() << endl;
Info<< "for-: " << it << endl;
}
}
forAll(list1, i) forAll(list1, i)
{ {
list1.set(i, new Scalar(1.3*i)); list1.set(i, new Scalar(1.3*i));

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,12 +28,32 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "OSspecific.H" #include "OSspecific.H"
#include "IOstreams.H" #include "IOstreams.H"
#include "SLList.H" #include "SLList.H"
#include "List.H"
#include "FlatOutput.H"
#include "ListOps.H"
using namespace Foam; using namespace Foam;
template<class T>
void printAddress(const UList<T>& list)
{
Info<< "list addr: " << long(&list)
<< " data addr: " << long(list.cdata()) << nl;
}
template<class T>
void printAddresses(const SLList<List<T>>& sll)
{
for (const auto& elem : sll)
{
printAddress(elem);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program: // Main program:
@ -50,34 +70,34 @@ int main(int argc, char *argv[])
myList.append(100.3); myList.append(100.3);
myList.append(500.3); myList.append(500.3);
Info<< nl << "And again using STL iterator: " << nl << endl; Info<< "SLList<scalar>" << myList << nl;
Info<< nl << "flat-output: " << flatOutput(myList) << nl;
Info<< nl << "range-for:" << nl;
for (const auto& val : myList) for (const auto& val : myList)
{ {
Info<< "element:" << val << endl; Info<< " " << val << nl;
} }
Info<< nl << "And again using STL const_iterator: " << nl << endl; Info<< nl << "const_iterator:" << nl;
const SLList<scalar>& const_myList = myList; const SLList<scalar>& const_myList = myList;
forAllConstIters(const_myList, iter) forAllConstIters(const_myList, iter)
{ {
Info<< "element:" << *iter << endl; Info<< " " << *iter << endl;
} }
Info<< nl << "Remove elements:" << nl;
forAllIters(myList, iter) forAllIters(myList, iter)
{ {
Info<< "Removing element:" << *iter << endl; Info<< " remove " << *iter;
myList.remove(iter); myList.remove(iter);
}
for (const auto& val : const_myList) Info<< " => " << flatOutput(myList) << nl;
{
Info<< "element:" << val << endl;
} }
for (int i = 0; i<10; i++) for (int i = 0; i<10; i++)
{ {
myList.append(1.3*i); myList.append(1.3*i);
@ -86,15 +106,72 @@ int main(int argc, char *argv[])
myList.append(100.3); myList.append(100.3);
myList.append(500.3); myList.append(500.3);
Info<< nl << "Testing transfer: " << nl << endl; Info<< nl << "Transfer: " << nl;
Info<< "original: " << myList << endl; Info<< "original: " << flatOutput(myList) << endl;
SLList<scalar> newList; SLList<scalar> newList;
newList.transfer(myList); newList.transfer(myList);
Info<< nl << "source: " << myList << nl Info<< nl
<< nl << "target: " << newList << endl; << "source: " << flatOutput(myList) << nl
<< "target: " << flatOutput(newList) << nl;
Info<< nl << "Move Construct: " << nl;
SLList<scalar> list2(std::move(newList));
Info<< nl
<< "in : " << flatOutput(newList) << nl
<< "out: " << flatOutput(list2) << nl;
// Move back
Info<< nl << "Move Assignment: " << nl;
newList = std::move(list2);
Info<< nl
<< "in : " << flatOutput(newList) << nl
<< "out: " << flatOutput(list2) << nl;
// Try delete data recovery
{
SLList<List<label>> labList;
for (int i = 0; i<5; i++)
{
labList.append(identity(6));
}
Info<< nl
<< "SLList<labelList> : " << labList << nl;
printAddresses(labList);
auto elem = labList.removeHead();
Info<< " removed head" << nl;
printAddress(elem);
elem = labList.removeHead();
Info<< " removed head" << nl;
printAddress(elem);
List<label> content1 = identity(10);
Info<< nl
<< " move append ";
printAddress(content1);
labList.append(std::move(content1));
Info<< " content " << flatOutput(content1) << nl
<< " list" << labList << nl;
printAddresses(labList);
// labList.append(content1);
}
Info<< nl << "Done." << endl; Info<< nl << "Done." << endl;
return 0; return 0;

View File

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

View File

View File

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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-UList
Description
Simple tests for UList constructors
See also
Foam::List
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "IOstreams.H"
#include "StringStream.H"
#include "labelList.H"
#include "ListOps.H"
#include "SubList.H"
#include "FlatOutput.H"
using namespace Foam;
template<class ListType>
void print(const ListType& list)
{
Info << flatOutput(list) << " data addr: " << long(list.cdata()) << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
List<label> source = identity(7);
List<label> other = identity(7);
// Text for reading as a SLList"
string inputSLList("(10 20 30 40 50 60 70)");
// Text for reading as a SLList"
string inputCompound("List<label> (-1 -2 -3 -4 -5 -6 -7)");
reverse(other);
UList<label> ulist(source.data(), source.size());
Info<<"source: "; print(source);
Info<<"other: "; print(other);
Info<<"UList: "; print(ulist);
{
Info<<"shallow copy" << nl;
ulist.shallowCopy(other);
Info<<"source: "; print(source);
Info<<"other: "; print(other);
Info<<"UList: "; print(ulist);
}
{
Info<<"deep copy" << nl;
ulist.deepCopy(source);
Info<<"source: "; print(source);
Info<<"other: "; print(other);
Info<<"UList: "; print(ulist);
}
{
Info<<"Read from " << inputSLList << nl;
IStringStream is(inputSLList);
is >> ulist;
// Info<<"source: "; print(source);
// Info<<"other: "; print(other);
Info<<"UList: "; print(ulist);
}
{
Info<<"Read from " << inputCompound << nl;
IStringStream is(inputCompound);
is >> ulist;
// Info<<"source: "; print(source);
// Info<<"other: "; print(other);
Info<<"UList: "; print(ulist);
}
return 0;
}
// ************************************************************************* //

View File

@ -70,11 +70,11 @@ class HashPtrTable
//- Read from Istream using given Istream constructor class //- Read from Istream using given Istream constructor class
template<class INew> template<class INew>
void read(Istream& is, const INew& inewt); void read(Istream& is, const INew& inew);
//- Read from dictionary using given dictionary constructor class //- Read from dictionary using given dictionary constructor class
template<class INew> template<class INew>
void read(const dictionary& dict, const INew& inewt); void read(const dictionary& dict, const INew& inew);
public: public:
@ -99,7 +99,7 @@ public:
//- Construct from Istream using given Istream constructor class //- Construct from Istream using given Istream constructor class
template<class INew> template<class INew>
HashPtrTable(Istream& is, const INew& inewt); HashPtrTable(Istream& is, const INew& inew);
//- Construct from Istream using default Istream constructor class //- Construct from Istream using default Istream constructor class
HashPtrTable(Istream& is); HashPtrTable(Istream& is);

View File

@ -33,7 +33,7 @@ License
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
template<class INew> template<class INew>
void Foam::HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt) void Foam::HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inew)
{ {
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
@ -47,25 +47,25 @@ void Foam::HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
if (firstToken.isLabel()) if (firstToken.isLabel())
{ {
const label s = firstToken.labelToken(); const label len = firstToken.labelToken();
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("HashPtrTable"); const char delimiter = is.readBeginList("HashPtrTable");
if (s) if (len)
{ {
if (2*s > this->capacity()) if (2*len > this->capacity())
{ {
this->resize(2*s); this->resize(2*len);
} }
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<s; ++i) for (label i=0; i<len; ++i)
{ {
Key key; Key key;
is >> key; is >> key;
this->insert(key, inewt(key, is).ptr()); this->insert(key, inew(key, is).ptr());
is.fatalCheck is.fatalCheck
( (
@ -110,7 +110,7 @@ void Foam::HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
is.putBack(lastToken); is.putBack(lastToken);
Key key; Key key;
is >> key; is >> key;
this->insert(key, inewt(key, is).ptr()); this->insert(key, inew(key, is).ptr());
is.fatalCheck is.fatalCheck
( (
@ -140,14 +140,14 @@ template<class INew>
void Foam::HashPtrTable<T, Key, Hash>::read void Foam::HashPtrTable<T, Key, Hash>::read
( (
const dictionary& dict, const dictionary& dict,
const INew& inewt const INew& inew
) )
{ {
forAllConstIter(dictionary, dict, iter) forAllConstIter(dictionary, dict, iter)
{ {
const word& k = iter().keyword(); const word& k = iter().keyword();
this->insert(k, inewt(dict.subDict(k)).ptr()); this->insert(k, inew(dict.subDict(k)).ptr());
} }
} }
@ -170,9 +170,9 @@ void Foam::HashPtrTable<T, Key, Hash>::write(Ostream& os) const
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
template<class INew> template<class INew>
Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(Istream& is, const INew& inewt) Foam::HashPtrTable<T, Key, Hash>::HashPtrTable(Istream& is, const INew& inew)
{ {
this->read(is, inewt); this->read(is, inew);
} }
@ -209,12 +209,12 @@ Foam::Ostream& Foam::operator<<
const HashPtrTable<T, Key, Hash>& tbl const HashPtrTable<T, Key, Hash>& tbl
) )
{ {
const label sz = tbl.size(); const label len = tbl.size();
if (sz) if (len)
{ {
// Size and start list delimiter // Size and start list delimiter
os << nl << sz << nl << token::BEGIN_LIST << nl; os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents // Contents
for (auto iter = tbl.cbegin(); iter != tbl.cend(); ++iter) for (auto iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
@ -233,7 +233,7 @@ Foam::Ostream& Foam::operator<<
else else
{ {
// Empty hash table // Empty hash table
os << sz << token::BEGIN_LIST << token::END_LIST; os << len << token::BEGIN_LIST << token::END_LIST;
} }
os.check(FUNCTION_NAME); os.check(FUNCTION_NAME);

View File

@ -160,21 +160,21 @@ Foam::Istream& Foam::operator>>
if (firstToken.isLabel()) if (firstToken.isLabel())
{ {
const label s = firstToken.labelToken(); const label len = firstToken.labelToken();
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("HashTable"); const char delimiter = is.readBeginList("HashTable");
if (s) if (len)
{ {
if (2*s > L.capacity_) if (2*len > L.capacity_)
{ {
L.resize(2*s); L.resize(2*len);
} }
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<s; ++i) for (label i=0; i<len; ++i)
{ {
Key key; Key key;
is >> key; is >> key;
@ -258,12 +258,12 @@ Foam::Ostream& Foam::operator<<
const HashTable<T, Key, Hash>& tbl const HashTable<T, Key, Hash>& tbl
) )
{ {
const label sz = tbl.size(); const label len = tbl.size();
if (sz) if (len)
{ {
// Size and start list delimiter // Size and start list delimiter
os << nl << sz << nl << token::BEGIN_LIST << nl; os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents // Contents
for (auto iter = tbl.cbegin(); iter != tbl.cend(); ++iter) for (auto iter = tbl.cbegin(); iter != tbl.cend(); ++iter)
@ -276,7 +276,7 @@ Foam::Ostream& Foam::operator<<
else else
{ {
// Empty hash table // Empty hash table
os << sz << token::BEGIN_LIST << token::END_LIST; os << len << token::BEGIN_LIST << token::END_LIST;
} }
os.check(FUNCTION_NAME); os.check(FUNCTION_NAME);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,18 +32,22 @@ Foam::ILList<LListBase, T>::ILList(const ILList<LListBase, T>& lst)
: :
UILList<LListBase, T>() UILList<LListBase, T>()
{ {
for for (const auto& item : lst)
(
typename UILList<LListBase, T>::const_iterator iter = lst.begin();
iter != lst.end();
++iter
)
{ {
this->append(iter().clone().ptr()); this->append(item.clone().ptr());
} }
} }
template<class LListBase, class T>
Foam::ILList<LListBase, T>::ILList(ILList<LListBase, T>&& lst)
:
UILList<LListBase, T>()
{
LListBase::transfer(lst);
}
template<class LListBase, class T> template<class LListBase, class T>
template<class CloneArg> template<class CloneArg>
Foam::ILList<LListBase, T>::ILList Foam::ILList<LListBase, T>::ILList
@ -54,14 +58,9 @@ Foam::ILList<LListBase, T>::ILList
: :
UILList<LListBase, T>() UILList<LListBase, T>()
{ {
for for (const auto& item :lst)
(
typename UILList<LListBase, T>::const_iterator iter = lst.begin();
iter != lst.end();
++iter
)
{ {
this->append(iter().clone(cloneArg).ptr()); this->append(item.clone(cloneArg).ptr());
} }
} }
@ -80,39 +79,38 @@ Foam::ILList<LListBase, T>::~ILList()
template<class LListBase, class T> template<class LListBase, class T>
bool Foam::ILList<LListBase, T>::eraseHead() bool Foam::ILList<LListBase, T>::eraseHead()
{ {
T* tPtr; T* p = this->removeHead();
if ((tPtr = this->removeHead()))
if (p)
{ {
delete tPtr; delete p;
return true; return true;
} }
else
{ return false;
return false;
}
} }
template<class LListBase, class T> template<class LListBase, class T>
bool Foam::ILList<LListBase, T>::erase(T* p) bool Foam::ILList<LListBase, T>::erase(T* item)
{ {
T* tPtr; T* p = remove(item);
if ((tPtr = remove(p)))
if (p)
{ {
delete tPtr; delete p;
return true; return true;
} }
else
{ return false;
return false;
}
} }
template<class LListBase, class T> template<class LListBase, class T>
void Foam::ILList<LListBase, T>::clear() void Foam::ILList<LListBase, T>::clear()
{ {
label oldSize = this->size(); const label len = this->size();
for (label i=0; i<oldSize; ++i)
for (label i=0; i<len; ++i)
{ {
eraseHead(); eraseHead();
} }
@ -136,20 +134,19 @@ void Foam::ILList<LListBase, T>::operator=(const ILList<LListBase, T>& lst)
{ {
this->clear(); this->clear();
for for (const auto& item : lst)
(
typename UILList<LListBase, T>::const_iterator iter = lst.begin();
iter != lst.end();
++iter
)
{ {
this->append(iter().clone().ptr()); this->append(item.clone().ptr());
} }
} }
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
#include "ILListIO.C" template<class LListBase, class T>
void Foam::ILList<LListBase, T>::operator=(ILList<LListBase, T>&& lst)
{
clear();
LListBase::transfer(lst);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -43,17 +43,16 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations
class Istream; class Istream;
class Ostream; class Ostream;
// Forward declaration of friend functions and operators
template<class LListBase, class T> class ILList; template<class LListBase, class T> class ILList;
template<class LListBase, class T> Istream& operator>> template<class LListBase, class T> Istream& operator>>
( (
Istream&, Istream& is,
ILList<LListBase, T>& ILList<LListBase, T>& lst
); );
@ -70,7 +69,7 @@ class ILList
//- Read from Istream using given Istream constructor class //- Read from Istream using given Istream constructor class
template<class INew> template<class INew>
void read(Istream&, const INew&); void read(Istream& is, const INew& inew);
public: public:
@ -78,28 +77,30 @@ public:
// Constructors // Constructors
//- Null construct //- Null construct
ILList() ILList() = default;
{}
//- Construct given initial T //- Construct and insert the initial T item pointer
ILList(T* a) explicit ILList(T* item)
: :
UILList<LListBase, T>(a) UILList<LListBase, T>(item)
{} {}
//- Construct from Istream //- Construct from Istream
ILList(Istream&); ILList(Istream& is);
//- Construct as copy //- Copy construct using the 'clone()' method for each element
ILList(const ILList<LListBase, T>&); ILList(const ILList<LListBase, T>& lst);
//- Copy constructor with additional argument for clone //- Move construct
ILList(ILList<LListBase, T>&& lst);
//- Copy constructor with additional argument for clone 'clone()'
template<class CloneArg> template<class CloneArg>
ILList(const ILList<LListBase, T>& lst, const CloneArg& cloneArg); ILList(const ILList<LListBase, T>& lst, const CloneArg& cloneArg);
//- Construct from Istream using given Istream constructor class //- Construct from Istream using given Istream constructor class
template<class INew> template<class INew>
ILList(Istream&, const INew&); ILList(Istream& is, const INew& inew);
//- Destructor //- Destructor
@ -108,35 +109,36 @@ public:
// Member Functions // Member Functions
// Edit //- Remove the head element specified from the list and delete it
bool eraseHead();
//- Remove the head element specified from the list and delete it //- Remove the specified element from the list and delete it
bool eraseHead(); bool erase(T* item);
//- Remove the specified element from the list and delete it //- Clear the contents of the list
bool erase(T* p); void clear();
//- Clear the contents of the list //- Transfer the contents of the argument into this List
void clear(); //- and annul the argument list.
void transfer(ILList<LListBase, T>& lst);
//- Transfer the contents of the argument into this List
// and annul the argument list.
void transfer(ILList<LListBase, T>&);
// Member operators // Member operators
//- Assignment operator //- Copy assignment using the 'clone()' method for each element
void operator=(const ILList<LListBase, T>&); void operator=(const ILList<LListBase, T>& lst);
//- Move assignment
void operator=(ILList<LListBase, T>&& lst);
// Istream operator // Istream operator
//- Read List from Istream, discarding contents of existing List. //- Read from Istream, discarding existing contents.
friend Istream& operator>> <LListBase, T> friend Istream& operator>> <LListBase, T>
( (
Istream&, Istream& is,
ILList<LListBase, T>& ILList<LListBase, T>& lst
); );
}; };
@ -149,6 +151,7 @@ public:
#ifdef NoRepository #ifdef NoRepository
#include "ILList.C" #include "ILList.C"
#include "ILListIO.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,59 +31,49 @@ License
template<class LListBase, class T> template<class LListBase, class T>
template<class INew> template<class INew>
void Foam::ILList<LListBase, T>::read(Istream& is, const INew& iNew) void Foam::ILList<LListBase, T>::read(Istream& is, const INew& inew)
{ {
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
token firstToken(is); token firstToken(is);
is.fatalCheck is.fatalCheck("ILList::readList : reading first token");
(
"operator>>(Istream&, ILList<LListBase, T>&) : reading first token"
);
if (firstToken.isLabel()) if (firstToken.isLabel())
{ {
const label s = firstToken.labelToken(); const label len = firstToken.labelToken();
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("ILList<LListBase, T>"); const char delimiter = is.readBeginList("ILList");
if (s) if (len)
{ {
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<s; ++i) for (label i=0; i<len; ++i)
{ {
this->append(iNew(is).ptr()); T* p = inew(is).ptr();
this->append(p);
is.fatalCheck is.fatalCheck("ILList::readList : reading entry");
(
"operator>>(Istream&, ILList<LListBase, T>&) : "
"reading entry"
);
} }
} }
else else
{ {
T* tPtr = iNew(is).ptr(); T* p = inew(is).ptr();
this->append(tPtr); this->append(p);
is.fatalCheck is.fatalCheck("ILList::readList : reading entry");
(
"operator>>(Istream&, ILList<LListBase, T>&) : "
"reading entry"
);
for (label i=1; i<s; ++i) for (label i=1; i<len; ++i)
{ {
this->append(new T(*tPtr)); this->append(new T(*p)); // Copy construct
} }
} }
} }
// Read end of contents // Read end of contents
is.readEndList("ILList<LListBase, T>"); is.readEndList("ILList");
} }
else if (firstToken.isPunctuation()) else if (firstToken.isPunctuation())
{ {
@ -108,7 +98,9 @@ void Foam::ILList<LListBase, T>::read(Istream& is, const INew& iNew)
) )
{ {
is.putBack(lastToken); is.putBack(lastToken);
this->append(iNew(is).ptr());
T* p = inew(is).ptr();
this->append(p);
is >> lastToken; is >> lastToken;
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
@ -128,9 +120,9 @@ void Foam::ILList<LListBase, T>::read(Istream& is, const INew& iNew)
template<class LListBase, class T> template<class LListBase, class T>
template<class INew> template<class INew>
Foam::ILList<LListBase, T>::ILList(Istream& is, const INew& iNew) Foam::ILList<LListBase, T>::ILList(Istream& is, const INew& inew)
{ {
this->read(is, iNew); this->read(is, inew);
} }
@ -144,10 +136,10 @@ Foam::ILList<LListBase, T>::ILList(Istream& is)
// * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * //
template<class LListBase, class T> template<class LListBase, class T>
Foam::Istream& Foam::operator>>(Istream& is, ILList<LListBase, T>& L) Foam::Istream& Foam::operator>>(Istream& is, ILList<LListBase, T>& lst)
{ {
L.clear(); lst.clear();
L.read(is, INew<T>()); lst.read(is, INew<T>());
return is; return is;
} }

View File

@ -39,6 +39,15 @@ Foam::LList<LListBase, T>::LList(const LList<LListBase, T>& lst)
} }
template<class LListBase, class T>
Foam::LList<LListBase, T>::LList(LList<LListBase, T>&& lst)
:
LListBase()
{
LListBase::transfer(lst);
}
template<class LListBase, class T> template<class LListBase, class T>
Foam::LList<LListBase, T>::LList(std::initializer_list<T> lst) Foam::LList<LListBase, T>::LList(std::initializer_list<T> lst)
: :
@ -51,6 +60,8 @@ Foam::LList<LListBase, T>::LList(std::initializer_list<T> lst)
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class LListBase, class T> template<class LListBase, class T>
Foam::LList<LListBase, T>::~LList() Foam::LList<LListBase, T>::~LList()
{ {
@ -63,8 +74,8 @@ Foam::LList<LListBase, T>::~LList()
template<class LListBase, class T> template<class LListBase, class T>
void Foam::LList<LListBase, T>::clear() void Foam::LList<LListBase, T>::clear()
{ {
label oldSize = this->size(); const label len = this->size();
for (label i=0; i<oldSize; ++i) for (label i=0; i<len; ++i)
{ {
this->removeHead(); this->removeHead();
} }
@ -95,6 +106,15 @@ void Foam::LList<LListBase, T>::operator=(const LList<LListBase, T>& lst)
} }
template<class LListBase, class T>
void Foam::LList<LListBase, T>::operator=(LList<LListBase, T>&& lst)
{
this->clear();
LListBase::transfer(lst);
}
template<class LListBase, class T> template<class LListBase, class T>
void Foam::LList<LListBase, T>::operator=(std::initializer_list<T> lst) void Foam::LList<LListBase, T>::operator=(std::initializer_list<T> lst)
{ {
@ -107,8 +127,4 @@ void Foam::LList<LListBase, T>::operator=(std::initializer_list<T> lst)
} }
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
#include "LListIO.C"
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -44,25 +44,25 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations
class Istream; class Istream;
class Ostream; class Ostream;
// Forward declaration of friend functions and operators
template<class LListBase, class T> class LList; template<class LListBase, class T> class LList;
template<class LListBase, class T> template<class LListBase, class T>
Istream& operator>> Istream& operator>>
( (
Istream&, Istream& is,
LList<LListBase, T>& LList<LListBase, T>& lst
); );
template<class LListBase, class T> template<class LListBase, class T>
Ostream& operator<< Ostream& operator<<
( (
Ostream&, Ostream& os,
const LList<LListBase, T>& const LList<LListBase, T>& lst
); );
@ -75,19 +75,42 @@ class LList
: :
public LListBase public LListBase
{ {
public: public:
// STL type definitions
//- Type of values stored.
typedef T value_type;
//- Pointer for value_type
typedef T* pointer;
//- Const pointer for value_type
typedef const T* const_pointer;
//- Reference for value_type
typedef T& reference;
//- Const reference for value_type
typedef const T& const_reference;
//- The type that can represent the container size
typedef label size_type;
//- The difference between iterator objects
typedef label difference_type;
// Forward declaration of STL iterators // Forward declaration of STL iterators
class iterator; class iterator;
friend class iterator;
class const_iterator; class const_iterator;
friend class const_iterator;
using base_iterator = typename LListBase::iterator;
using const_base_iterator = typename LListBase::const_iterator;
//- Link structure //- The storage of T with linked nodes
struct link struct link
: :
public LListBase::link public LListBase::link
@ -95,34 +118,73 @@ public:
//- Stored object //- Stored object
T obj_; T obj_;
//- Construct given object //- Copy construct from given object
link(T a) link(const T& obj)
: :
obj_(a) obj_(obj)
{} {}
//- Move construct from given object
link(T&& obj)
:
obj_(std::move(obj))
{}
//- Dereference LListBase::link to obtain address of stored object
static constexpr T* ptr(typename LListBase::link* node)
{
return &(static_cast<link*>(node)->obj_);
}
//- Dereference LListBase::link to obtain address of stored object
static constexpr const T* ptr(const typename LListBase::link* node)
{
return &(static_cast<const link*>(node)->obj_);
}
//- Dereference LListBase::link to obtain the stored object
static constexpr T& ref(typename LListBase::link* node)
{
return static_cast<link*>(node)->obj_;
}
//- Dereference LListBase::link to obtain the stored object
static constexpr const T& ref(const typename LListBase::link* node)
{
return static_cast<const link*>(node)->obj_;
}
}; };
// Constructors // Constructors
//- Null construct //- Null construct
LList() LList() = default;
{}
//- Construct given initial T //- Construct and copy insert the initial T item
explicit LList(T a) explicit LList(const T& item)
: {
LListBase(new link(a)) this->insert(item);
{} }
//- Construct and move insert the initial T item
explicit LList(T&& item)
{
this->insert(std::move(item));
}
//- Construct from Istream //- Construct from Istream
explicit LList(Istream&); explicit LList(Istream& is);
//- Construct as copy //- Copy construct
LList(const LList<LListBase, T>&); LList(const LList<LListBase, T>& lst);
//- Construct from an initializer list //- Move construct
LList(std::initializer_list<T>); LList(LList<LListBase, T>&& lst);
//- Copy construct from an initializer list
LList(std::initializer_list<T> lst);
//- Destructor //- Destructor
@ -131,240 +193,375 @@ public:
// Member Functions // Member Functions
// Access //- The first entry in the list
reference first()
{
return link::ref(LListBase::first());
}
//- Return the first entry added //- The first entry in the list (const access)
T& first() const_reference first() const
{ {
return static_cast<link*>(LListBase::first())->obj_; return link::ref(LListBase::first());
} }
//- Return const access to the first entry added //- The last entry in the list
const T& first() const reference last()
{ {
return static_cast<const link*>(LListBase::first())->obj_; return link::ref(LListBase::last());
} }
//- Return the last entry added //- The last entry in the list (const access)
T& last() const_reference last() const
{ {
return static_cast<link*>(LListBase::last())->obj_; return link::ref(LListBase::last());
} }
//- Return const access to the last entry added
const T& last() const
{
return static_cast<const link*>(LListBase::last())->obj_;
}
// Edit //- Add copy at head of list
void insert(const T& item)
{
LListBase::insert(new link(item));
}
//- Add at head of list //- Move construct at head of list
void insert(const T& a) void insert(T&& item)
{ {
LListBase::insert(new link(a)); LListBase::insert(new link(std::move(item)));
} }
//- Add at tail of list
void append(const T& a)
{
LListBase::append(new link(a));
}
//- Remove and return head //- Add copy at tail of list
T removeHead() void append(const T& item)
{ {
link* elmtPtr = static_cast<link*>(LListBase::removeHead()); LListBase::append(new link(item));
T data = elmtPtr->obj_; }
delete elmtPtr;
return data;
}
//- Remove and return element //- Move construct at tail of list
T remove(link* l) void append(T&& item)
{ {
link* elmtPtr = static_cast<link*>(LListBase::remove(l)); LListBase::append(new link(std::move(item)));
T data = elmtPtr->obj_; }
delete elmtPtr;
return data;
}
//- Remove and return element specified by iterator
T remove(iterator& it)
{
link* elmtPtr = static_cast<link*>(LListBase::remove(it));
T data = elmtPtr->obj_;
delete elmtPtr;
return data;
}
//- Delete contents of list //- Remove and return head
void clear(); T removeHead()
{
auto p = LListBase::removeHead();
T obj(std::move(link::ref(p)));
delete p;
return obj;
}
//- Transfer the contents of the argument into this List //- Remove and return element
// and annul the argument list. T remove(link* item)
void transfer(LList<LListBase, T>&); {
auto p = LListBase::remove(item);
T obj(std::move(link::ref(p)));
delete p;
return obj;
}
//- Remove and return element specified by iterator
T remove(iterator& iter)
{
auto p = LListBase::remove(iter);
T obj(std::move(link::ref(p)));
delete p;
return obj;
}
//- Delete contents of list
void clear();
//- Transfer the contents of the argument into this List
// and annul the argument list.
void transfer(LList<LListBase, T>& lst);
// Member operators // Member operators
//- Assignment operator //- Copy assignment
void operator=(const LList<LListBase, T>&); void operator=(const LList<LListBase, T>& lst);
//- Assignment to an initializer list //- Move assignment
void operator=(std::initializer_list<T>); void operator=(LList<LListBase, T>&& lst);
//- Copy assignment from an initializer list
// STL type definitions void operator=(std::initializer_list<T> lst);
//- Type of values the LList contains.
typedef T value_type;
//- Type that can be used for storing into value_type
// objects.
typedef T& reference;
//- Type that can be used for storing into constant
// LList::value_type objects.
typedef const T& const_reference;
//- The type that can represent the size of a LList.
typedef label size_type;
// STL iterator
typedef typename LListBase::iterator LListBase_iterator;
//- An STL-conforming iterator
class iterator
:
public LListBase_iterator
{
public:
//- Construct from base iterator
iterator(LListBase_iterator baseIter)
:
LListBase_iterator(baseIter)
{}
// Member operators
T& operator*() const
{
return
static_cast<link&>
(LListBase_iterator::operator*()).obj_;
}
T& operator()() const
{
return operator*();
}
iterator& operator++()
{
LListBase_iterator::operator++();
return *this;
}
};
inline iterator begin()
{
return LListBase::begin();
}
inline const iterator& end()
{
return static_cast<const iterator&>(LListBase::end());
}
// STL const_iterator
typedef typename LListBase::const_iterator LListBase_const_iterator;
//- An STL-conforming const_iterator
class const_iterator
:
public LListBase_const_iterator
{
public:
//- Construct from base const_iterator
const_iterator(LListBase_const_iterator baseIter)
:
LListBase_const_iterator(baseIter)
{}
//- Construct from base iterator
const_iterator(LListBase_iterator baseIter)
:
LListBase_const_iterator(baseIter)
{}
// Member operators
const T& operator*() const
{
return
static_cast<const link&>
(LListBase_const_iterator::operator*()).obj_;
}
const T& operator()() const
{
return operator*();
}
const_iterator& operator++()
{
LListBase_const_iterator::operator++();
return *this;
}
};
inline const_iterator cbegin() const
{
return LListBase::cbegin();
}
inline const const_iterator& cend() const
{
return static_cast<const const_iterator&>(LListBase::cend());
}
inline const_iterator begin() const
{
return LListBase::begin();
}
inline const const_iterator& end() const
{
return static_cast<const const_iterator&>(LListBase::end());
}
// IOstream operators // IOstream operators
//- Write LList with line-breaks when its length exceeds
//- shortListLen.
// Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortListLen=0) const;
//- Read list from Istream
friend Istream& operator>> <LListBase, T> friend Istream& operator>> <LListBase, T>
( (
Istream&, Istream&,
LList<LListBase, T>& LList<LListBase, T>& lst
); );
//- Write LList to Ostream with line breaks,
//- as per writeList() with shortListLen=-1
friend Ostream& operator<< <LListBase, T> friend Ostream& operator<< <LListBase, T>
( (
Ostream&, Ostream& os,
const LList<LListBase, T>& const LList<LListBase, T>& lst
); );
// STL iterator
//- An STL-conforming iterator
class iterator
:
public base_iterator
{
public:
//- Construct from base iterator
iterator(base_iterator iter)
:
base_iterator(iter)
{}
reference operator*() const
{
return link::ref(this->get_node());
}
pointer operator->() const
{
return link::ptr(this->get_node());
}
reference operator()() const
{
return operator*();
}
iterator& operator++()
{
this->next();
return *this;
}
iterator& operator--()
{
this->prev(); // May not be implemented
return *this;
}
};
// STL const_iterator
//- An STL-conforming const_iterator
class const_iterator
:
public const_base_iterator
{
public:
//- Construct from base iterator
const_iterator(const_base_iterator iter)
:
const_base_iterator(iter)
{}
//- Construct from base iterator
const_iterator(base_iterator iter)
:
const_base_iterator(iter)
{}
const_reference operator*() const
{
return link::ref(this->get_node());
}
const_pointer operator->() const
{
return link::ptr(this->get_node());
}
const_reference operator()() const
{
return operator*();
}
const_iterator& operator++()
{
this->next();
return *this;
}
const_iterator& operator--()
{
this->prev(); // May not be implemented
return *this;
}
};
// STL reverse_iterator
//- A reverse_iterator, for LListBase classes that support
//- reverse iteration
class reverse_iterator
:
public base_iterator
{
public:
//- Construct from base iterator
reverse_iterator(base_iterator iter)
:
base_iterator(iter)
{}
reference operator*() const
{
return link::ref(this->get_node());
}
pointer operator->() const
{
return link::ptr(this->get_node());
}
reverse_iterator& operator++()
{
this->prev(); // Only if base iterator is bidirectional
return *this;
}
reverse_iterator& operator--()
{
this->next();
return *this;
}
};
// STL const_reverse_iterator
//- A const_reverse_iterator, for LListBase classes that support
//- reverse iteration
class const_reverse_iterator
:
public const_base_iterator
{
public:
//- Construct from base iterator
const_reverse_iterator(const_base_iterator iter)
:
const_base_iterator(iter)
{}
const_reference operator*() const
{
return link::ref(this->get_node());
}
const_pointer operator->() const
{
return link::ptr(this->get_node());
}
const_reverse_iterator& operator++()
{
this->prev(); // Only if base iterator is bidirectional
return *this;
}
const_reverse_iterator& operator--()
{
this->next();
return *this;
}
};
//- Iterator to first item in list with non-const access
inline iterator begin()
{
return LListBase::template iterator_first<base_iterator>();
}
//- Iterator to first item in list with const access
inline const_iterator cbegin() const
{
return LListBase::template iterator_first<const_base_iterator>();
}
//- Iterator to last item in list with non-const access
inline reverse_iterator rbegin()
{
return LListBase::template iterator_last<base_iterator>();
}
//- Iterator to last item in list with const access
inline const_reverse_iterator crbegin() const
{
return LListBase::template iterator_last<const_base_iterator>();
}
//- Iterator to first item in list with const access
inline const_iterator begin() const
{
return LListBase::cbegin();
}
//- Iterator to last item in list with const access
inline const_reverse_iterator rbegin() const
{
return crbegin();
}
//- End of list for forward iterators
inline const iterator& end()
{
return LListBase::template iterator_end<iterator>();
}
//- End of list for forward iterators
inline const const_iterator& cend() const
{
return LListBase::template iterator_end<const_iterator>();
}
//- End of list for reverse iterators
inline const reverse_iterator& rend()
{
return LListBase::template iterator_rend<reverse_iterator>();
}
//- End of list for reverse iterators
inline const const_reverse_iterator& crend() const
{
return LListBase::template iterator_rend<const_reverse_iterator>();
}
//- End of list for forward iterators
inline const const_iterator& end() const
{
return cend();
}
//- End of list for reverse iterators
inline const const_reverse_iterator& rend() const
{
return crend();
}
}; };
@ -376,6 +573,7 @@ public:
#ifdef NoRepository #ifdef NoRepository
#include "LList.C" #include "LList.C"
#include "LListIO.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,39 +36,36 @@ Foam::LList<LListBase, T>::LList(Istream& is)
} }
// * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class LListBase, class T> template<class LListBase, class T>
Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& L) Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& lst)
{ {
// Anull list // Anull list
L.clear(); lst.clear();
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
token firstToken(is); token firstToken(is);
is.fatalCheck is.fatalCheck("LList::readList : reading first token");
(
" operator>>(Istream&, LList<LListBase, T>&) : reading first token"
);
if (firstToken.isLabel()) if (firstToken.isLabel())
{ {
const label s = firstToken.labelToken(); const label len = firstToken.labelToken();
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("LList<LListBase, T>"); const char delimiter = is.readBeginList("LList");
if (s) if (len)
{ {
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<s; ++i) for (label i=0; i<len; ++i)
{ {
T element; T element;
is >> element; is >> element;
L.append(element); lst.append(element);
} }
} }
else else
@ -76,9 +73,9 @@ Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& L)
T element; T element;
is >> element; is >> element;
for (label i=0; i<s; ++i) for (label i=0; i<len; ++i)
{ {
L.append(element); lst.append(element);
} }
} }
} }
@ -109,9 +106,10 @@ Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& L)
) )
{ {
is.putBack(lastToken); is.putBack(lastToken);
T element; T element;
is >> element; is >> element;
L.append(element); lst.append(element);
is >> lastToken; is >> lastToken;
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
@ -125,36 +123,66 @@ Foam::Istream& Foam::operator>>(Istream& is, LList<LListBase, T>& L)
<< exit(FatalIOError); << exit(FatalIOError);
} }
// Check state of IOstream
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
return is; return is;
} }
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class LListBase, class T> template<class LListBase, class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const LList<LListBase, T>& lst) Foam::Ostream& Foam::LList<LListBase, T>::writeList
(
Ostream& os,
const label shortListLen
) const
{ {
// Write size const label len = this->size();
os << nl << lst.size();
// Write beginning of contents if
os << nl << token::BEGIN_LIST << nl; (
len <= 1 || !shortListLen
// Write contents || (len <= shortListLen)
for (const T& val : lst) )
{ {
os << val << nl; // Size and start delimiter
} os << len << token::BEGIN_LIST;
// Write end of contents // Contents
os << token::END_LIST; bool space = false;
for (const T& val : *this)
{
if (space) os << token::SPACE;
os << val;
space = true;
}
// End delimiter
os << token::END_LIST;
}
else
{
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents
for (const T& val : *this)
{
os << val << nl;
}
// End delimiter
os << token::END_LIST;
}
os.check(FUNCTION_NAME); os.check(FUNCTION_NAME);
return os; return os;
} }
template<class LListBase, class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const LList<LListBase, T>& lst)
{
return lst.writeList(os, -1); // always with line breaks
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -32,13 +32,22 @@ Foam::LPtrList<LListBase, T>::LPtrList(const LPtrList<LListBase, T>& lst)
: :
LList<LListBase, T*>() LList<LListBase, T*>()
{ {
for (const_iterator iter = lst.begin(); iter != lst.end(); ++iter) for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
{ {
this->append(iter().clone().ptr()); this->append((*iter).clone().ptr());
} }
} }
template<class LListBase, class T>
Foam::LPtrList<LListBase, T>::LPtrList(LPtrList<LListBase, T>&& lst)
:
LList<LListBase, T*>()
{
LList<LListBase, T*>::transfer(lst);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class LListBase, class T> template<class LListBase, class T>
@ -53,24 +62,23 @@ Foam::LPtrList<LListBase, T>::~LPtrList()
template<class LListBase, class T> template<class LListBase, class T>
bool Foam::LPtrList<LListBase, T>::eraseHead() bool Foam::LPtrList<LListBase, T>::eraseHead()
{ {
T* tPtr; T* p = this->removeHead();
if ((tPtr = this->removeHead()))
if (p)
{ {
delete tPtr; delete p;
return true; return true;
} }
else
{ return false;
return false;
}
} }
template<class LListBase, class T> template<class LListBase, class T>
void Foam::LPtrList<LListBase, T>::clear() void Foam::LPtrList<LListBase, T>::clear()
{ {
const label oldSize = this->size(); const label len = this->size();
for (label i=0; i<oldSize; ++i) for (label i=0; i<len; ++i)
{ {
eraseHead(); eraseHead();
} }
@ -94,16 +102,18 @@ void Foam::LPtrList<LListBase, T>::operator=(const LPtrList<LListBase, T>& lst)
{ {
clear(); clear();
for (const_iterator iter = lst.begin(); iter != lst.end(); ++iter) for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
{ {
this->append(iter().clone().ptr()); this->append((*iter).clone().ptr());
} }
} }
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // template<class LListBase, class T>
void Foam::LPtrList<LListBase, T>::operator=(LPtrList<LListBase, T>&& lst)
#include "LPtrListIO.C" {
transfer(lst);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -43,22 +43,22 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators // Forward declarations
template<class LListBase, class T> class LPtrList; template<class LListBase, class T> class LPtrList;
template<class LListBase, class T> template<class LListBase, class T>
Istream& operator>> Istream& operator>>
( (
Istream&, Istream& is,
LPtrList<LListBase, T>& LPtrList<LListBase, T>& lst
); );
template<class LListBase, class T> template<class LListBase, class T>
Ostream& operator<< Ostream& operator<<
( (
Ostream&, Ostream& os,
const LPtrList<LListBase, T>& const LPtrList<LListBase, T>& lst
); );
@ -71,45 +71,67 @@ class LPtrList
: :
public LList<LListBase, T*> public LList<LListBase, T*>
{ {
private:
// Private Member Functions // Private Member Functions
//- Read from Istream using given Istream constructor class //- Read from Istream using given Istream constructor class
template<class INew> template<class INew>
void read(Istream&, const INew&); void read(Istream& is, const INew& inew);
public: public:
// STL type definitions
//- Pointer for LPtrList::value_type objects.
typedef T* pointer;
//- Const pointer for LPtrList::value_type objects.
typedef const T* const_pointer;
//- Reference for LPtrList::value_type objects.
typedef T& reference;
//- Const reference for LPtrList::value_type objects.
typedef const T& const_reference;
// Forward declaration of STL iterators // Forward declaration of STL iterators
class iterator; class iterator;
friend class iterator;
class const_iterator; class const_iterator;
friend class const_iterator;
using base_iterator = typename LListBase::iterator;
using const_base_iterator = typename LListBase::const_iterator;
//- The parent list storage
typedef LList<LListBase, T*> parent_type;
// Constructors // Constructors
//- Null construct //- Null construct
LPtrList() LPtrList() = default;
{}
//- Construct given initial T //- Construct and insert the initial T item
LPtrList(T* a) explicit LPtrList(T* item)
: {
LList<LListBase, T*>(a) this->insert(item);
{} }
//- Copy construct by using 'clone()' for each element
LPtrList(const LPtrList& lst);
//- Move construct
LPtrList(LPtrList&& lst);
//- Construct from Istream using given Istream constructor class //- Construct from Istream using given Istream constructor class
template<class INew> template<class INew>
LPtrList(Istream&, const INew&); LPtrList(Istream& is, const INew& inew);
//- Construct from Istream using default Istream constructor class //- Construct from Istream using default Istream constructor class
LPtrList(Istream&); LPtrList(Istream& is);
//- Construct as copy
LPtrList(const LPtrList&);
//- Destructor //- Destructor
@ -118,147 +140,292 @@ public:
// Member Functions // Member Functions
// Access //- The first entry in the list
T& first()
{
return *(parent_type::first());
}
//- Return the first entry added //- The first entry in the list (const access)
T& first() const T& first() const
{ {
return *LList<LListBase, T*>::first(); return *(parent_type::first());
} }
//- Return const access to the first entry added //- The last entry in the list
const T& first() const T& last()
{ {
return *LList<LListBase, T*>::first(); return *(parent_type::last());
} }
//- Return the last entry added //- The last entry in the list (const access)
T& last() const T& last() const
{ {
return *LList<LListBase, T*>::last(); return *(parent_type::last());
} }
//- Return const access to the last entry added
const T& last() const
{
return *LList<LListBase, T*>::last();
}
// Edit //- Remove the head element from the list and delete the pointer
bool eraseHead();
//- Remove the head element from the list and delete the pointer //- Clear the contents of the list
bool eraseHead(); void clear();
//- Clear the contents of the list //- Transfer the contents of the argument into this List
void clear(); //- and annul the argument list.
void transfer(LPtrList<LListBase, T>& lst);
//- Transfer the contents of the argument into this List
// and annul the argument list.
void transfer(LPtrList<LListBase, T>&);
// Member operators // Member operators
//- Assign copy //- Copy assign by using 'clone()' for each element
void operator=(const LPtrList<LListBase, T>&); void operator=(const LPtrList<LListBase, T>& lst);
//- Move assign
// STL type definitions void operator=(LPtrList<LListBase, T>&& lst);
//- Type that can be used for storing into LPtrList::value_type
// objects.
typedef T& reference;
//- Type that can be used for storing into constant
// LPtrList::value_type objects.
typedef T& const_reference;
// STL iterator // STL iterator
typedef typename LListBase::iterator LListBase_iterator;
//- An STL-conforming iterator //- An STL-conforming iterator
class iterator class iterator
: :
public LList<LListBase, T*>::iterator public parent_type::iterator
{ {
public: public:
//- Construct from base iterator iterator(base_iterator iter)
iterator(LListBase_iterator baseIter)
: :
LList<LListBase, T*>::iterator(baseIter) parent_type::iterator(iter)
{} {}
//- Return the address of the object being referenced
pointer get() const
{
return parent_type::iterator::operator*();
}
// Member operators reference operator*() const
{
return *(this->get());
}
T& operator*() const pointer operator->() const
{ {
return *(LList<LListBase, T*>::iterator::operator*()); return this->get();
} }
T& operator()() const reference operator()() const
{ {
return operator*(); return operator*();
} }
}; };
// STL const_iterator // STL const_iterator
typedef typename LListBase::const_iterator LListBase_const_iterator;
//- An STL-conforming const_iterator //- An STL-conforming const_iterator
class const_iterator class const_iterator
: :
public LList<LListBase, T*>::const_iterator public parent_type::const_iterator
{ {
public: public:
//- Construct from base const_iterator const_iterator(const_base_iterator iter)
const_iterator(LListBase_const_iterator baseIter)
: :
LList<LListBase, T*>::const_iterator(baseIter) parent_type::const_iterator(iter)
{} {}
//- Construct from base iterator const_iterator(base_iterator iter)
const_iterator(LListBase_iterator baseIter)
: :
LList<LListBase, T*>::const_iterator(baseIter) parent_type::const_iterator(iter)
{} {}
//- Return the address of the object being referenced
const_pointer get() const
{
return parent_type::const_iterator::operator*();
}
// Member operators const_reference operator*() const
{
return *(this->get());
}
const T& operator*() const const_pointer operator->() const
{ {
return *(LList<LListBase, T*>::const_iterator::operator*()); return this->get();
} }
const T& operator()() const const_reference operator()() const
{ {
return operator*(); return operator*();
} }
}; };
// STL reverse_iterator
//- A reverse_iterator, for base classes that support
//- reverse iteration
class reverse_iterator
:
public parent_type::reverse_iterator
{
public:
reverse_iterator(base_iterator iter)
:
parent_type::reverse_iterator(iter)
{}
//- Return the address of the object being referenced
pointer get() const
{
return parent_type::reverse_iterator::operator*();
}
reference operator*() const
{
return *(this->get());
}
pointer operator->() const
{
return this->get();
}
reference operator()() const
{
return operator*();
}
};
// STL const_reverse_iterator
//- A const_reverse_iterator, for base classes that support
//- reverse iteration
class const_reverse_iterator
:
public parent_type::const_reverse_iterator
{
public:
const_reverse_iterator(const_base_iterator iter)
:
parent_type::const_reverse_iterator(iter)
{}
//- Return the address of the object being referenced
const_pointer get() const
{
return parent_type::const_reverse_iterator::operator*();
}
const_reference operator*() const
{
return *(this->get());
}
const_pointer operator->() const
{
return this->get();
}
const_reference operator()() const
{
return operator*();
}
};
//- Iterator to first item in list with non-const access
inline iterator begin()
{
return LListBase::template iterator_first<base_iterator>();
}
//- Iterator to first item in list with const access
inline const_iterator cbegin() const
{
return LListBase::template iterator_first<const_base_iterator>();
}
//- Iterator to last item in list with non-const access
inline reverse_iterator rbegin()
{
return LListBase::template iterator_last<base_iterator>();
}
//- Iterator to last item in list with const access
inline const_reverse_iterator crbegin() const
{
return LListBase::template iterator_last<const_base_iterator>();
}
//- Iterator to first item in list with const access
inline const_iterator begin() const
{
return LListBase::cbegin();
}
//- Iterator to last item in list with const access
inline const_reverse_iterator rbegin() const
{
return crbegin();
}
//- End of list for forward iterators
inline const iterator& end()
{
return LListBase::template iterator_end<iterator>();
}
//- End of list for forward iterators
inline const const_iterator& cend() const
{
return LListBase::template iterator_end<const_iterator>();
}
//- End of list for reverse iterators
inline const reverse_iterator& rend()
{
return LListBase::template iterator_rend<reverse_iterator>();
}
//- End of list for reverse iterators
inline const const_reverse_iterator& crend() const
{
return LListBase::template iterator_rend<const_reverse_iterator>();
}
//- End of list for forward iterators
inline const const_iterator& end() const
{
return cend();
}
//- End of list for reverse iterators
inline const const_reverse_iterator& rend() const
{
return crend();
}
// IOstream operators // IOstream operators
friend Istream& operator>> <LListBase, T> friend Istream& operator>> <LListBase, T>
( (
Istream&, Istream& is,
LPtrList<LListBase, T>& LPtrList<LListBase, T>& lst
); );
friend Ostream& operator<< <LListBase, T> friend Ostream& operator<< <LListBase, T>
( (
Ostream&, Ostream& os,
const LPtrList<LListBase, T>& const LPtrList<LListBase, T>& lst
); );
}; };
@ -271,6 +438,7 @@ public:
#ifdef NoRepository #ifdef NoRepository
#include "LPtrList.C" #include "LPtrList.C"
#include "LPtrListIO.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,60 +32,49 @@ License
template<class LListBase, class T> template<class LListBase, class T>
template<class INew> template<class INew>
void Foam::LPtrList<LListBase, T>::read(Istream& is, const INew& iNew) void Foam::LPtrList<LListBase, T>::read(Istream& is, const INew& inew)
{ {
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
token firstToken(is); token firstToken(is);
is.fatalCheck is.fatalCheck("LPtrList::readList : reading first token");
(
"LPtrList<LListBase, T>::read(Istream&, const INew&) : "
"reading first token"
);
if (firstToken.isLabel()) if (firstToken.isLabel())
{ {
const label s = firstToken.labelToken(); const label len = firstToken.labelToken();
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("LPtrList<LListBase, T>"); const char delimiter = is.readBeginList("LPtrList");
if (s) if (len)
{ {
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<s; ++i) for (label i=0; i<len; ++i)
{ {
this->append(iNew(is).ptr()); T* p = inew(is).ptr();
this->append(p);
is.fatalCheck is.fatalCheck("LPtrList::readList : reading entry");
(
"LPtrList<LListBase, T>::read(Istream&, const INew&) : "
"reading entry"
);
} }
} }
else else
{ {
T* tPtr = iNew(is).ptr(); T* p = inew(is).ptr();
this->append(tPtr); this->append(p);
is.fatalCheck is.fatalCheck("LPtrList::readList : reading entry");
(
"LPtrList<LListBase, T>::read(Istream&, const INew&) : "
"reading entry"
);
for (label i=1; i<s; ++i) for (label i=1; i<len; ++i)
{ {
this->append(tPtr->clone().ptr()); this->append(p->clone().ptr());
} }
} }
} }
// Read end of contents // Read end of contents
is.readEndList("LPtrList<LListBase, T>"); is.readEndList("LPtrList");
} }
else if (firstToken.isPunctuation()) else if (firstToken.isPunctuation())
{ {
@ -110,7 +99,7 @@ void Foam::LPtrList<LListBase, T>::read(Istream& is, const INew& iNew)
) )
{ {
is.putBack(lastToken); is.putBack(lastToken);
this->append(iNew(is).ptr()); this->append(inew(is).ptr());
is >> lastToken; is >> lastToken;
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
@ -134,9 +123,9 @@ void Foam::LPtrList<LListBase, T>::read(Istream& is, const INew& iNew)
template<class LListBase, class T> template<class LListBase, class T>
template<class INew> template<class INew>
Foam::LPtrList<LListBase, T>::LPtrList(Istream& is, const INew& iNew) Foam::LPtrList<LListBase, T>::LPtrList(Istream& is, const INew& inew)
{ {
this->read(is, iNew); this->read(is, inew);
} }
@ -164,24 +153,16 @@ Foam::Istream& Foam::operator>>(Istream& is, LPtrList<LListBase, T>& L)
template<class LListBase, class T> template<class LListBase, class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const LPtrList<LListBase, T>& lst) Foam::Ostream& Foam::operator<<(Ostream& os, const LPtrList<LListBase, T>& lst)
{ {
// Write size // Size and start delimiter
os << nl << lst.size(); os << nl << lst.size() << nl << token::BEGIN_LIST << nl;
// Write beginning of contents // Contents
os << nl << token::BEGIN_LIST << nl; for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
// Write contents
for
(
typename LPtrList<LListBase, T>::const_iterator iter = lst.begin();
iter != lst.end();
++iter
)
{ {
os << iter() << nl; os << *iter << nl;
} }
// Write end of contents // End delimiter
os << token::END_LIST; os << token::END_LIST;
os.check(FUNCTION_NAME); os.check(FUNCTION_NAME);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -30,9 +30,9 @@ License
template<class LListBase, class T> template<class LListBase, class T>
Foam::UILList<LListBase, T>::UILList(const UILList<LListBase, T>& lst) Foam::UILList<LListBase, T>::UILList(const UILList<LListBase, T>& lst)
{ {
for (const_iterator iter = lst.begin(); iter != lst.end(); ++iter) for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
{ {
this->append(&iter()); this->append(&(*iter));
} }
} }
@ -40,13 +40,13 @@ Foam::UILList<LListBase, T>::UILList(const UILList<LListBase, T>& lst)
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class LListBase, class T> template<class LListBase, class T>
void Foam::UILList<LListBase, T>::operator=(const UILList<LListBase, T>& rhs) void Foam::UILList<LListBase, T>::operator=(const UILList<LListBase, T>& lst)
{ {
LListBase::clear(); LListBase::clear();
for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter) for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
{ {
this->append(&iter()); this->append(&(*iter));
} }
} }
@ -57,22 +57,22 @@ bool Foam::UILList<LListBase, T>::operator==
const UILList<LListBase, T>& rhs const UILList<LListBase, T>& rhs
) const ) const
{ {
bool equal = (this->size() == rhs.size()); if (this->size() != rhs.size())
if (!equal)
{ {
return false; return false;
} }
const_iterator iter1 = this->begin(); auto iter2 = rhs.cbegin();
const_iterator iter2 = rhs.begin();
for (; iter1 != this->end(); ++iter1, ++iter2) for (auto iter1 = this->cbegin(); iter1 != this->cend(); ++iter1, ++iter2)
{ {
equal = (iter1() == iter2()); if (!(*iter1 == *iter2))
if (!equal) break; {
return false;
}
} }
return equal; return true;
} }
@ -86,9 +86,4 @@ bool Foam::UILList<LListBase, T>::operator!=
} }
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
#include "UILListIO.C"
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -44,18 +44,17 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations
class Ostream; class Ostream;
// Forward declaration of friend functions and operators template<class LListBase, class T> class UILList;
template<class LListBase, class T>
class UILList;
template<class LListBase, class T> template<class LListBase, class T>
Ostream& operator<< Ostream& operator<<
( (
Ostream&, Ostream& os,
const UILList<LListBase, T>& const UILList<LListBase, T>& lst
); );
@ -68,308 +67,385 @@ class UILList
: :
public LListBase public LListBase
{ {
public: public:
// STL type definitions
//- Type of values stored
typedef T value_type;
//- Pointer for value_type
typedef T* pointer;
//- Const pointer for value_type
typedef const T* const_pointer;
//- Reference for value_type
typedef T& reference;
//- Const reference for value_type
typedef const T& const_reference;
//- The type that can represent the container size
typedef label size_type;
//- The difference between iterator objects
typedef label difference_type;
// Forward declaration of STL iterators // Forward declaration of STL iterators
class iterator; class iterator;
friend class iterator;
class const_iterator; class const_iterator;
friend class const_iterator;
class const_reverse_iterator; using base_iterator = typename LListBase::iterator;
friend class const_reverse_iterator; using const_base_iterator = typename LListBase::const_iterator;
// Constructors // Constructors
//- Null construct //- Null construct
UILList() UILList() = default;
{}
//- Construct given initial T //- Construct and insert the initial T item
UILList(T* a) explicit UILList(T* item)
: {
LListBase(a) this->insert(item);
{} }
//- Construct as copy //- Construct as copy
UILList(const UILList<LListBase, T>&); UILList(const UILList<LListBase, T>& lst);
// Member Functions // Member Functions
// Access //- The first entry in the list
T* first()
{
return static_cast<T*>(LListBase::first());
}
//- Return the first entry //- The first entry in the list (const access)
T* first() const T* first() const
{ {
return static_cast<T*>(LListBase::first()); return static_cast<const T*>(LListBase::first());
} }
//- Return the first entry //- The last entry in the list
const T* first() const T* last()
{ {
return static_cast<const T*>(LListBase::first()); return static_cast<T*>(LListBase::last());
} }
//- Return the last entry //- The last entry in the list (const access)
T* last() const T* last() const
{ {
return static_cast<T*>(LListBase::last()); return static_cast<const T*>(LListBase::last());
} }
//- Return the last entry
const T* last() const
{
return static_cast<const T*>(LListBase::last());
}
// Edit //- Remove and return head
T* removeHead()
{
return static_cast<T*>(LListBase::removeHead());
}
//- Remove and return head //- Remove and return element
T* removeHead() T* remove(T* item)
{ {
return static_cast<T*>(LListBase::removeHead()); return static_cast<T*>(LListBase::remove(item));
} }
//- Remove and return element //- Remove and return item specified by iterator
T* remove(T* p) T* remove(iterator& iter)
{ {
return static_cast<T*>(LListBase::remove(p)); return static_cast<T*>(LListBase::remove(iter));
} }
//- Remove and return specified by iterator
T* remove(iterator& it)
{
return static_cast<T*>(LListBase::remove(it));
}
// Member operators // Member operators
void operator=(const UILList<LListBase, T>&); //- Copy assignment
void operator=(const UILList<LListBase, T>& lst);
//- Equality. True both lists are element-wise equal
// (using value_type::operator==). Takes linear time.
bool operator==(const UILList<LListBase, T>& lst) const;
//- The opposite of the equality operation. Takes linear time.
bool operator!=(const UILList<LListBase, T>& lst) const;
// STL type definitions // IOstream operators
//- Type of values the DLList contains. //- Write UILList with line-breaks when its length exceeds
typedef T value_type; //- shortListLen.
// Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortListLen=0) const;
//- Type that can be used for storing into DLList::value_type //- Write UILList to Ostream with line breaks,
// objects. //- as per writeList() with shortListLen=-1
typedef T& reference; friend Ostream& operator<< <LListBase, T>
(
//- Type that can be used for storing into constant Ostream& os,
// DLList::value_type objects. const UILList<LListBase, T>& lst
typedef const T& const_reference; );
//- The type that can represent the size of a DLList.
typedef label size_type;
// STL iterator // STL iterator
typedef typename LListBase::iterator LListBase_iterator; //- A non-const iterator
//- An STL-conforming iterator
class iterator class iterator
: :
public LListBase_iterator public base_iterator
{ {
public: public:
//- Construct from base iterator iterator(base_iterator iter)
iterator(LListBase_iterator baseIter)
: :
LListBase_iterator(baseIter) base_iterator(iter)
{} {}
//- Return the address of the object being referenced
pointer get() const
{
return static_cast<T*>(base_iterator::get_node());
}
// Member operators reference operator*() const
{
return *(this->get());
}
T& operator*() const pointer operator->() const
{ {
return static_cast<T&>(LListBase_iterator::operator*()); return this->get();
} }
T& operator()() const reference operator()() const
{ {
return operator*(); return operator*();
} }
iterator& operator++() iterator& operator++()
{ {
LListBase_iterator::operator++(); this->next();
return *this; return *this;
} }
}; };
inline iterator begin()
{
return LListBase::begin();
}
inline const iterator& end()
{
return static_cast<const iterator&>(LListBase::end());
}
// STL const_iterator // STL const_iterator
typedef typename LListBase::const_iterator LListBase_const_iterator; //- A const_iterator
//- An STL-conforming const_iterator
class const_iterator class const_iterator
: :
public LListBase_const_iterator public const_base_iterator
{ {
public: public:
//- Construct from base const_iterator //- Construct from base const_iterator
const_iterator(LListBase_const_iterator baseIter) const_iterator(const_base_iterator iter)
: :
LListBase_const_iterator(baseIter) const_base_iterator(iter)
{} {}
//- Construct from base iterator //- Construct from base iterator
const_iterator(LListBase_iterator baseIter) const_iterator(base_iterator iter)
: :
LListBase_const_iterator(baseIter) const_base_iterator(iter)
{} {}
//- Return the address of the object being referenced
const_pointer get() const
{
return static_cast<const T*>(const_base_iterator::get_node());
}
// Member operators const_reference operator*() const
{
return *(this->get());
}
const T& operator*() const const_pointer operator->() const
{ {
return return this->get();
static_cast<const T&> }
(LListBase_const_iterator::operator*());
}
const T& operator()() const const_reference operator()() const
{ {
return operator*(); return operator*();
} }
const_iterator& operator++() const_iterator& operator++()
{ {
LListBase_const_iterator::operator++(); this->next();
return *this; return *this;
} }
}; };
inline const_iterator cbegin() const
{
return LListBase::cbegin();
}
inline const const_iterator& cend() const // STL reverse_iterator
{
return static_cast<const const_iterator&>(LListBase::cend());
}
inline const_iterator begin() const //- A reverse_iterator, for LListBase classes that support
//- reverse iteration
class reverse_iterator
:
public base_iterator
{ {
return LListBase::begin(); public:
}
inline const const_iterator& end() const reverse_iterator(base_iterator iter)
{ :
return static_cast<const const_iterator&>(LListBase::end()); base_iterator(iter)
} {}
//- Return the address of the object being referenced
pointer get() const
{
return static_cast<T*>(base_iterator::get_node());
}
reference operator*() const
{
return *(this->get());
}
pointer operator->() const
{
return this->get();
}
reference operator()() const
{
return operator*();
}
reverse_iterator& operator++()
{
this->prev(); // Only if base iterator is bidirectional
return *this;
}
};
// STL const_reverse_iterator // STL const_reverse_iterator
//- An STL-conforming const_reverse_iterator //- A const_reverse_iterator, for LListBase classes that support
//- reverse iteration
class const_reverse_iterator class const_reverse_iterator
: :
public LListBase::const_reverse_iterator public const_base_iterator
{ {
public: public:
//- Construct from base const_reverse_iterator const_reverse_iterator(const_base_iterator iter)
const_reverse_iterator
(
typename LListBase::const_reverse_iterator baseIter
)
: :
LListBase::const_reverse_iterator(baseIter) const_base_iterator(iter)
{} {}
//- Return the address of the object being referenced
const_pointer get() const
{
return static_cast<const T*>(const_base_iterator::get_node());
}
// Member operators const_reference operator*() const
{
return *(this->get());
}
const T& operator*() const const_pointer operator->() const
{ {
return return this->get();
static_cast<const T&> }
(LListBase::const_reverse_iterator::operator*());
}
const T& operator()() const const_reference operator()() const
{ {
return operator*(); return operator*();
} }
const_reverse_iterator& operator++() const_reverse_iterator& operator++()
{ {
LListBase::const_reverse_iterator::operator++(); this->prev(); // Only if base iterator is bidirectional
return *this; return *this;
} }
}; };
//- Iterator to first item in list with non-const access
inline iterator begin()
{
return LListBase::template iterator_first<base_iterator>();
}
//- Iterator to first item in list with const access
inline const_iterator cbegin() const
{
return LListBase::template iterator_first<const_base_iterator>();
}
//- Iterator to last item in list with non-const access
inline reverse_iterator rbegin()
{
return LListBase::template iterator_last<base_iterator>();
}
//- Iterator to last item in list with const access
inline const_reverse_iterator crbegin() const inline const_reverse_iterator crbegin() const
{ {
return LListBase::crbegin(); return LListBase::template iterator_last<const_base_iterator>();
} }
inline const const_reverse_iterator& crend() const //- Iterator to first item in list with const access
inline const_iterator begin() const
{ {
return return LListBase::cbegin();
static_cast<const const_reverse_iterator&>(LListBase::crend());
} }
//- Iterator to last item in list with const access
inline const_reverse_iterator rbegin() const inline const_reverse_iterator rbegin() const
{ {
return LListBase::rbegin(); return crbegin();
} }
//- End of list for forward iterators
inline const iterator& end()
{
return LListBase::template iterator_end<iterator>();
}
//- End of list for forward iterators
inline const const_iterator& cend() const
{
return LListBase::template iterator_end<const_iterator>();
}
//- End of list for reverse iterators
inline const reverse_iterator& rend()
{
return LListBase::template iterator_rend<reverse_iterator>();
}
//- End of list for reverse iterators
inline const const_reverse_iterator& crend() const
{
return LListBase::template iterator_rend<const_reverse_iterator>();
}
//- End of list for forward iterators
inline const const_iterator& end() const
{
return cend();
}
//- End of list for reverse iterators
inline const const_reverse_iterator& rend() const inline const const_reverse_iterator& rend() const
{ {
return return crend();
static_cast<const const_reverse_iterator&>(LListBase::rend());
} }
// STL member operators
//- Equality operation on ULists of the same type.
// Returns true when the ULists are element-wise equal
// (using UList::value_type::operator==). Takes linear time.
bool operator==(const UILList<LListBase, T>&) const;
//- The opposite of the equality operation. Takes linear time.
bool operator!=(const UILList<LListBase, T>&) const;
// Ostream operator
friend Ostream& operator<< <LListBase, T>
(
Ostream&,
const UILList<LListBase, T>&
);
}; };
@ -381,6 +457,7 @@ public:
#ifdef NoRepository #ifdef NoRepository
#include "UILList.C" #include "UILList.C"
#include "UILListIO.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -30,30 +30,61 @@ License
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class LListBase, class T> template<class LListBase, class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const UILList<LListBase, T>& lst) Foam::Ostream& Foam::UILList<LListBase, T>::writeList
(
Ostream& os,
const label shortListLen
) const
{ {
// Write size const label len = this->size();
os << nl << lst.size();
// Write beginning of contents if
os << nl << token::BEGIN_LIST << nl;
// Write contents
for
( (
typename UILList<LListBase, T>::const_iterator iter = lst.begin(); len <= 1 || !shortListLen
iter != lst.end(); || (len <= shortListLen)
++iter
) )
{ {
os << iter() << nl; // Size and start delimiter
} os << len << token::BEGIN_LIST;
// Write end of contents // Contents
os << token::END_LIST; bool space = false;
for (const T& val : *this)
{
if (space) os << token::SPACE;
space = true;
os << val;
}
// End delimiter
os << token::END_LIST;
}
else
{
// Size and start delimiter
os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents
for (const T& val : *this)
{
os << val << nl;
}
// End delimiter
os << token::END_LIST;
}
os.check(FUNCTION_NAME); os.check(FUNCTION_NAME);
return os; return os;
} }
template<class LListBase, class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const UILList<LListBase, T>& lst)
{
return lst.writeList(os, -1);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -23,158 +23,142 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H"
#include "DLListBase.H" #include "DLListBase.H"
#include "IOstreams.H" #include "error.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
Foam::DLListBase::iterator Foam::DLListBase::endIter_
(
const_cast<DLListBase&>(static_cast<const DLListBase&>(DLListBase()))
);
Foam::DLListBase::const_iterator Foam::DLListBase::endConstIter_
(
static_cast<const DLListBase&>(DLListBase()),
reinterpret_cast<const link*>(0)
);
Foam::DLListBase::const_reverse_iterator Foam::DLListBase::endConstRevIter_
(
static_cast<const DLListBase&>(DLListBase()),
reinterpret_cast<const link*>(0)
);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::DLListBase::insert(DLListBase::link* a) void Foam::DLListBase::insert(DLListBase::link* item)
{ {
nElmts_++; if (!item)
{
return;
}
++size_;
if (!first_) if (!first_)
{ {
a->prev_ = a; item->prev_ = item;
a->next_ = a; item->next_ = item;
first_ = last_ = a; first_ = last_ = item;
} }
else else
{ {
a->prev_ = a; item->prev_ = item;
a->next_ = first_; item->next_ = first_;
first_->prev_ = a; first_->prev_ = item;
first_ = a; first_ = item;
} }
} }
void Foam::DLListBase::append(DLListBase::link* a) void Foam::DLListBase::append(DLListBase::link* item)
{ {
nElmts_++; if (!item)
{
return;
}
++size_;
if (!first_) if (!first_)
{ {
a->prev_ = a; item->prev_ = item;
a->next_ = a; item->next_ = item;
first_ = last_ = a; first_ = last_ = item;
} }
else else
{ {
last_->next_ = a; last_->next_ = item;
a->prev_ = last_; item->prev_ = last_;
a->next_ = a; item->next_ = item;
last_ = a; last_ = item;
} }
} }
bool Foam::DLListBase::swapUp(DLListBase::link* a) bool Foam::DLListBase::swapUp(DLListBase::link* a)
{ {
if (first_ != a) if (first_ == a)
{
link* ap = a->prev_;
if (ap == first_)
{
first_ = a;
ap->prev_ = a;
}
else
{
ap->prev_->next_ = a;
}
if (a == last_)
{
last_ = ap;
a->next_ = ap;
}
else
{
a->next_->prev_ = ap;
}
a->prev_ = ap->prev_;
ap->prev_ = a;
ap->next_ = a->next_;
a->next_ = ap;
return true;
}
else
{ {
return false; return false;
} }
DLListBase::link *ap = a->prev_;
if (ap == first_)
{
first_ = a;
ap->prev_ = a;
}
else
{
ap->prev_->next_ = a;
}
if (a == last_)
{
last_ = ap;
a->next_ = ap;
}
else
{
a->next_->prev_ = ap;
}
a->prev_ = ap->prev_;
ap->prev_ = a;
ap->next_ = a->next_;
a->next_ = ap;
return true;
} }
bool Foam::DLListBase::swapDown(DLListBase::link* a) bool Foam::DLListBase::swapDown(DLListBase::link* a)
{ {
if (last_ != a) if (last_ == a)
{
link* an = a->next_;
if (a == first_)
{
first_ = an;
a->prev_ = an;
}
else
{
a->prev_->next_ = an;
}
if (an == last_)
{
last_ = a;
an->next_ = a;
}
else
{
an->next_->prev_ = a;
}
an->prev_ = a->prev_;
a->prev_ = an;
a->next_ = an->next_;
an->next_ = a;
return true;
}
else
{ {
return false; return false;
} }
DLListBase::link *an = a->next_;
if (a == first_)
{
first_ = an;
a->prev_ = an;
}
else
{
a->prev_->next_ = an;
}
if (an == last_)
{
last_ = a;
an->next_ = a;
}
else
{
an->next_->prev_ = a;
}
an->prev_ = a->prev_;
a->prev_ = an;
a->next_ = an->next_;
an->next_ = a;
return true;
} }
Foam::DLListBase::link* Foam::DLListBase::removeHead() Foam::DLListBase::link* Foam::DLListBase::removeHead()
{ {
nElmts_--; --size_;
if (!first_) if (!first_)
{ {
@ -183,44 +167,44 @@ Foam::DLListBase::link* Foam::DLListBase::removeHead()
<< abort(FatalError); << abort(FatalError);
} }
DLListBase::link* f = first_; DLListBase::link *ret = first_;
first_ = f->next_; first_ = first_->next_;
if (!first_) if (!first_)
{ {
last_ = nullptr; last_ = nullptr;
} }
f->deregister(); ret->deregister();
return f; return ret;
} }
Foam::DLListBase::link* Foam::DLListBase::remove(DLListBase::link* l) Foam::DLListBase::link* Foam::DLListBase::remove(DLListBase::link* item)
{ {
nElmts_--; --size_;
link* ret = l; DLListBase::link *ret = item;
if (l == first_ && first_ == last_) if (item == first_ && first_ == last_)
{ {
first_ = nullptr; first_ = nullptr;
last_ = nullptr; last_ = nullptr;
} }
else if (l == first_) else if (item == first_)
{ {
first_ = first_->next_; first_ = first_->next_;
first_->prev_ = first_; first_->prev_ = first_;
} }
else if (l == last_) else if (item == last_)
{ {
last_ = last_->prev_; last_ = last_->prev_;
last_->next_ = last_; last_->next_ = last_;
} }
else else
{ {
l->next_->prev_ = l->prev_; item->next_->prev_ = item->prev_;
l->prev_->next_ = l->next_; item->prev_->next_ = item->next_;
} }
ret->deregister(); ret->deregister();
@ -234,7 +218,7 @@ Foam::DLListBase::link* Foam::DLListBase::replace
DLListBase::link* newLink DLListBase::link* newLink
) )
{ {
link* ret = oldLink; DLListBase::link *ret = oldLink;
newLink->prev_ = oldLink->prev_; newLink->prev_ = oldLink->prev_;
newLink->next_ = oldLink->next_; newLink->next_ = oldLink->next_;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,6 +27,13 @@ Class
Description Description
Base for doubly-linked lists. Base for doubly-linked lists.
The iterators associated with the list only have a core functionality
for navigation, with additional functionality to be added by inheriting
classes. The node iterators always have a node-pointer as the
first member data, which allows reinterpret_cast from anything else with
a nullptr as its first data member.
The nullObject is such an item (with a nullptr data member).
SourceFiles SourceFiles
DLListBaseI.H DLListBaseI.H
DLListBase.C DLListBase.C
@ -36,9 +43,9 @@ SourceFiles
#ifndef DLListBase_H #ifndef DLListBase_H
#define DLListBase_H #define DLListBase_H
#include "bool.H"
#include "label.H" #include "label.H"
#include "uLabel.H" #include "uLabel.H"
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -51,35 +58,40 @@ namespace Foam
class DLListBase class DLListBase
{ {
public: public:
//- Link structure //- The structure for a doubly-linked storage node
struct link struct link
{ {
//- Pointer to prev entry in list
link* prev_ = nullptr;
//- Pointer to next entry in list //- Pointer to next entry in list
link *prev_, *next_; link* next_ = nullptr;
//- Null construct //- Null construct
inline link(); link() = default;
//- Check if the link is registered with the DLListBase //- Check if the node is registered with the list
inline bool registered() const; inline bool registered() const;
//- Deregister the link after removal //- Deregister the node after removal
inline void deregister(); inline void deregister();
}; };
private: private:
// Private data // Private Member Data
//- first_ points to first element and last_ points to last element. //- Pointer to first element
link *first_, *last_; link *first_ = nullptr;
//- Number of elements in in list //- Pointer to last element
label nElmts_; link *last_ = nullptr;
//- Number of elements in the list
label size_ = 0;
// Private Member Functions // Private Member Functions
@ -91,9 +103,34 @@ private:
void operator=(const DLListBase&) = delete; void operator=(const DLListBase&) = delete;
protected:
// Protected Member Functions
//- Factory method to return an iterator end
// Simply reinterprets a NullObject as a DLListBase iterator.
template<class IteratorType>
inline static const IteratorType& iterator_end();
//- Factory method to return an iterator reverse end
// Simply reinterprets a NullObject as a DLListBase iterator.
template<class IteratorType>
inline static const IteratorType& iterator_rend();
//- Return iterator to first item or end-iterator if list is empty
// Removes constness which the caller promises to manage.
template<class IteratorType>
inline IteratorType iterator_first() const;
//- Return iterator to last item or end-iterator if list is empty
// Removes constness which the caller promises to manage.
template<class IteratorType>
inline IteratorType iterator_last() const;
public: public:
// Forward declaration of STL iterators // Forward declaration of iterators
class iterator; class iterator;
friend class iterator; friend class iterator;
@ -101,213 +138,185 @@ public:
class const_iterator; class const_iterator;
friend class const_iterator; friend class const_iterator;
class const_reverse_iterator;
friend class const_reverse_iterator;
// Constructors // Constructors
//- Null construct //- Null construct
inline DLListBase(); DLListBase() = default;
//- Construct given initial entry
inline DLListBase(link*);
//- Destructor //- Destructor
~DLListBase(); ~DLListBase() = default;
// Member Functions // Member Functions
// Access //- Return number of elements in list
inline label size() const;
//- Return number of elements in list //- Return true if the list is empty
inline label size() const; inline bool empty() const;
//- Return true if the list is empty //- Return first entry
inline bool empty() const; inline link* first();
//- Return first entry //- Return const access to first entry
inline link* first(); inline const link* first() const;
//- Return const access to first entry //- Return last entry
inline const link* first() const; inline link* last();
//- Return last entry //- Return const access to last entry
inline link* last(); inline const link* last() const;
//- Return const access to last entry
inline const link* last() const;
// Edit //- Add at head of list
void insert(link* item);
//- Add at head of list //- Add at tail of list
void insert(link*); void append(link* item);
//- Add at tail of list //- Swap this element with the one above unless it is at the top
void append(link*); bool swapUp(link* item);
//- Swap this element with the one above unless it is at the top //- Swap this element with the one below unless it is at the bottom
bool swapUp(link*); bool swapDown(link* item);
//- Swap this element with the one below unless it is at the bottom //- Remove and return head
bool swapDown(link*); link* removeHead();
//- Remove and return head //- Remove and return element
link* removeHead(); link* remove(link* item);
//- Remove and return element // Remove and return element specified by iterator
link* remove(link*); inline link* remove(iterator& iter);
// Remove and return element specified by iterator //- Replace oldLink with newLink and return element
inline link* remove(iterator&); link* replace(link* oldLink, link* newLink);
//- Replace oldLink with newLink and return element //- Replace oldIter with newItem and return element
link* replace(link* oldLink, link* newLink); inline link* replace(iterator& oldIter, link* newitem);
//- Replace oldIter with newLink and return element //- Clear the list
inline link* replace(iterator& oldIter, link* newLink); inline void clear();
//- Clear the list //- Swap the contents of the list
inline void clear(); inline void swap(DLListBase& lst);
//- Transfer the contents of the argument into this List //- Transfer the contents of the argument into this list
// and annul the argument list. //- and annul the argument list.
inline void transfer(DLListBase&); inline void transfer(DLListBase& lst);
// STL iterator
//- An STL-conforming iterator // iterator
//- A primitive non-const node iterator.
// Needs to be extended by inheriting classes.
class iterator class iterator
{ {
friend class DLListBase; friend class DLListBase;
friend class const_iterator; friend class const_iterator;
//- Reference to the list this is an iterator for //- The selected node.
DLListBase& curList_; // MUST be the first member for easy comparison between iterators
// and for reinterpret_cast from nullObject
link* node_;
//- Current element //- The list being iterated on
link* curElmt_; DLListBase* list_;
//- Copy of the link //- Copy of the node prev/next pointers (to use after removal)
link curLink_; link copy_;
//- Construct for a given SLListBase with nullptr element and link.
// Only used to create endIter
inline iterator(DLListBase&);
public: public:
//- Construct for a given DLListBase and link //- Construct for a node on a list
inline iterator(DLListBase&, link*); inline iterator(DLListBase* list, link* item);
//- Currently pointing at a valid entry //- The storage node
inline link* get_node() const;
//- Pointing at a valid storage node
inline bool found() const; inline bool found() const;
//- Move backward through list
inline void prev();
//- Move forward through list
inline void next();
inline void operator=(const iterator& iter); inline void operator=(const iterator& iter);
inline bool operator==(const iterator& iter) const; inline bool operator==(const iterator&) const;
inline bool operator!=(const iterator& iter) const; inline bool operator!=(const iterator&) const;
inline link& operator*() const;
inline iterator& operator++();
inline iterator operator++(int);
}; };
inline iterator begin();
inline const iterator& end();
// const_iterator
// STL const_iterator //- A primitive const node iterator (bidirectional).
// Must normally be extended by inheriting classes.
//- An STL-conforming const_iterator // Since this iterator works bidirectionally, it can be used as the
// basis for a derived const_reverse_iterator
class const_iterator class const_iterator
{ {
//- Reference to the list this is an iterator for //- The selected node.
const DLListBase& curList_; // MUST be the first member for easy comparison between iterators
// and for reinterpret_cast from nullObject
const link* node_;
//- Current element //- The list being iterated on (as pointer for bitwise copy)
const link* curElmt_; const DLListBase* list_;
public: public:
//- Construct for a given DLListBase and link //- Construct for a node on a list
inline const_iterator(const DLListBase&, const link*); inline const_iterator(const DLListBase* list, const link* item);
//- Construct from a non-const iterator //- Copy construct from a non-const iterator
inline const_iterator(const DLListBase::iterator& iter); inline const_iterator(const DLListBase::iterator& iter);
//- Currently pointing at a valid entry //- Copy construct
const_iterator(const const_iterator&) = default;
//- The storage node
inline const link* get_node() const;
//- Pointing at a valid storage node
inline bool found() const; inline bool found() const;
inline void operator=(const const_iterator& iter); //- Move backward through list
inline void prev();
inline bool operator==(const const_iterator& iter) const; //- Move forward through list
inline bool operator!=(const const_iterator& iter) const; inline void next();
inline const link& operator*() const; const_iterator& operator=(const const_iterator&) = default;
inline const_iterator& operator++(); inline bool operator==(const const_iterator&) const;
inline const_iterator operator++(int); inline bool operator!=(const const_iterator&) const;
}; };
//- Iterator to first item in list with non-const access
inline iterator begin();
//- Iterator to first item in list with const access
inline const_iterator cbegin() const; inline const_iterator cbegin() const;
//- Iterator to last item in list with const access
// Note that this is not a const_reverse_iterator, this is the
// responsibilty of any derived classes.
inline const_iterator crbegin() const;
//- End of list for iterators
inline const iterator& end();
//- End of list for iterators
inline const const_iterator& cend() const; inline const const_iterator& cend() const;
inline const_iterator begin() const; //- End of list for reverse iterators
inline const const_iterator& end() const; inline const const_iterator& crend() const;
// STL const_reverse_iterator
//- An STL-conforming const_reverse_iterator
class const_reverse_iterator
{
//- Reference to the list this is an reverse_iterator for
const DLListBase& curList_;
//- Current element
const link* curElmt_;
public:
//- Construct for a given DLListBase and link
inline const_reverse_iterator(const DLListBase& lst, const link*);
//- Currently pointing at a valid entry
inline bool found() const;
inline void operator=(const const_reverse_iterator& iter);
inline bool operator==(const const_reverse_iterator& iter) const;
inline bool operator!=(const const_reverse_iterator& iter) const;
inline const link& operator*() const;
inline const_reverse_iterator& operator++();
inline const_reverse_iterator operator++(int);
};
inline const_reverse_iterator crbegin() const;
inline const const_reverse_iterator& crend() const;
inline const_reverse_iterator rbegin() const;
inline const const_reverse_iterator& rend() const;
private:
//- Iterator returned by end()
static iterator endIter_;
//- const_iterator returned by end()
static const_iterator endConstIter_;
//- const_reverse_iterator returned by end()
static const_reverse_iterator endConstRevIter_;
}; };

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -24,39 +24,74 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "error.H"
#include "nullObject.H"
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
inline Foam::DLListBase::link::link() template<class IteratorType>
: inline const IteratorType& Foam::DLListBase::iterator_end()
prev_(nullptr),
next_(nullptr)
{}
inline Foam::DLListBase::DLListBase()
:
first_(nullptr),
last_(nullptr),
nElmts_(0)
{}
inline Foam::DLListBase::DLListBase(link* a)
:
first_(a),
last_(a),
nElmts_(1)
{ {
a->prev_ = a; return *reinterpret_cast<const IteratorType*>(nullObjectPtr);
a->next_ = a;
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template<class IteratorType>
inline const IteratorType& Foam::DLListBase::iterator_rend()
{
return *reinterpret_cast<const IteratorType*>(nullObjectPtr);
}
inline Foam::DLListBase::~DLListBase()
{} template<class IteratorType>
inline IteratorType Foam::DLListBase::iterator_first() const
{
DLListBase* list = const_cast<DLListBase*>(this);
if (size())
{
return IteratorType(list, const_cast<DLListBase::link*>(first_));
}
// Return an end iterator
return IteratorType(list, nullptr);
}
template<class IteratorType>
inline IteratorType Foam::DLListBase::iterator_last() const
{
DLListBase* list = const_cast<DLListBase*>(this);
if (size())
{
return IteratorType(list, const_cast<DLListBase::link*>(last_));
}
// Return an end iterator
return IteratorType(list, nullptr);
}
// * * * * * * * * * * * * * * * Iterator ends * * * * * * * * * * * * * * * //
inline const Foam::DLListBase::iterator& Foam::DLListBase::end()
{
return iterator_end<DLListBase::iterator>();
}
inline const Foam::DLListBase::const_iterator&
Foam::DLListBase::cend() const
{
return iterator_end<DLListBase::const_iterator>();
}
inline const Foam::DLListBase::const_iterator&
Foam::DLListBase::crend() const
{
return iterator_rend<DLListBase::const_iterator>();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -69,27 +104,26 @@ inline bool Foam::DLListBase::link::registered() const
inline void Foam::DLListBase::link::deregister() inline void Foam::DLListBase::link::deregister()
{ {
prev_ = nullptr; prev_ = next_ = nullptr;
next_ = nullptr;
} }
inline Foam::label Foam::DLListBase::size() const inline Foam::label Foam::DLListBase::size() const
{ {
return nElmts_; return size_;
} }
inline bool Foam::DLListBase::empty() const inline bool Foam::DLListBase::empty() const
{ {
return !nElmts_; return !size_;
} }
inline Foam::DLListBase::link* inline Foam::DLListBase::link*
Foam::DLListBase::first() Foam::DLListBase::first()
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -102,7 +136,7 @@ Foam::DLListBase::first()
inline const Foam::DLListBase::link* inline const Foam::DLListBase::link*
Foam::DLListBase::first() const Foam::DLListBase::first() const
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -115,7 +149,7 @@ Foam::DLListBase::first() const
inline Foam::DLListBase::link* inline Foam::DLListBase::link*
Foam::DLListBase::last() Foam::DLListBase::last()
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -128,7 +162,7 @@ Foam::DLListBase::last()
inline const Foam::DLListBase::link* inline const Foam::DLListBase::link*
Foam::DLListBase::last() const Foam::DLListBase::last() const
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -142,15 +176,23 @@ inline void Foam::DLListBase::clear()
{ {
first_ = nullptr; first_ = nullptr;
last_ = nullptr; last_ = nullptr;
nElmts_ = 0; size_ = 0;
}
inline void Foam::DLListBase::swap(DLListBase& lst)
{
std::swap(first_, lst.first_);
std::swap(last_, lst.last_);
std::swap(size_, lst.size_);
} }
inline void Foam::DLListBase::transfer(DLListBase& lst) inline void Foam::DLListBase::transfer(DLListBase& lst)
{ {
first_ = lst.first_; first_ = lst.first_;
last_ = lst.last_; last_ = lst.last_;
nElmts_ = lst.nElmts_; size_ = lst.size_;
lst.clear(); lst.clear();
} }
@ -159,10 +201,10 @@ inline void Foam::DLListBase::transfer(DLListBase& lst)
inline Foam::DLListBase::link* inline Foam::DLListBase::link*
Foam::DLListBase::remove Foam::DLListBase::remove
( (
DLListBase::iterator& it DLListBase::iterator& iter
) )
{ {
return remove(it.curElmt_); return remove(iter.node_);
} }
@ -170,88 +212,100 @@ inline Foam::DLListBase::link*
Foam::DLListBase::replace Foam::DLListBase::replace
( (
DLListBase::iterator& oldIter, DLListBase::iterator& oldIter,
DLListBase::link* newLink DLListBase::link* newItem
) )
{ {
return replace(oldIter.curElmt_, newLink); return replace(oldIter.node_, newItem);
} }
// * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * * //
inline Foam::DLListBase::iterator::iterator(DLListBase& s, link* elmt) inline Foam::DLListBase::iterator::iterator
(
DLListBase* list,
DLListBase::link* item
)
: :
curList_(s), node_(item),
curElmt_(elmt), list_(list),
curLink_(*curElmt_) copy_()
{} {
if (node_ != nullptr)
{
copy_ = *node_;
}
}
inline Foam::DLListBase::iterator::iterator(DLListBase& s) inline Foam::DLListBase::link*
: Foam::DLListBase::iterator::get_node() const
curList_(s), {
curElmt_(nullptr), return node_;
curLink_() }
{}
inline bool Foam::DLListBase::iterator::found() const inline bool Foam::DLListBase::iterator::found() const
{ {
return (curElmt_ != nullptr); return (node_ != nullptr);
}
inline void Foam::DLListBase::iterator::prev()
{
if (list_)
{
// Check if the node_ is the first element (points to itself)
// or if the list is empty because last element was removed
if (node_ == copy_.prev_ || list_->first_ == nullptr)
{
node_ = nullptr;
}
else
{
node_ = copy_.prev_;
copy_ = *node_;
}
}
}
inline void Foam::DLListBase::iterator::next()
{
if (list_)
{
// Check if the node_ is the last element (points to itself)
// or if the list is empty because last element was removed
if (node_ == copy_.next_ || list_->last_ == nullptr)
{
node_ = nullptr;
}
else
{
node_ = copy_.next_;
copy_ = *node_;
}
}
} }
inline void Foam::DLListBase::iterator::operator=(const iterator& iter) inline void Foam::DLListBase::iterator::operator=(const iterator& iter)
{ {
curElmt_ = iter.curElmt_; node_ = iter.node_;
curLink_ = iter.curLink_; list_ = iter.list_;
copy_ = iter.copy_;
} }
inline bool Foam::DLListBase::iterator::operator==(const iterator& iter) const inline bool Foam::DLListBase::iterator::operator==(const iterator& iter) const
{ {
return curElmt_ == iter.curElmt_; return node_ == iter.node_;
} }
inline bool Foam::DLListBase::iterator::operator!=(const iterator& iter) const inline bool Foam::DLListBase::iterator::operator!=(const iterator& iter) const
{ {
return curElmt_ != iter.curElmt_; return node_ != iter.node_;
}
inline Foam::DLListBase::link&
Foam::DLListBase::iterator::operator*() const
{
return *curElmt_;
}
inline Foam::DLListBase::iterator&
Foam::DLListBase::iterator::operator++()
{
// Check if the curElmt_ is the last element (if it points to itself)
// or if the list is empty because the last element may have been removed
if (curLink_.next_ == curElmt_ || curList_.last_ == nullptr)
{
curElmt_ = nullptr;
}
else
{
curElmt_ = curLink_.next_;
curLink_ = *curElmt_;
}
return *this;
}
inline Foam::DLListBase::iterator
Foam::DLListBase::iterator::operator++(int)
{
iterator tmp = *this;
++*this;
return tmp;
} }
@ -260,18 +314,10 @@ Foam::DLListBase::begin()
{ {
if (size()) if (size())
{ {
return iterator(*this, first()); return iterator_first<iterator>();
} }
else
{
return endIter_;
}
}
return end();
inline const Foam::DLListBase::iterator& Foam::DLListBase::end()
{
return endIter_;
} }
@ -279,12 +325,12 @@ inline const Foam::DLListBase::iterator& Foam::DLListBase::end()
inline Foam::DLListBase::const_iterator::const_iterator inline Foam::DLListBase::const_iterator::const_iterator
( (
const DLListBase& s, const DLListBase* list,
const link* elmt const DLListBase::link* item
) )
: :
curList_(s), node_(item),
curElmt_(elmt) list_(list)
{} {}
@ -293,23 +339,53 @@ inline Foam::DLListBase::const_iterator::const_iterator
const DLListBase::iterator& iter const DLListBase::iterator& iter
) )
: :
curList_(iter.curList_), node_(iter.node_),
curElmt_(iter.curElmt_) list_(iter.list_)
{} {}
inline const Foam::DLListBase::link*
Foam::DLListBase::const_iterator::get_node() const
{
return node_;
}
inline bool Foam::DLListBase::const_iterator::found() const inline bool Foam::DLListBase::const_iterator::found() const
{ {
return (curElmt_ != nullptr); return (node_ != nullptr);
} }
inline void Foam::DLListBase::const_iterator::operator= inline void Foam::DLListBase::const_iterator::prev()
(
const const_iterator& iter
)
{ {
curElmt_ = iter.curElmt_; if (list_ && node_)
{
if (node_ == list_->first_)
{
node_ = nullptr;
}
else
{
node_ = node_->prev_;
}
}
}
inline void Foam::DLListBase::const_iterator::next()
{
if (list_ && node_)
{
if (node_ == list_->last_)
{
node_ = nullptr;
}
else
{
node_ = node_->next_;
}
}
} }
@ -318,7 +394,7 @@ inline bool Foam::DLListBase::const_iterator::operator==
const const_iterator& iter const const_iterator& iter
) const ) const
{ {
return curElmt_ == iter.curElmt_; return node_ == iter.node_;
} }
@ -327,39 +403,7 @@ inline bool Foam::DLListBase::const_iterator::operator!=
const const_iterator& iter const const_iterator& iter
) const ) const
{ {
return curElmt_ != iter.curElmt_; return node_ != iter.node_;
}
inline const Foam::DLListBase::link&
Foam::DLListBase::const_iterator::operator*() const
{
return *curElmt_;
}
inline Foam::DLListBase::const_iterator&
Foam::DLListBase::const_iterator::operator++()
{
if (curElmt_ == curList_.last_)
{
curElmt_ = nullptr;
}
else
{
curElmt_ = curElmt_->next_;
}
return *this;
}
inline Foam::DLListBase::const_iterator
Foam::DLListBase::const_iterator::operator++(int)
{
const_iterator tmp = *this;
++*this;
return tmp;
} }
@ -368,146 +412,22 @@ Foam::DLListBase::cbegin() const
{ {
if (size()) if (size())
{ {
return const_iterator(*this, first()); return iterator_first<const_iterator>();
} }
else
{
return endConstIter_;
}
}
return cend();
inline const Foam::DLListBase::const_iterator&
Foam::DLListBase::cend() const
{
return endConstIter_;
} }
inline Foam::DLListBase::const_iterator inline Foam::DLListBase::const_iterator
Foam::DLListBase::begin() const
{
return this->cbegin();
}
inline const Foam::DLListBase::const_iterator&
Foam::DLListBase::end() const
{
return endConstIter_;
}
// * * * * * * * * * * STL const_reverse_iterator * * * * * * * * * * * * * //
inline Foam::DLListBase::const_reverse_iterator::const_reverse_iterator
(
const DLListBase& lst,
const link* elmt
)
:
curList_(lst),
curElmt_(elmt)
{}
inline bool Foam::DLListBase::const_reverse_iterator::found() const
{
return (curElmt_ != nullptr);
}
inline void Foam::DLListBase::const_reverse_iterator::operator=
(
const const_reverse_iterator& iter
)
{
curElmt_ = iter.curElmt_;
}
inline bool Foam::DLListBase::const_reverse_iterator::operator==
(
const const_reverse_iterator& iter
) const
{
return curElmt_ == iter.curElmt_;
}
inline bool Foam::DLListBase::const_reverse_iterator::operator!=
(
const const_reverse_iterator& iter
) const
{
return curElmt_ != iter.curElmt_;
}
inline const Foam::DLListBase::link&
Foam::DLListBase::const_reverse_iterator::operator*() const
{
return *curElmt_;
}
inline Foam::DLListBase::const_reverse_iterator&
Foam::DLListBase::const_reverse_iterator::operator++()
{
if (curElmt_ == curList_.first_)
{
curElmt_ = nullptr;
}
else
{
curElmt_ = curElmt_->prev_;
}
return *this;
}
inline Foam::DLListBase::const_reverse_iterator
Foam::DLListBase::const_reverse_iterator::operator++(int)
{
const_reverse_iterator tmp = *this;
++*this;
return tmp;
}
inline Foam::DLListBase::const_reverse_iterator
Foam::DLListBase::crbegin() const Foam::DLListBase::crbegin() const
{ {
if (size()) if (size())
{ {
return const_reverse_iterator(*this, this->last()); return iterator_last<const_iterator>();
} }
else
{
return endConstRevIter_;
}
}
return crend();
inline const Foam::DLListBase::const_reverse_iterator&
Foam::DLListBase::crend() const
{
return endConstRevIter_;
}
inline Foam::DLListBase::const_reverse_iterator
Foam::DLListBase::rbegin() const
{
return this->crbegin();
}
inline const Foam::DLListBase::const_reverse_iterator&
Foam::DLListBase::rend() const
{
return endConstRevIter_;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -23,61 +23,57 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H"
#include "SLListBase.H" #include "SLListBase.H"
#include "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::SLListBase::iterator Foam::SLListBase::endIter_
(
const_cast<SLListBase&>(static_cast<const SLListBase&>(SLListBase()))
);
Foam::SLListBase::const_iterator Foam::SLListBase::endConstIter_
(
static_cast<const SLListBase&>(SLListBase()),
reinterpret_cast<const link*>(0)
);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::SLListBase::insert(SLListBase::link* a) void Foam::SLListBase::insert(SLListBase::link* item)
{ {
nElmts_++; if (!item)
{
return;
}
++size_;
if (last_) if (last_)
{ {
a->next_ = last_->next_; item->next_ = last_->next_;
} }
else else
{ {
last_ = a; last_ = item;
} }
last_->next_ = a; last_->next_ = item;
} }
void Foam::SLListBase::append(SLListBase::link* a) void Foam::SLListBase::append(SLListBase::link* item)
{ {
nElmts_++; if (!item)
{
return;
}
++size_;
if (last_) if (last_)
{ {
a->next_ = last_->next_; item->next_ = last_->next_;
last_ = last_->next_ = a; last_ = last_->next_ = item;
} }
else else
{ {
last_ = a->next_ = a; last_ = item->next_ = item;
} }
} }
Foam::SLListBase::link* Foam::SLListBase::removeHead() Foam::SLListBase::link* Foam::SLListBase::removeHead()
{ {
nElmts_--; --size_;
if (last_ == nullptr) if (last_ == nullptr)
{ {
@ -86,39 +82,39 @@ Foam::SLListBase::link* Foam::SLListBase::removeHead()
<< abort(FatalError); << abort(FatalError);
} }
SLListBase::link* f = last_->next_; SLListBase::link *ret = last_->next_;
if (f == last_) if (ret == last_)
{ {
last_ = nullptr; last_ = nullptr;
} }
else else
{ {
last_->next_ = f->next_; last_->next_ = ret->next_;
} }
return f; return ret;
} }
Foam::SLListBase::link* Foam::SLListBase::remove(SLListBase::link* it) Foam::SLListBase::link* Foam::SLListBase::remove(SLListBase::link* item)
{ {
SLListBase::iterator iter = begin(); SLListBase::iterator iter = begin();
SLListBase::link *prev = &(*iter); SLListBase::link *prev = iter.get_node();
if (it == prev) if (item == prev)
{ {
return removeHead(); return removeHead();
} }
nElmts_--; for (iter.next(); iter != end(); iter.next())
for (++iter; iter != end(); ++iter)
{ {
SLListBase::link *p = &(*iter); SLListBase::link *p = iter.get_node();
if (p == it) if (p == item)
{ {
--size_;
prev->next_ = p->next_; prev->next_ = p->next_;
if (p == last_) if (p == last_)
@ -126,12 +122,13 @@ Foam::SLListBase::link* Foam::SLListBase::remove(SLListBase::link* it)
last_ = prev; last_ = prev;
} }
return it; return item;
} }
prev = p; prev = p;
} }
// Did not remove
return nullptr; return nullptr;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,6 +27,13 @@ Class
Description Description
Base for singly-linked lists. Base for singly-linked lists.
The iterators associated with the list only have a core functionality
for navigation, with additional functionality to be added by inheriting
classes. The node iterators always have a node-pointer as the
first member data, which allows reinterpret_cast from anything else with
a nullptr as its first data member.
The nullObject is such an item (with a nullptr data member).
SourceFiles SourceFiles
SLListBaseI.H SLListBaseI.H
SLListBase.C SLListBase.C
@ -36,9 +43,9 @@ SourceFiles
#ifndef SLListBase_H #ifndef SLListBase_H
#define SLListBase_H #define SLListBase_H
#include "bool.H"
#include "label.H" #include "label.H"
#include "uLabel.H" #include "uLabel.H"
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -51,33 +58,30 @@ namespace Foam
class SLListBase class SLListBase
{ {
public: public:
//- Link structure //- The structure for a singly-linked storage node
struct link struct link
{ {
//- Pointer to next entry in list //- Pointer to next entry in list
link* next_; link* next_ = nullptr;
//- Null construct //- Null construct
inline link(); link() = default;
//- Construct given pointer to another link
inline link(link* p);
}; };
private: private:
// Private data // Private Member Data
//- last_ points to last element //- A pointer to the last element.
// last_->next_ points to first element, i.e. circular storage // last_->next_ points to first element, i.e. circular storage
link* last_; link* last_ = nullptr;
//- Number of elements in the list
label size_ = 0;
//- Number of elements in in list
label nElmts_;
// Private Member Functions // Private Member Functions
@ -88,9 +92,33 @@ private:
void operator=(const SLListBase&) = delete; void operator=(const SLListBase&) = delete;
protected:
// Protected Member Functions
//- Factory method to return an iterator end
// Simply reinterprets a NullObject as a SLListBase iterator.
template<class IteratorType>
inline static const IteratorType& iterator_end();
//- Factory method to return an iterator rend
// Deleted for SLListBase
template<class IteratorType>
static const IteratorType& iterator_rend() = delete;
//- Return iterator to first item or end-iterator if list is empty
// Removes constness which the caller promises to manage.
template<class IteratorType>
inline IteratorType iterator_first() const;
//- Return iterator to last item or end-iterator if list is empty
// Removes constness which the caller promises to manage.
template<class IteratorType>
inline IteratorType iterator_last() const;
public: public:
// Forward declaration of STL iterators // Forward declaration of iterators
class iterator; class iterator;
friend class iterator; friend class iterator;
@ -102,154 +130,166 @@ public:
// Constructors // Constructors
//- Null construct //- Null construct
inline SLListBase(); SLListBase() = default;
//- Construct given initial entry
inline SLListBase(link*);
//- Destructor //- Destructor
~SLListBase(); ~SLListBase() = default;
// Member Functions // Member Functions
// Access //- Return number of elements in list
inline label size() const;
//- Return number of elements in list //- Return true if the list is empty
inline label size() const; inline bool empty() const;
//- Return true if the list is empty //- Return first entry
inline bool empty() const; inline link* first();
//- Return first entry //- Return const access to first entry
inline link* first(); inline const link* first() const;
//- Return const access to first entry //- Return last entry
inline const link* first() const; inline link* last();
//- Return last entry //- Return const access to last entry
inline link* last(); inline const link* last() const;
//- Return const access to last entry
inline const link* last() const;
// Edit //- Add at head of list
void insert(link* item);
//- Add at head of list //- Add at tail of list
void insert(link*); void append(link* item);
//- Add at tail of list //- Remove and return head
void append(link*); link* removeHead();
//- Remove and return head // Remove and return element
link* removeHead(); link* remove(link* item);
// Remove and return element // Remove and return element specified by iterator
link* remove(link*); inline link* remove(iterator& iter);
// Remove and return element specified by iterator //- Clear the list
inline link* remove(iterator&); inline void clear();
//- Clear the list //- Swap the contents of list
inline void clear(); inline void swap(SLListBase& lst);
//- Transfer the contents of the argument into this List //- Transfer the contents of the argument into this list
// and annul the argument list. //- and annul the argument list.
inline void transfer(SLListBase&); inline void transfer(SLListBase& lst);
// STL iterator
//- An STL-conforming iterator // iterator
//- A primitive non-const node iterator.
// Must normally be extended by inheriting classes.
class iterator class iterator
{ {
friend class SLListBase; friend class SLListBase;
friend class const_iterator; friend class const_iterator;
//- Reference to the list this is an iterator for //- The selected node.
SLListBase& curList_; // MUST be the first member for easy comparison between iterators
// and for reinterpret_cast from nullObject
link* node_;
//- Current element //- The list being iterated on (as pointer for bitwise copy)
link* curElmt_; SLListBase* list_;
//- Copy of the link //- Copy of the node next pointer (to use after removal)
link curLink_; link copy_;
//- Construct for a given SLListBase with nullptr element and link.
// Only used to create endIter
inline iterator(SLListBase&);
public: public:
//- Construct for a given SLListBase and link //- Construct for a node on the list
inline iterator(SLListBase&, link*); inline iterator(SLListBase* list, link* item);
//- Currently pointing at a valid entry //- The storage node
inline link* get_node() const;
//- Pointing at a valid storage node
inline bool found() const; inline bool found() const;
//- Cannot move backward through list
inline void prev() = delete;
//- Move forward through list
inline void next();
inline void operator=(const iterator& iter); inline void operator=(const iterator& iter);
inline bool operator==(const iterator& iter) const; inline bool operator==(const iterator& iter) const;
inline bool operator!=(const iterator& iter) const; inline bool operator!=(const iterator& iter) const;
inline link& operator*() const;
inline iterator& operator++();
inline iterator operator++(int);
}; };
inline iterator begin();
inline const iterator& end();
// STL const_iterator // STL const_iterator
//- An STL-conforming const_iterator //- A primitive const node iterator.
// Must normally be extended by inheriting classes.
class const_iterator class const_iterator
{ {
//- Reference to the list this is an iterator for //- The selected node.
const SLListBase& curList_; // MUST be the first member for easy comparison between iterators
// and for reinterpret_cast from nullObject
const link* node_;
//- Current element //- The list being iterated on (as pointer for bitwise copy)
const link* curElmt_; const SLListBase* list_;
public: public:
//- Construct for a given SLListBase and link //- Construct for a node on the list
inline const_iterator(const SLListBase&, const link*); inline const_iterator(const SLListBase* list, const link* item);
//- Construct from a non-const iterator //- Construct from a non-const iterator
inline const_iterator(const SLListBase::iterator& iter); inline const_iterator(const SLListBase::iterator& iter);
//- Currently pointing at a valid entry //- Copy construct
const_iterator(const const_iterator&) = default;
//- The storage node
inline const link* get_node() const;
//- Pointing at a valid storage node
inline bool found() const; inline bool found() const;
inline void operator=(const const_iterator& iter); //- Cannot move backward through list
inline void prev() = delete;
//- Move forward through list
inline void next();
const_iterator& operator=(const const_iterator&) = default;
inline bool operator==(const const_iterator& iter) const; inline bool operator==(const const_iterator& iter) const;
inline bool operator!=(const const_iterator& iter) const; inline bool operator!=(const const_iterator& iter) const;
inline const link& operator*() const;
inline const_iterator& operator++();
inline const_iterator operator++(int);
}; };
//- Iterator to first item in list with non-const access
inline iterator begin();
//- Iterator to first item in list with const access
inline const_iterator cbegin() const; inline const_iterator cbegin() const;
//- No reverse iteration
const_iterator crbegin() const = delete;
//- End of list for iterators
inline const iterator& end();
//- End of list for iterators
inline const const_iterator& cend() const; inline const const_iterator& cend() const;
inline const_iterator begin() const; //- No reverse iteration
inline const const_iterator& end() const; const const_iterator& crend() const = delete;
private:
//- Iterator returned by end()
static iterator endIter_;
//- const_iterator returned by end()
static const_iterator endConstIter_;
}; };

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -24,65 +24,65 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "error.H"
#include "nullObject.H"
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
inline Foam::SLListBase::link::link() template<class IteratorType>
: inline const IteratorType& Foam::SLListBase::iterator_end()
next_(nullptr)
{}
inline Foam::SLListBase::link::link(link* p)
:
next_(p)
{}
inline Foam::SLListBase::SLListBase()
:
last_(nullptr),
nElmts_(0)
{}
inline Foam::SLListBase::SLListBase(link* a)
:
last_(a),
nElmts_(0)
{ {
if (a) // protect against nullptr return *reinterpret_cast<const IteratorType*>(nullObjectPtr);
{
a->next_ = a;
nElmts_ = 1;
}
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template<class IteratorType>
inline IteratorType Foam::SLListBase::iterator_first() const
{
SLListBase* list = const_cast<SLListBase*>(this);
inline Foam::SLListBase::~SLListBase() if (size())
{} {
return IteratorType(list, const_cast<SLListBase::link*>(last_->next_));
}
// Return an end iterator
return IteratorType(list, nullptr);
}
template<class IteratorType>
inline IteratorType Foam::SLListBase::iterator_last() const
{
SLListBase* list = const_cast<SLListBase*>(this);
if (size())
{
return IteratorType(list, const_cast<SLListBase::link*>(last_));
}
// Return an end iterator
return IteratorType(list, nullptr);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::label Foam::SLListBase::size() const inline Foam::label Foam::SLListBase::size() const
{ {
return nElmts_; return size_;
} }
inline bool Foam::SLListBase::empty() const inline bool Foam::SLListBase::empty() const
{ {
return !nElmts_; return !size_;
} }
inline Foam::SLListBase::link* inline Foam::SLListBase::link*
Foam::SLListBase::first() Foam::SLListBase::first()
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -95,7 +95,7 @@ Foam::SLListBase::first()
inline const Foam::SLListBase::link* inline const Foam::SLListBase::link*
Foam::SLListBase::first() const Foam::SLListBase::first() const
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -108,7 +108,7 @@ Foam::SLListBase::first() const
inline Foam::SLListBase::link* inline Foam::SLListBase::link*
Foam::SLListBase::last() Foam::SLListBase::last()
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -121,7 +121,7 @@ Foam::SLListBase::last()
inline const Foam::SLListBase::link* inline const Foam::SLListBase::link*
Foam::SLListBase::last() const Foam::SLListBase::last() const
{ {
if (!nElmts_) if (!size_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "list is empty" << "list is empty"
@ -134,14 +134,21 @@ Foam::SLListBase::last() const
inline void Foam::SLListBase::clear() inline void Foam::SLListBase::clear()
{ {
last_ = nullptr; last_ = nullptr;
nElmts_ = 0; size_ = 0;
}
inline void Foam::SLListBase::swap(SLListBase& lst)
{
std::swap(last_, lst.last_);
std::swap(size_, lst.size_);
} }
inline void Foam::SLListBase::transfer(SLListBase& lst) inline void Foam::SLListBase::transfer(SLListBase& lst)
{ {
last_ = lst.last_; last_ = lst.last_;
nElmts_ = lst.nElmts_; size_ = lst.size_;
lst.clear(); lst.clear();
} }
@ -149,84 +156,79 @@ inline void Foam::SLListBase::transfer(SLListBase& lst)
inline Foam::SLListBase::link* Foam::SLListBase::remove inline Foam::SLListBase::link* Foam::SLListBase::remove
( (
SLListBase::iterator& it SLListBase::iterator& iter
) )
{ {
return remove(it.curElmt_); return remove(iter.node_);
} }
// * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * * //
inline Foam::SLListBase::iterator::iterator(SLListBase& s, link* elmt) inline Foam::SLListBase::iterator::iterator
(
SLListBase* list,
SLListBase::link* item
)
: :
curList_(s), node_(item),
curElmt_(elmt), list_(list),
curLink_(*curElmt_) copy_()
{} {
if (node_ != nullptr)
{
copy_ = *node_;
}
}
inline Foam::SLListBase::iterator::iterator(SLListBase& s) inline Foam::SLListBase::link*
: Foam::SLListBase::iterator::get_node() const
curList_(s), {
curElmt_(nullptr), return node_;
curLink_() }
{}
inline bool Foam::SLListBase::iterator::found() const inline bool Foam::SLListBase::iterator::found() const
{ {
return (curElmt_ != nullptr); return (node_ != nullptr);
}
inline void Foam::SLListBase::iterator::next()
{
if (list_)
{
if (node_ == list_->last_ || list_->last_ == nullptr)
{
node_ = nullptr;
}
else
{
node_ = copy_.next_;
copy_ = *node_;
}
}
} }
inline void Foam::SLListBase::iterator::operator=(const iterator& iter) inline void Foam::SLListBase::iterator::operator=(const iterator& iter)
{ {
curElmt_ = iter.curElmt_; node_ = iter.node_;
curLink_ = iter.curLink_; list_ = iter.list_;
copy_ = iter.copy_;
} }
inline bool Foam::SLListBase::iterator::operator==(const iterator& iter) const inline bool Foam::SLListBase::iterator::operator==(const iterator& iter) const
{ {
return curElmt_ == iter.curElmt_; return node_ == iter.node_;
} }
inline bool Foam::SLListBase::iterator::operator!=(const iterator& iter) const inline bool Foam::SLListBase::iterator::operator!=(const iterator& iter) const
{ {
return curElmt_ != iter.curElmt_; return node_ != iter.node_;
}
inline Foam::SLListBase::link& Foam::SLListBase::iterator::operator*() const
{
return *curElmt_;
}
inline Foam::SLListBase::iterator& Foam::SLListBase::iterator::operator++()
{
if (curElmt_ == curList_.last_ || curList_.last_ == nullptr)
{
curElmt_ = nullptr;
}
else
{
curElmt_ = curLink_.next_;
curLink_ = *curElmt_;
}
return *this;
}
inline Foam::SLListBase::iterator
Foam::SLListBase::iterator::operator++(int)
{
iterator tmp = *this;
++*this;
return tmp;
} }
@ -235,19 +237,24 @@ Foam::SLListBase::begin()
{ {
if (size()) if (size())
{ {
return iterator(*this, first()); return iterator_first<iterator>();
}
else
{
return endIter_;
} }
return end();
} }
inline const Foam::SLListBase::iterator& inline const Foam::SLListBase::iterator&
Foam::SLListBase::end() Foam::SLListBase::end()
{ {
return endIter_; return iterator_end<SLListBase::iterator>();
}
inline const Foam::SLListBase::const_iterator&
Foam::SLListBase::cend() const
{
return iterator_end<SLListBase::const_iterator>();
} }
@ -255,12 +262,12 @@ Foam::SLListBase::end()
inline Foam::SLListBase::const_iterator::const_iterator inline Foam::SLListBase::const_iterator::const_iterator
( (
const SLListBase& s, const SLListBase* list,
const link* elmt const SLListBase::link* item
) )
: :
curList_(s), node_(item),
curElmt_(elmt) list_(list)
{} {}
@ -269,23 +276,37 @@ inline Foam::SLListBase::const_iterator::const_iterator
const SLListBase::iterator& iter const SLListBase::iterator& iter
) )
: :
curList_(iter.curList_), node_(iter.node_),
curElmt_(iter.curElmt_) list_(iter.list_)
{} {}
inline const Foam::SLListBase::link*
Foam::SLListBase::const_iterator::get_node() const
{
return node_;
}
inline bool Foam::SLListBase::const_iterator::found() const inline bool Foam::SLListBase::const_iterator::found() const
{ {
return (curElmt_ != nullptr); return (node_ != nullptr);
} }
inline void Foam::SLListBase::const_iterator::operator= inline void Foam::SLListBase::const_iterator::next()
(
const const_iterator& iter
)
{ {
curElmt_ = iter.curElmt_; if (list_)
{
if (node_ == list_->last_)
{
node_ = nullptr;
}
else
{
node_ = node_->next_;
}
}
} }
@ -294,7 +315,7 @@ inline bool Foam::SLListBase::const_iterator::operator==
const const_iterator& iter const const_iterator& iter
) const ) const
{ {
return curElmt_ == iter.curElmt_; return node_ == iter.node_;
} }
@ -303,39 +324,7 @@ inline bool Foam::SLListBase::const_iterator::operator!=
const const_iterator& iter const const_iterator& iter
) const ) const
{ {
return curElmt_ != iter.curElmt_; return node_ != iter.node_;
}
inline const Foam::SLListBase::link&
Foam::SLListBase::const_iterator::operator*() const
{
return *curElmt_;
}
inline Foam::SLListBase::const_iterator&
Foam::SLListBase::const_iterator::operator++()
{
if (curElmt_ == curList_.last_)
{
curElmt_ = nullptr;
}
else
{
curElmt_ = curElmt_->next_;
}
return *this;
}
inline Foam::SLListBase::const_iterator
Foam::SLListBase::const_iterator::operator++(int)
{
const_iterator tmp = *this;
++*this;
return tmp;
} }
@ -344,33 +333,10 @@ Foam::SLListBase::cbegin() const
{ {
if (size()) if (size())
{ {
return const_iterator(*this, first()); return iterator_first<const_iterator>();
} }
else
{
return endConstIter_;
}
}
return cend();
inline const Foam::SLListBase::const_iterator&
Foam::SLListBase::cend() const
{
return endConstIter_;
}
inline Foam::SLListBase::const_iterator
Foam::SLListBase::begin() const
{
return this->cbegin();
}
inline const Foam::SLListBase::const_iterator&
Foam::SLListBase::end() const
{
return endConstIter_;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,10 +27,7 @@ Class
Description Description
A FIFO stack based on a singly-linked list. A FIFO stack based on a singly-linked list.
Operations are push(), pop(), top(), bottom() and empty(). Stack operations are push(), pop(), top(), bottom().
SourceFiles
FIFOStack.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -53,7 +50,6 @@ class FIFOStack
: :
public SLList<T> public SLList<T>
{ {
public: public:
// Constructors // Constructors
@ -64,34 +60,35 @@ public:
// Member Functions // Member Functions
// Access //- Return a copy of the top element
T top() const
{
return this->last();
}
//- Return a copy of the top element //- Return a copy of the bottom element
T top() const T bottom() const
{ {
return this->last(); return this->first();
} }
//- Return a copy of the bottom element //- Push an element onto the back of the stack
T bottom() const void push(const T& element)
{ {
return this->first(); this->append(element);
} }
//- Move an element onto the back of the stack
void push(T&& element)
{
this->append(std::move(element));
}
// Edit //- Pop the bottom element off the stack
T pop()
//- Push an element onto the stack {
void push(const T& a) return this->removeHead();
{ }
this->append(a);
}
//- Pop the bottom element off the stack
T pop()
{
return this->removeHead();
}
}; };

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,10 +27,7 @@ Class
Description Description
A LIFO stack based on a singly-linked list. A LIFO stack based on a singly-linked list.
Operations are push(), pop(), top(), bottom() and empty(). Stack operations are push(), pop(), top(), bottom().
SourceFiles
LIFOStack.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -53,7 +50,6 @@ class LIFOStack
: :
public SLList<T> public SLList<T>
{ {
public: public:
// Constructors // Constructors
@ -64,34 +60,35 @@ public:
// Member Functions // Member Functions
// Access //- Return a copy of the top element
T top() const
{
return this->first();
}
//- Return a copy of the top element //- Return a copy of the bottom element
T top() const T bottom() const
{ {
return this->first(); return this->last();
} }
//- Return a copy of the bottom element //- Push an element onto the front of the stack
T bottom() const void push(const T& element)
{ {
return this->last(); this->insert(element);
} }
//- Move an element onto the front of the stack
void push(T&& element)
{
this->insert(std::move(element));
}
// Edit //- Pop the top element off the stack
T pop()
//- Push an element onto the stack {
void push(const T& a) return this->removeHead();
{ }
this->insert(a);
}
//- Pop the top element off the stack
T pop()
{
return this->removeHead();
}
}; };

View File

@ -32,18 +32,10 @@ Description
#ifndef SLList_H #ifndef SLList_H
#define SLList_H #define SLList_H
#include "LList.H"
#include "SLListBase.H" #include "SLListBase.H"
#include "LList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "SLListFwd.H"
namespace Foam
{
template<class T>
using SLList = LList<SLListBase, T>;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif

View File

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
InClass
Foam::SLList
Description
Forward declarations for SLList
\*---------------------------------------------------------------------------*/
#ifndef SLListFwd_H
#define SLListFwd_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class SLListBase;
template<class LListBase, class T> class LList;
// Alias
template<class T>
using SLList = LList<SLListBase, T>;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -32,18 +32,9 @@ Description
#ifndef SLPtrList_H #ifndef SLPtrList_H
#define SLPtrList_H #define SLPtrList_H
#include "LPtrList.H"
#include "SLListBase.H" #include "SLListBase.H"
#include "LPtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "SLPtrListFwd.H"
namespace Foam
{
template<class T>
using SLPtrList = LPtrList<SLListBase, T>;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif

View File

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
InClass
Foam::SLPtrList
Description
Forward declarations for SLPtrList
\*---------------------------------------------------------------------------*/
#ifndef SLPtrListFwd_H
#define SLPtrListFwd_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class SLListBase;
template<class LListBase, class T> class LPtrList;
// Alias
template<class T>
using SLPtrList = LPtrList<SLListBase, T>;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -43,6 +43,7 @@ SourceFiles
#include "Hash.H" #include "Hash.H"
#include "autoPtr.H" #include "autoPtr.H"
#include "Swap.H" #include "Swap.H"
#include "SLListFwd.H"
#include <type_traits> #include <type_traits>
#include <initializer_list> #include <initializer_list>
@ -52,7 +53,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators // Forward declarations
template<class T, unsigned Size> class FixedList; template<class T, unsigned Size> class FixedList;
@ -64,10 +65,6 @@ Ostream& operator<<(Ostream&, const FixedList<T, Size>&);
template<class T> class UList; template<class T> class UList;
class SLListBase;
template<class LListBase, class T> class LList;
template<class T>
using SLList = LList<SLListBase, T>;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class FixedList Declaration Class FixedList Declaration
@ -491,14 +488,14 @@ public:
friend Istream& operator>> <T, Size> friend Istream& operator>> <T, Size>
( (
Istream& is, Istream& is,
FixedList<T, Size>& L FixedList<T, Size>& lst
); );
//- Write List to Ostream, as per writeList() with shortListLen=10 //- Write List to Ostream, as per writeList() with shortListLen=10
friend Ostream& operator<< <T, Size> friend Ostream& operator<< <T, Size>
( (
Ostream& os, Ostream& os,
const FixedList<T, Size>& L const FixedList<T, Size>& lst
); );
}; };

View File

@ -67,7 +67,7 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
const label shortListLen const label shortListLen
) const ) const
{ {
const FixedList<T, Size>& L = *this; const FixedList<T, Size>& lst = *this;
// Write list contents depending on data format // Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>()) if (os.format() == IOstream::ASCII || !contiguous<T>())
@ -76,9 +76,9 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
bool uniform = (Size > 1 && contiguous<T>()); bool uniform = (Size > 1 && contiguous<T>());
if (uniform) if (uniform)
{ {
forAll(L, i) for (unsigned i=0; i<Size; ++i)
{ {
if (L[i] != L[0]) if (lst[i] != lst[0])
{ {
uniform = false; uniform = false;
break; break;
@ -92,7 +92,7 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
os << Size << token::BEGIN_BLOCK; os << Size << token::BEGIN_BLOCK;
// Contents // Contents
os << L[0]; os << lst[0];
// End delimiter // End delimiter
os << token::END_BLOCK; os << token::END_BLOCK;
@ -107,10 +107,10 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
os << token::BEGIN_LIST; os << token::BEGIN_LIST;
// Contents // Contents
forAll(L, i) for (unsigned i=0; i<Size; ++i)
{ {
if (i) os << token::SPACE; if (i) os << token::SPACE;
os << L[i]; os << lst[i];
} }
// End delimiter // End delimiter
@ -122,9 +122,9 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
os << nl << token::BEGIN_LIST << nl; os << nl << token::BEGIN_LIST << nl;
// Contents // Contents
forAll(L, i) for (unsigned i=0; i<Size; ++i)
{ {
os << L[i] << nl; os << lst[i] << nl;
} }
// End delimiter // End delimiter
@ -133,10 +133,10 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
} }
else else
{ {
// Contents are binary and contiguous // Binary, contiguous
// write(...) includes surrounding start/end delimiters // write(...) includes surrounding start/end delimiters
os.write(reinterpret_cast<const char*>(L.cdata()), Size*sizeof(T)); os.write(reinterpret_cast<const char*>(lst.cdata()), Size*sizeof(T));
} }
os.check(FUNCTION_NAME); os.check(FUNCTION_NAME);
@ -154,7 +154,7 @@ Foam::FixedList<T, Size>::FixedList(Istream& is)
template<class T, unsigned Size> template<class T, unsigned Size>
Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L) Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& lst)
{ {
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
@ -169,17 +169,17 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
if (firstToken.isCompound()) if (firstToken.isCompound())
{ {
L = dynamicCast<token::Compound<List<T>>> lst = dynamicCast<token::Compound<List<T>>>
( (
firstToken.transferCompoundToken(is) firstToken.transferCompoundToken(is)
); );
} }
else if (firstToken.isLabel()) else if (firstToken.isLabel())
{ {
label s = firstToken.labelToken(); const label len = firstToken.labelToken();
// Set list length to that read // List lengths must match
L.checkSize(s); lst.checkSize(len);
} }
else if (!firstToken.isPunctuation()) else if (!firstToken.isPunctuation())
{ {
@ -202,7 +202,7 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
{ {
for (unsigned i=0; i<Size; ++i) for (unsigned i=0; i<Size; ++i)
{ {
is >> L[i]; is >> lst[i];
is.fatalCheck is.fatalCheck
( (
@ -224,7 +224,7 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
for (unsigned i=0; i<Size; ++i) for (unsigned i=0; i<Size; ++i)
{ {
L[i] = element; lst[i] = element; // Copy the value
} }
} }
@ -233,9 +233,9 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
} }
else else
{ {
// contents are binary and contiguous // Binary and contiguous
is.read(reinterpret_cast<char*>(L.data()), Size*sizeof(T)); is.read(reinterpret_cast<char*>(lst.data()), Size*sizeof(T));
is.fatalCheck is.fatalCheck
( (
@ -249,9 +249,9 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
template<class T, unsigned Size> template<class T, unsigned Size>
Foam::Ostream& Foam::operator<<(Ostream& os, const FixedList<T, Size>& L) Foam::Ostream& Foam::operator<<(Ostream& os, const FixedList<T, Size>& lst)
{ {
return L.writeList(os, 10); return lst.writeList(os, 10);
} }

View File

@ -373,6 +373,15 @@ Foam::List<T>::List(SortableList<T>&& lst)
} }
template<class T>
Foam::List<T>::List(SLList<T>&& lst)
:
UList<T>(nullptr, 0)
{
operator=(std::move(lst));
}
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
template<class T> template<class T>
@ -530,9 +539,11 @@ void Foam::List<T>::operator=(const List<T>& lst)
template<class T> template<class T>
void Foam::List<T>::operator=(const SLList<T>& lst) void Foam::List<T>::operator=(const SLList<T>& lst)
{ {
reAlloc(lst.size()); const label len = lst.size();
if (this->size_) reAlloc(len);
if (len)
{ {
label i = 0; label i = 0;
for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter) for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
@ -631,6 +642,22 @@ void Foam::List<T>::operator=(SortableList<T>&& lst)
} }
template<class T>
void Foam::List<T>::operator=(SLList<T>&& lst)
{
const label len = lst.size();
reAlloc(len);
for (label i = 0; i < len; ++i)
{
this->operator[](i) = std::move(lst.removeHead());
}
lst.clear();
}
// * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * // // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
#include "ListIO.C" #include "ListIO.C"

View File

@ -43,6 +43,8 @@ SourceFiles
#include "UList.H" #include "UList.H"
#include "autoPtr.H" #include "autoPtr.H"
#include "Xfer.H" #include "Xfer.H"
#include "SLListFwd.H"
#include <initializer_list> #include <initializer_list>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -57,15 +59,9 @@ class Ostream;
template<class T> class List; template<class T> class List;
template<class T, unsigned Size> class FixedList; template<class T, unsigned Size> class FixedList;
template<class T> class PtrList;
class SLListBase;
template<class LListBase, class T> class LList;
template<class T>
using SLList = LList<SLListBase, T>;
template<class T, int SizeMin> class DynamicList; template<class T, int SizeMin> class DynamicList;
template<class T> class PtrList;
template<class T> class SortableList; template<class T> class SortableList;
template<class T> class IndirectList; template<class T> class IndirectList;
template<class T> class UIndirectList; template<class T> class UIndirectList;
@ -73,6 +69,7 @@ template<class T> class BiIndirectList;
template<class T> Istream& operator>>(Istream& is, List<T>& L); template<class T> Istream& operator>>(Istream& is, List<T>& L);
// Commonly required list types
typedef List<char> charList; typedef List<char> charList;
@ -217,6 +214,9 @@ public:
//- Move construct from SortableList //- Move construct from SortableList
List(SortableList<T>&& lst); List(SortableList<T>&& lst);
//- Move construct from SLList
List(SLList<T>&& lst);
//- Construct from Istream //- Construct from Istream
List(Istream& is); List(Istream& is);
@ -326,6 +326,9 @@ public:
//- Move assignment. Takes constant time. //- Move assignment. Takes constant time.
void operator=(SortableList<T>&& lst); void operator=(SortableList<T>&& lst);
//- Move assignment. Takes constant time
void operator=(SLList<T>&& lst);
// Istream operator // Istream operator

View File

@ -41,10 +41,10 @@ Foam::List<T>::List(Istream& is)
template<class T> template<class T>
Foam::Istream& Foam::operator>>(Istream& is, List<T>& L) Foam::Istream& Foam::operator>>(Istream& is, List<T>& lst)
{ {
// Anull list // Anull list
L.setSize(0); lst.setSize(0);
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
@ -52,22 +52,28 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
// Compound: simply transfer contents
if (firstToken.isCompound()) if (firstToken.isCompound())
{ {
L.transfer lst.transfer
( (
dynamicCast<token::Compound<List<T>>> dynamicCast<token::Compound<List<T>>>
( (
firstToken.transferCompoundToken(is) firstToken.transferCompoundToken(is)
) )
); );
return is;
} }
else if (firstToken.isLabel())
// Label: could be int(..), int{...} or just a plain '0'
if (firstToken.isLabel())
{ {
const label sz = firstToken.labelToken(); const label len = firstToken.labelToken();
// Set list length to that read // Set list length to that read
L.setSize(sz); lst.setSize(len);
// Read list contents depending on data format // Read list contents depending on data format
@ -76,13 +82,13 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("List"); const char delimiter = is.readBeginList("List");
if (sz) if (len)
{ {
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<sz; ++i) for (label i=0; i<len; ++i)
{ {
is >> L[i]; is >> lst[i];
is.fatalCheck is.fatalCheck
( (
@ -103,9 +109,9 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
"reading the single entry" "reading the single entry"
); );
for (label i=0; i<sz; ++i) for (label i=0; i<len; ++i)
{ {
L[i] = element; lst[i] = element; // Copy the value
} }
} }
} }
@ -113,22 +119,24 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
// Read end of contents // Read end of contents
is.readEndList("List"); is.readEndList("List");
} }
else else if (len)
{ {
// Contents are binary and contiguous // Non-empty, binary, contiguous
if (sz) is.read(reinterpret_cast<char*>(lst.data()), len*sizeof(T));
{
is.read(reinterpret_cast<char*>(L.data()), sz*sizeof(T));
is.fatalCheck is.fatalCheck
( (
"operator>>(Istream&, List<T>&) : reading the binary block" "operator>>(Istream&, List<T>&) : reading the binary block"
); );
}
} }
return is;
} }
else if (firstToken.isPunctuation())
// "(...)" : read as SLList and transfer contents
if (firstToken.isPunctuation())
{ {
if (firstToken.pToken() != token::BEGIN_LIST) if (firstToken.pToken() != token::BEGIN_LIST)
{ {
@ -138,23 +146,22 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
<< exit(FatalIOError); << exit(FatalIOError);
} }
// Putback the opening bracket is.putBack(firstToken); // Putback the opening bracket
is.putBack(firstToken);
// Read as a singly-linked list SLList<T> sll(is); // Read as singly-linked list
SLList<T> sll(is);
// Convert the singly-linked list to this list // Reallocate and move assign list elements
L = sll; lst = std::move(sll);
}
else return is;
{
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< exit(FatalIOError);
} }
FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< exit(FatalIOError);
return is; return is;
} }

View File

@ -271,34 +271,34 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
token firstTok(is); token firstTok(is);
is.fatalCheck is.fatalCheck
( (
"PackedList<nBits>::read(Istream&) : " "PackedList::read(Istream&) : "
"reading first token" "reading first token"
); );
if (firstTok.isLabel()) if (firstTok.isLabel())
{ {
const label sz = firstTok.labelToken(); const label len = firstTok.labelToken();
// Set list length to that read // Set list length to that read
lst.resize(sz); lst.resize(len);
// Read list contents depending on data format // Read list contents depending on data format
if (is.format() == IOstream::ASCII) if (is.format() == IOstream::ASCII)
{ {
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("PackedList<nBits>"); const char delimiter = is.readBeginList("PackedList");
if (sz) if (len)
{ {
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<sz; ++i) for (label i=0; i<len; ++i)
{ {
lst[i] = lst.readValue(is); lst[i] = lst.readValue(is);
is.fatalCheck is.fatalCheck
( (
"PackedList<nBits>::read(Istream&) : " "PackedList::read(Istream&) : "
"reading entry" "reading entry"
); );
} }
@ -310,7 +310,7 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
is.fatalCheck is.fatalCheck
( (
"PackedList<nBits>::read(Istream&) : " "PackedList::read(Istream&) : "
"reading the single entry" "reading the single entry"
); );
} }
@ -324,11 +324,11 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
} }
// Read end of contents // Read end of contents
is.readEndList("PackedList<nBits>"); is.readEndList("PackedList");
} }
else else
{ {
if (sz) if (len)
{ {
is.read is.read
( (
@ -338,7 +338,7 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
is.fatalCheck is.fatalCheck
( (
"PackedList<nBits>::read(Istream&) : " "PackedList::read(Istream&) : "
"reading the binary block" "reading the binary block"
); );
} }
@ -413,13 +413,13 @@ Foam::Ostream& Foam::PackedList<nBits>::writeList
{ {
const bool indexedOutput = (shortListLen < 0); const bool indexedOutput = (shortListLen < 0);
const PackedList<nBits>& lst = *this; const PackedList<nBits>& lst = *this;
const label sz = lst.size(); const label len = lst.size();
// Write list contents depending on data format // Write list contents depending on data format
if (os.format() == IOstream::ASCII) if (os.format() == IOstream::ASCII)
{ {
// Can the contents be considered 'uniform' (ie, identical)? // Can the contents be considered 'uniform' (ie, identical)?
bool uniform = (sz > 1 && !indexedOutput); bool uniform = (len > 1 && !indexedOutput);
if (uniform) if (uniform)
{ {
forAll(lst, i) forAll(lst, i)
@ -435,7 +435,7 @@ Foam::Ostream& Foam::PackedList<nBits>::writeList
if (uniform) if (uniform)
{ {
// uniform values: // uniform values:
os << sz << token::BEGIN_BLOCK << lst[0] << token::END_BLOCK; os << len << token::BEGIN_BLOCK << lst[0] << token::END_BLOCK;
} }
else if (indexedOutput) else if (indexedOutput)
{ {
@ -457,10 +457,10 @@ Foam::Ostream& Foam::PackedList<nBits>::writeList
os << token::END_BLOCK << nl; os << token::END_BLOCK << nl;
} }
else if (!shortListLen || sz <= shortListLen) else if (!shortListLen || len <= shortListLen)
{ {
// Shorter list, or line-breaks suppressed // Shorter list, or line-breaks suppressed
os << sz << token::BEGIN_LIST; os << len << token::BEGIN_LIST;
forAll(lst, i) forAll(lst, i)
{ {
if (i) os << token::SPACE; if (i) os << token::SPACE;
@ -471,7 +471,7 @@ Foam::Ostream& Foam::PackedList<nBits>::writeList
else else
{ {
// Longer list // Longer list
os << nl << sz << nl << token::BEGIN_LIST << nl; os << nl << len << nl << token::BEGIN_LIST << nl;
forAll(lst, i) forAll(lst, i)
{ {
os << lst[i] << nl; os << lst[i] << nl;
@ -482,9 +482,9 @@ Foam::Ostream& Foam::PackedList<nBits>::writeList
else else
{ {
// Contents are binary and contiguous // Contents are binary and contiguous
os << nl << sz << nl; os << nl << len << nl;
if (sz) if (len)
{ {
// write(...) includes surrounding start/end delimiters // write(...) includes surrounding start/end delimiters
os.write os.write

View File

@ -36,9 +36,9 @@ Foam::PtrList<T>::PtrList()
template<class T> template<class T>
Foam::PtrList<T>::PtrList(const label s) Foam::PtrList<T>::PtrList(const label len)
: :
UPtrList<T>(s) UPtrList<T>(len)
{} {}
@ -99,12 +99,12 @@ Foam::PtrList<T>::PtrList(const SLPtrList<T>& sll)
label i = 0; label i = 0;
for for
( (
typename SLPtrList<T>::const_iterator iter = sll.begin(); typename SLPtrList<T>::const_iterator iter = sll.cbegin();
iter != sll.end(); iter != sll.cend();
++iter ++iter
) )
{ {
this->ptrs_[i++] = (iter()).clone().ptr(); this->ptrs_[i++] = (*iter).clone().ptr();
} }
} }
} }
@ -209,7 +209,7 @@ void Foam::PtrList<T>::reorder(const labelUList& oldToNew)
forAll(*this, i) forAll(*this, i)
{ {
label newI = oldToNew[i]; const label newI = oldToNew[i];
if (newI < 0 || newI >= this->size()) if (newI < 0 || newI >= this->size())
{ {

View File

@ -42,27 +42,20 @@ SourceFiles
#define PtrList_H #define PtrList_H
#include "UPtrList.H" #include "UPtrList.H"
#include "SLPtrListFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
// Forward declaration of classes // Forward declarations
template<class T> class autoPtr; template<class T> class autoPtr;
template<class T> class tmp; template<class T> class tmp;
class SLListBase;
template<class LListBase, class T> class LPtrList;
template<class T>
using SLPtrList = LPtrList<SLListBase, T>;
// Forward declaration of friend functions and operators
template<class T> class PtrList; template<class T> class PtrList;
template<class T> template<class T> Istream& operator>>(Istream& is, PtrList<T>& lst);
Istream& operator>>(Istream&, PtrList<T>&);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -81,7 +74,7 @@ protected:
//- Read from Istream using given Istream constructor class //- Read from Istream using given Istream constructor class
template<class INew> template<class INew>
void read(Istream&, const INew& inewt); void read(Istream& is, const INew& inew);
public: public:
@ -92,30 +85,30 @@ public:
PtrList(); PtrList();
//- Construct with size specified //- Construct with size specified
explicit PtrList(const label); explicit PtrList(const label len);
//- Copy constructor //- Copy constructor, using 'clone()' method on each element
PtrList(const PtrList<T>&); PtrList(const PtrList<T>& a);
//- Copy constructor with additional argument for clone //- Copy constructor with additional argument for clone
template<class CloneArg> template<class CloneArg>
PtrList(const PtrList<T>&, const CloneArg&); PtrList(const PtrList<T>& a, const CloneArg& cloneArg);
//- Construct by transferring the parameter contents //- Construct by transferring the parameter contents
PtrList(const Xfer<PtrList<T>>&); PtrList(const Xfer<PtrList<T>>& lst);
//- Construct as copy or re-use as specified //- Construct as copy or re-use as specified
PtrList(PtrList<T>&, bool reuse); PtrList(PtrList<T>& a, bool reuse);
//- Construct as copy of SLPtrList<T> //- Construct as copy of SLPtrList<T>
explicit PtrList(const SLPtrList<T>&); explicit PtrList(const SLPtrList<T>& sll);
//- Construct from Istream using given Istream constructor class //- Construct from Istream using given Istream constructor class
template<class INew> template<class INew>
PtrList(Istream&, const INew&); PtrList(Istream& is, const INew& inew);
//- Construct from Istream using default Istream constructor class //- Construct from Istream using default Istream constructor class
PtrList(Istream&); PtrList(Istream& is);
//- Destructor //- Destructor

View File

@ -38,9 +38,9 @@ inline void Foam::PtrList<T>::resize(const label newSize)
template<class T> template<class T>
inline void Foam::PtrList<T>::append(T* ptr) inline void Foam::PtrList<T>::append(T* ptr)
{ {
label sz = this->size(); const label idx = this->size();
this->setSize(sz+1); this->setSize(idx + 1);
this->ptrs_[sz] = ptr; this->ptrs_[idx] = ptr;
} }

View File

@ -33,7 +33,7 @@ License
template<class T> template<class T>
template<class INew> template<class INew>
void Foam::PtrList<T>::read(Istream& is, const INew& inewt) void Foam::PtrList<T>::read(Istream& is, const INew& inew)
{ {
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
@ -41,58 +41,66 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
is.fatalCheck is.fatalCheck
( (
"PtrList<T>::read(Istream&, const INew&) : " "PtrList::read(Istream&) : "
"reading first token" "reading first token"
); );
// Label: could be int(..), int{...} or just a plain '0'
if (firstToken.isLabel()) if (firstToken.isLabel())
{ {
// Read size of list // Read size of list
const label sz = firstToken.labelToken(); const label len = firstToken.labelToken();
// Set list length to that read // Set list length to that read
setSize(sz); setSize(len);
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("PtrList"); const char delimiter = is.readBeginList("PtrList");
if (sz) if (len)
{ {
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<sz; ++i) for (label i=0; i<len; ++i)
{ {
set(i, inewt(is)); T* p = inew(is).ptr();
set(i, p);
is.fatalCheck is.fatalCheck
( (
"PtrList<T>::read(Istream&, const INew&) : " "PtrList::read(Istream&) : "
"reading entry" "reading entry"
); );
} }
} }
else else
{ {
T* tPtr = inewt(is).ptr(); T* p = inew(is).ptr();
set(0, tPtr); set(0, p);
is.fatalCheck is.fatalCheck
( (
"PtrList<T>::read(Istream&, const INew&) : " "PtrList::read(Istream&) : "
"reading the single entry" "reading the single entry"
); );
for (label i=1; i<sz; ++i) for (label i=1; i<len; ++i)
{ {
set(i, tPtr->clone()); set(i, p->clone());
} }
} }
} }
// Read end of contents // Read end of contents
is.readEndList("PtrList"); is.readEndList("PtrList");
return;
} }
else if (firstToken.isPunctuation())
// "(...)" : read as SLList and transfer contents
if (firstToken.isPunctuation())
{ {
if (firstToken.pToken() != token::BEGIN_LIST) if (firstToken.pToken() != token::BEGIN_LIST)
{ {
@ -125,32 +133,33 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
<< exit(FatalIOError); << exit(FatalIOError);
} }
sllPtrs.append(inewt(is).ptr()); sllPtrs.append(inew(is).ptr());
is >> lastToken; is >> lastToken;
} }
setSize(sllPtrs.size()); setSize(sllPtrs.size());
// Pointers - can simply copy
label i = 0; label i = 0;
for for
( (
typename SLList<T*>::iterator iter = sllPtrs.begin(); typename SLList<T*>::const_iterator iter = sllPtrs.cbegin();
iter != sllPtrs.end(); iter != sllPtrs.cend();
++iter ++iter
) )
{ {
set(i++, iter()); set(i++, *iter);
} }
return;
} }
else
{ FatalIOErrorInFunction
FatalIOErrorInFunction (
( is
is ) << "incorrect first token, expected <int> or '(', found "
) << "incorrect first token, expected <int> or '(', found " << firstToken.info()
<< firstToken.info() << exit(FatalIOError);
<< exit(FatalIOError);
}
} }
@ -158,9 +167,9 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
template<class T> template<class T>
template<class INew> template<class INew>
Foam::PtrList<T>::PtrList(Istream& is, const INew& inewt) Foam::PtrList<T>::PtrList(Istream& is, const INew& inew)
{ {
read(is, inewt); read(is, inew);
} }
@ -174,10 +183,10 @@ Foam::PtrList<T>::PtrList(Istream& is)
// * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Istream Operator * * * * * * * * * * * * * //
template<class T> template<class T>
Foam::Istream& Foam::operator>>(Istream& is, PtrList<T>& L) Foam::Istream& Foam::operator>>(Istream& is, PtrList<T>& lst)
{ {
L.clear(); lst.clear();
L.read(is, INew<T>()); lst.read(is, INew<T>());
return is; return is;
} }

View File

@ -39,16 +39,16 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
{ {
const UIndirectList<T>& L = *this; const UIndirectList<T>& L = *this;
const label sz = L.size(); const label len = L.size();
// Write list contents depending on data format // Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>()) if (os.format() == IOstream::ASCII || !contiguous<T>())
{ {
// Can the contents be considered 'uniform' (ie, identical)? // Can the contents be considered 'uniform' (ie, identical)?
bool uniform = (sz > 1 && contiguous<T>()); bool uniform = (len > 1 && contiguous<T>());
if (uniform) if (uniform)
{ {
for (label i=1; i < sz; ++i) for (label i=1; i < len; ++i)
{ {
if (L[i] != L[0]) if (L[i] != L[0])
{ {
@ -61,7 +61,7 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
if (uniform) if (uniform)
{ {
// Size and start delimiter // Size and start delimiter
os << sz << token::BEGIN_BLOCK; os << len << token::BEGIN_BLOCK;
// Contents // Contents
os << L[0]; os << L[0];
@ -71,15 +71,15 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
} }
else if else if
( (
sz <= 1 || !shortListLen len <= 1 || !shortListLen
|| (sz <= shortListLen && contiguous<T>()) || (len <= shortListLen && contiguous<T>())
) )
{ {
// Size and start delimiter // Size and start delimiter
os << sz << token::BEGIN_LIST; os << len << token::BEGIN_LIST;
// Contents // Contents
for (label i=0; i < sz; ++i) for (label i=0; i < len; ++i)
{ {
if (i) os << token::SPACE; if (i) os << token::SPACE;
os << L[i]; os << L[i];
@ -91,10 +91,10 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
else else
{ {
// Size and start delimiter // Size and start delimiter
os << nl << sz << nl << token::BEGIN_LIST << nl; os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents // Contents
for (label i=0; i < sz; ++i) for (label i=0; i < len; ++i)
{ {
os << L[i] << nl; os << L[i] << nl;
} }
@ -106,16 +106,16 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
else else
{ {
// Contents are binary and contiguous // Contents are binary and contiguous
os << nl << sz << nl; os << nl << len << nl;
if (sz) if (len)
{ {
// The TOTAL number of bytes to be written. // The TOTAL number of bytes to be written.
// - possibly add start delimiter // - possibly add start delimiter
os.beginRaw(sz*sizeof(T)); os.beginRaw(len*sizeof(T));
// Contents // Contents
for (label i=0; i < sz; ++i) for (label i=0; i < len; ++i)
{ {
os.writeRaw os.writeRaw
( (

View File

@ -63,9 +63,9 @@ Foam::labelRange Foam::UList<T>::validateRange
auto iter = start_size.begin(); auto iter = start_size.begin();
const label beg = *(iter++); const label beg = *(iter++);
const label sz = *iter; const label len = *iter;
return this->validateRange(labelRange(beg, sz)); return this->validateRange(labelRange(beg, len));
} }

View File

@ -76,16 +76,16 @@ Foam::Ostream& Foam::UList<T>::writeList
{ {
const UList<T>& L = *this; const UList<T>& L = *this;
const label sz = L.size(); const label len = L.size();
// Write list contents depending on data format // Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>()) if (os.format() == IOstream::ASCII || !contiguous<T>())
{ {
// Can the contents be considered 'uniform' (ie, identical)? // Can the contents be considered 'uniform' (ie, identical)?
bool uniform = (sz > 1 && contiguous<T>()); bool uniform = (len > 1 && contiguous<T>());
if (uniform) if (uniform)
{ {
for (label i=1; i < sz; ++i) for (label i=1; i < len; ++i)
{ {
if (L[i] != L[0]) if (L[i] != L[0])
{ {
@ -98,7 +98,7 @@ Foam::Ostream& Foam::UList<T>::writeList
if (uniform) if (uniform)
{ {
// Size and start delimiter // Size and start delimiter
os << sz << token::BEGIN_BLOCK; os << len << token::BEGIN_BLOCK;
// Contents // Contents
os << L[0]; os << L[0];
@ -108,15 +108,15 @@ Foam::Ostream& Foam::UList<T>::writeList
} }
else if else if
( (
sz <= 1 || !shortListLen len <= 1 || !shortListLen
|| (sz <= shortListLen && contiguous<T>()) || (len <= shortListLen && contiguous<T>())
) )
{ {
// Size and start delimiter // Size and start delimiter
os << sz << token::BEGIN_LIST; os << len << token::BEGIN_LIST;
// Contents // Contents
for (label i=0; i < sz; ++i) for (label i=0; i < len; ++i)
{ {
if (i) os << token::SPACE; if (i) os << token::SPACE;
os << L[i]; os << L[i];
@ -128,10 +128,10 @@ Foam::Ostream& Foam::UList<T>::writeList
else else
{ {
// Size and start delimiter // Size and start delimiter
os << nl << sz << nl << token::BEGIN_LIST << nl; os << nl << len << nl << token::BEGIN_LIST << nl;
// Contents // Contents
for (label i=0; i < sz; ++i) for (label i=0; i < len; ++i)
{ {
os << L[i] << nl; os << L[i] << nl;
} }
@ -143,9 +143,9 @@ Foam::Ostream& Foam::UList<T>::writeList
else else
{ {
// Contents are binary and contiguous // Contents are binary and contiguous
os << nl << sz << nl; os << nl << len << nl;
if (sz) if (len)
{ {
// write(...) includes surrounding start/end delimiters // write(...) includes surrounding start/end delimiters
os.write os.write
@ -171,14 +171,18 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const UList<T>& lst)
template<class T> template<class T>
Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L) Foam::Istream& Foam::operator>>(Istream& is, UList<T>& lst)
{ {
// The target list length - must match with sizes read
const label len = lst.size();
is.fatalCheck(FUNCTION_NAME); is.fatalCheck(FUNCTION_NAME);
token firstToken(is); token firstToken(is);
is.fatalCheck("operator>>(Istream&, UList<T>&) : reading first token"); is.fatalCheck("operator>>(Istream&, UList<T>&) : reading first token");
// Compound: simply transfer contents
if (firstToken.isCompound()) if (firstToken.isCompound())
{ {
List<T> elems; List<T> elems;
@ -189,31 +193,38 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
firstToken.transferCompoundToken(is) firstToken.transferCompoundToken(is)
) )
); );
// Check list length
const label sz = elems.size();
if (sz != L.size()) const label inputLen = elems.size();
// List lengths must match
if (inputLen != len)
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "incorrect length for UList. Read " << sz << "incorrect length for UList. Read "
<< " expected " << L.size() << inputLen << " expected " << len
<< exit(FatalIOError); << exit(FatalIOError);
} }
for (label i=0; i<sz; ++i)
{
L[i] = elems[i];
}
}
else if (firstToken.isLabel())
{
const label sz = firstToken.labelToken();
// Set list length to that read for (label i = 0; i < len; ++i)
if (sz != L.size()) {
lst[i] = std::move(elems[i]);
}
return is;
}
// Label: could be int(..), int{...} or just a plain '0'
if (firstToken.isLabel())
{
const label inputLen = firstToken.labelToken();
// List lengths must match
if (inputLen != len)
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "incorrect length for UList. Read " << sz << "incorrect length for UList. Read "
<< " expected " << L.size() << inputLen << " expected " << len
<< exit(FatalIOError); << exit(FatalIOError);
} }
@ -224,13 +235,13 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("List"); const char delimiter = is.readBeginList("List");
if (sz) if (len)
{ {
if (delimiter == token::BEGIN_LIST) if (delimiter == token::BEGIN_LIST)
{ {
for (label i=0; i<sz; ++i) for (label i=0; i<len; ++i)
{ {
is >> L[i]; is >> lst[i];
is.fatalCheck is.fatalCheck
( (
@ -251,9 +262,9 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
"reading the single entry" "reading the single entry"
); );
for (label i=0; i<sz; ++i) for (label i=0; i<len; ++i)
{ {
L[i] = element; lst[i] = element; // Copy the value
} }
} }
} }
@ -261,22 +272,24 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
// Read end of contents // Read end of contents
is.readEndList("List"); is.readEndList("List");
} }
else else if (len)
{ {
// contents are binary and contiguous // Non-empty, binary, contiguous
if (sz) is.read(reinterpret_cast<char*>(lst.data()), len*sizeof(T));
{
is.read(reinterpret_cast<char*>(L.data()), sz*sizeof(T));
is.fatalCheck is.fatalCheck
( (
"operator>>(Istream&, UList<T>&) : reading the binary block" "operator>>(Istream&, UList<T>&) : reading the binary block"
); );
}
} }
return is;
} }
else if (firstToken.isPunctuation())
// "(...)" : read as SLList and transfer contents
if (firstToken.isPunctuation())
{ {
if (firstToken.pToken() != token::BEGIN_LIST) if (firstToken.pToken() != token::BEGIN_LIST)
{ {
@ -286,40 +299,33 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
<< exit(FatalIOError); << exit(FatalIOError);
} }
// Putback the opening bracket is.putBack(firstToken); // Putback the opening bracket
is.putBack(firstToken);
// Now read as a singly-linked list SLList<T> sll(is); // Read as singly-linked list
SLList<T> sll(is);
if (sll.size() != L.size()) // List lengths must match
if (sll.size() != len)
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "incorrect length for UList. Read " << sll.size() << "incorrect length for UList. Read "
<< " expected " << L.size() << sll.size() << " expected " << len
<< exit(FatalIOError); << exit(FatalIOError);
} }
// Convert the singly-linked list to this list // Move assign each list element
label i = 0; for (label i = 0; i < len; ++i)
for
(
typename SLList<T>::const_iterator iter = sll.begin();
iter != sll.end();
++iter, ++i
)
{ {
L[i] = iter(); lst[i] = std::move(sll.removeHead());
} }
return is;
} }
else
{
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "incorrect first token, expected <int> or '(', found " << "incorrect first token, expected <int> or '(', found "
<< firstToken.info() << firstToken.info()
<< exit(FatalIOError); << exit(FatalIOError);
}
return is; return is;
} }

View File

@ -29,18 +29,18 @@ License
// * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
template<class T> template<class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& L) Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& lst)
{ {
const label sz = L.size(); const label len = lst.size();
// Size and start delimiter // Size and start delimiter
os << nl << indent << sz << nl os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl; << indent << token::BEGIN_LIST << incrIndent << nl;
// Contents // Contents
for (label i=0; i < sz; ++i) for (label i=0; i < len; ++i)
{ {
os << L[i] << nl; os << lst[i] << nl;
} }
// End delimiter // End delimiter

View File

@ -89,8 +89,8 @@ readField
{ {
for for
( (
IDLList<entry>::const_reverse_iterator iter = dict.rbegin(); IDLList<entry>::const_reverse_iterator iter = dict.crbegin();
iter != dict.rend(); iter != dict.crend();
++iter ++iter
) )
{ {