ENH: support ASCII List output on a single-line

- Introduce writeList(Ostream&, label) method in various List classes to
  provide more flexibility and avoid hard-coded limits when deciding if a
  list is too long and should be broken up into multiple lines (ASCII only).

- The old hard-code limit (10) is retained in the operator<< versions

- This functionality is wrapped in the FlatOutput output adapter class
  and directly accessible via the 'flatOutput()' function.

Eg,
    #include "ListOps.H"
    Info<< "methods: " << flatOutput(myLongList) << endl;

    // OR

    Info<< "methods: ";
    myLongList.writeList(os) << endl;
This commit is contained in:
Mark Olesen
2017-02-10 09:55:37 +01:00
parent 285442776c
commit e3d9084c62
12 changed files with 325 additions and 146 deletions

View File

@ -40,7 +40,6 @@ See also
#include "IStringStream.H" #include "IStringStream.H"
#include "scalar.H" #include "scalar.H"
#include "vector.H" #include "vector.H"
#include "ListOps.H"
#include "labelRange.H" #include "labelRange.H"
#include "ListOps.H" #include "ListOps.H"
@ -140,11 +139,36 @@ int main(int argc, char *argv[])
Info<< "Elements " << map << " out of " << list3 Info<< "Elements " << map << " out of " << list3
<< " => " << subList3 << endl; << " => " << subList3 << endl;
// test flattened output
{
Info<< nl;
labelList longLabelList = identity(15);
Info<< "labels (contiguous=" << contiguous<label>() << ")" << nl;
Info<< "normal: " << longLabelList << nl;
Info<< "flatOutput: " << flatOutput(longLabelList) << nl;
// Info<< "flatOutput(14): " << flatOutput(longLabelList, 14) << nl;
// Info<< "flatOutput(15): " << flatOutput(longLabelList, 15) << nl;
stringList longStringList(12);
forAll(longStringList, i)
{
longStringList[i].resize(3, 'a' + i);
}
Info<< "string (contiguous=" << contiguous<string>() << ")" << nl;
Info<< "normal: " << longStringList << nl;
Info<< "flatOutput: " << flatOutput(longStringList) << nl;
// contiguous longStringList[i].resize(3, 'a' + i);
}
wordReList reLst; wordReList reLst;
wordList wLst; wordList wLst;
stringList sLst; stringList sLst;
scalar xxx(-1); scalar xxx(-1);
if (args.optionFound("flag")) if (args.optionFound("flag"))
@ -173,9 +197,9 @@ int main(int argc, char *argv[])
} }
Info<< nl Info<< nl
<< "-reList: " << reLst << nl << "-reList: " << flatOutput(reLst) << nl
<< "-wordList: " << wLst << nl << "-wordList: " << flatOutput(wLst) << nl
<< "-stringList: " << sLst << endl; << "-stringList: " << flatOutput(sLst) << endl;
return 0; return 0;
} }

View File

@ -143,7 +143,7 @@ int main(int argc, char *argv[])
Info<< "\ntest Istream constructor\n"; Info<< "\ntest Istream constructor\n";
list4.printInfo(Info, true); list4.printInfo(Info, true);
Info<< list4 << " indices: " << list4.used()() <<endl; Info<< list4 << " indices: " << list4.used()() << nl;
Info<< "\nassign from labelList\n"; Info<< "\nassign from labelList\n";
list4 = labelList list4 = labelList
@ -155,7 +155,7 @@ int main(int argc, char *argv[])
); );
list4.printInfo(Info, true); list4.printInfo(Info, true);
Info<< list4 << " indices: " << list4.used()() <<endl; Info<< list4 << " indices: " << list4.used()() << nl;
Info<< "\nassign from indices\n"; Info<< "\nassign from indices\n";
list4.read list4.read
@ -168,7 +168,7 @@ int main(int argc, char *argv[])
list4.printInfo(Info, true); list4.printInfo(Info, true);
Info<< list4 << " indices: " << list4.used()() <<endl; Info<< list4 << " indices: " << list4.used()() << nl;
List<bool> boolLst(list4.size()); List<bool> boolLst(list4.size());
forAll(list4, i) forAll(list4, i)
@ -176,8 +176,7 @@ int main(int argc, char *argv[])
boolLst[i] = list4[i]; boolLst[i] = list4[i];
} }
Info<< "List<bool>: " << boolLst <<endl; Info<< "List<bool>: " << boolLst << nl;
// check roundabout assignments // check roundabout assignments
PackedList<2> pl2 PackedList<2> pl2
@ -188,7 +187,7 @@ int main(int argc, char *argv[])
)() )()
); );
Info<< "roundabout assignment: " << pl2 << endl; Info<< "roundabout assignment: " << pl2 << nl;
list4.clear(); list4.clear();
forAll(pl2, i) forAll(pl2, i)
@ -196,7 +195,7 @@ int main(int argc, char *argv[])
list4[i] = pl2[i]; list4[i] = pl2[i];
} }
list4.write(Info, true) << endl; list4.writeList(Info, -1) << nl; // indexed output
list4.writeEntry("PackedBoolList", Info); list4.writeEntry("PackedBoolList", Info);

View File

@ -364,6 +364,9 @@ public:
//- Write the List as a dictionary entry with keyword //- Write the List as a dictionary entry with keyword
void writeEntry(const word& keyword, Ostream& os) const; void writeEntry(const word& keyword, Ostream& os) const;
//- Write the List, with line-breaks in ASCII if the list length
// exceeds shortListLen. Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortListLen=0) const;
// IOstream operators // IOstream operators
@ -375,7 +378,7 @@ public:
FixedList<T, Size>& L FixedList<T, Size>& L
); );
//- Write FixedList to Ostream //- Write List to Ostream, as per writeList() with shortListLen=10
friend Ostream& operator<< <T, Size> friend Ostream& operator<< <T, Size>
( (
Ostream& os, Ostream& os,

View File

@ -60,6 +60,92 @@ void Foam::FixedList<T, Size>::writeEntry
} }
template<class T, unsigned Size>
Foam::Ostream& Foam::FixedList<T, Size>::writeList
(
Ostream& os,
const label shortListLen
) const
{
const FixedList<T, Size>& L = *this;
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>())
{
// Can the contents be considered 'uniform' (ie, identical)?
bool uniform = (Size > 1 && contiguous<T>());
if (uniform)
{
forAll(L, i)
{
if (L[i] != L[0])
{
uniform = false;
break;
}
}
}
if (uniform)
{
// Write size (so it is valid dictionary entry) and start delimiter
os << Size << token::BEGIN_BLOCK;
// Write contents
os << L[0];
// Write end delimiter
os << token::END_BLOCK;
}
else if
(
Size <= 1 || !shortListLen
|| (Size <= shortListLen && contiguous<T>())
)
{
// Write start delimiter
os << token::BEGIN_LIST;
// Write contents
forAll(L, i)
{
if (i) os << token::SPACE;
os << L[i];
}
// Write end delimiter
os << token::END_LIST;
}
else
{
// Write start delimiter
os << nl << token::BEGIN_LIST << nl;
// Write contents
forAll(L, i)
{
os << L[i] << nl;
}
// Write end delimiter
os << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
// write(...) includes surrounding start/end delimiters
os.write(reinterpret_cast<const char*>(L.cdata()), Size*sizeof(T));
}
// Check state of IOstream
os.check("const FixedList::writeList(Ostream&)");
return os;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class T, unsigned Size> template<class T, unsigned Size>
@ -164,81 +250,10 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
} }
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
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>& L)
{ {
// Write list contents depending on data format return L.writeList(os, 10);
if (os.format() == IOstream::ASCII || !contiguous<T>())
{
// Can the contents be considered 'uniform' (ie, identical)?
bool uniform = (Size > 1 && contiguous<T>());
if (uniform)
{
forAll(L, i)
{
if (L[i] != L[0])
{
uniform = false;
break;
}
}
}
if (uniform)
{
// Write size (so it is valid dictionary entry) and start delimiter
os << L.size() << token::BEGIN_BLOCK;
// Write contents
os << L[0];
// Write end delimiter
os << token::END_BLOCK;
}
else if (Size <= 1 || (Size < 11 && contiguous<T>()))
{
// Write start delimiter
os << token::BEGIN_LIST;
// Write contents
forAll(L, i)
{
if (i) os << token::SPACE;
os << L[i];
}
// Write end delimiter
os << token::END_LIST;
}
else
{
// Write start delimiter
os << nl << token::BEGIN_LIST;
// Write contents
forAll(L, i)
{
os << nl << L[i];
}
// Write end delimiter
os << nl << token::END_LIST << nl;
}
}
else
{
// Contents are binary and contiguous
// write(...) includes surrounding start/end delimiters
os.write(reinterpret_cast<const char*>(L.cdata()), Size*sizeof(T));
}
// Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const FixedList&)");
return os;
} }

View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::FlatOutput
Description
Simple output adapter for list output on a single line.
The backend type must support a two-argument \c writeList() method.
\*---------------------------------------------------------------------------*/
#ifndef FlatOutput_H
#define FlatOutput_H
#include "Ostream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class Container> class FlatOutput;
template<class Container>
Ostream& operator<<(Ostream& os, const FlatOutput<Container>& obj);
/*---------------------------------------------------------------------------*\
Class FlatOutput Declaration
\*---------------------------------------------------------------------------*/
template<class Container>
class FlatOutput
{
const Container& ref_;
const label len_;
public:
//- Construct from components
inline FlatOutput(const Container& obj, label len)
:
ref_(obj),
len_(len)
{}
//- Ostream operator
inline friend Ostream& operator<<
(
Ostream& os,
const FlatOutput<Container>& wrapped
)
{
return wrapped.ref_.writeList(os, wrapped.len_);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Global flatOutput function
template<class Container>
FlatOutput<Container> flatOutput(const Container& obj, label len=0)
{
return FlatOutput<Container>(obj, len);
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#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,6 +36,7 @@ SourceFiles
#ifndef ListOps_H #ifndef ListOps_H
#define ListOps_H #define ListOps_H
#include "FlatOutput.H"
#include "labelList.H" #include "labelList.H"
#include "ops.H" #include "ops.H"

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.
@ -405,12 +405,13 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
template<unsigned nBits> template<unsigned nBits>
Foam::Ostream& Foam::PackedList<nBits>::write Foam::Ostream& Foam::PackedList<nBits>::writeList
( (
Ostream& os, Ostream& os,
const bool indexedOutput const label shortListLen
) const ) const
{ {
const bool indexedOutput = (shortListLen < 0);
const PackedList<nBits>& lst = *this; const PackedList<nBits>& lst = *this;
const label sz = lst.size(); const label sz = lst.size();
@ -456,36 +457,33 @@ Foam::Ostream& Foam::PackedList<nBits>::write
os << token::END_BLOCK << nl; os << token::END_BLOCK << nl;
} }
else if (sz < 11) else if (!shortListLen || sz <= shortListLen)
{ {
// short list: // Shorter list, or line-breaks suppressed
os << sz << token::BEGIN_LIST; os << sz << token::BEGIN_LIST;
forAll(lst, i) forAll(lst, i)
{ {
if (i) if (i) os << token::SPACE;
{
os << token::SPACE;
}
os << lst[i]; os << lst[i];
} }
os << token::END_LIST; os << token::END_LIST;
} }
else else
{ {
// longer list: // Longer list
os << nl << sz << nl << token::BEGIN_LIST; os << nl << sz << nl << token::BEGIN_LIST << nl;
forAll(lst, i) forAll(lst, i)
{ {
os << nl << lst[i]; os << lst[i] << nl;
} }
os << nl << token::END_LIST << nl; os << token::END_LIST << nl;
} }
} }
else else
{ {
// Contents are binary and contiguous // Contents are binary and contiguous
os << nl << sz << nl; os << nl << sz << nl;
if (sz) if (sz)
{ {
// write(...) includes surrounding start/end delimiters // write(...) includes surrounding start/end delimiters
@ -562,7 +560,7 @@ Foam::Istream& Foam::operator>>(Istream& is, PackedList<nBits>& lst)
template<unsigned nBits> template<unsigned nBits>
Foam::Ostream& Foam::operator<<(Ostream& os, const PackedList<nBits>& lst) Foam::Ostream& Foam::operator<<(Ostream& os, const PackedList<nBits>& lst)
{ {
return lst.write(os, false); return lst.writeList(os, 10);
} }

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.
@ -232,19 +232,19 @@ public:
inline PackedList(const label size, const unsigned val); inline PackedList(const label size, const unsigned val);
//- Construct from Istream //- Construct from Istream
inline PackedList(Istream&); inline PackedList(Istream& is);
//- Copy constructor //- Copy constructor
inline PackedList(const PackedList<nBits>&); inline PackedList(const PackedList<nBits>& lst);
//- Construct by transferring the parameter contents //- Construct by transferring the parameter contents
inline PackedList(const Xfer<PackedList<nBits>>&); inline PackedList(const Xfer<PackedList<nBits>>& lst);
//- Construct from a list of labels //- Construct from a list of labels
explicit inline PackedList(const labelUList&); explicit inline PackedList(const labelUList& lst);
//- Construct from an indirect list of labels //- Construct from an indirect list of labels
explicit inline PackedList(const UIndirectList<label>&); explicit inline PackedList(const UIndirectList<label>& lst);
//- Clone //- Clone
inline autoPtr<PackedList<nBits>> clone() const; inline autoPtr<PackedList<nBits>> clone() const;
@ -265,16 +265,16 @@ public:
//- Get value at index I. //- Get value at index I.
// Never auto-vivify entries. // Never auto-vivify entries.
inline unsigned int get(const label) const; inline unsigned int get(const label i) const;
//- Set value at index I. Return true if value changed. //- Set value at index I. Return true if value changed.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent entries.
// Default value set is the max_value. // Default value set is the max_value.
inline bool set(const label, const unsigned int val = ~0u); inline bool set(const label i, const unsigned int val = ~0u);
//- Unset the entry at index I. Return true if value changed. //- Unset the entry at index I. Return true if value changed.
// Never auto-vivify entries. // Never auto-vivify entries.
inline bool unset(const label); inline bool unset(const label i);
//- Return the underlying packed storage //- Return the underlying packed storage
// Manipulate with utmost caution // Manipulate with utmost caution
@ -364,7 +364,10 @@ public:
//- Clear list and read from stream //- Clear list and read from stream
Istream& read(Istream& is); Istream& read(Istream& is);
//- Write, optionally with indexedOutput //- Write the List, with line-breaks in ASCII if the list length
// exceeds shortListLen. Using '0' suppresses line-breaks entirely.
// A special indexed output (ASCII only) is triggered by specifying
// a negative value for shortListLen.
// //
// The indexed output may be convenient in some situations. // The indexed output may be convenient in some situations.
// The general format is a group of index/value pairs: // The general format is a group of index/value pairs:
@ -376,14 +379,7 @@ public:
// \verbatim // \verbatim
// { index1 index2 index3 } // { index1 index2 index3 }
// \endverbatim // \endverbatim
// Ostream& writeList(Ostream& os, const label shortListLen=0) const;
// Note the indexed output is only supported for ASCII streams.
Ostream& write
(
Ostream& os,
const bool indexedOutput=false
) const;
//- Write as a dictionary entry with keyword //- Write as a dictionary entry with keyword
void writeEntry(const word& keyword, Ostream& os) const; void writeEntry(const word& keyword, Ostream& os) const;
@ -399,24 +395,24 @@ public:
//- Get value at index I //- Get value at index I
// Never auto-vivify entries. // Never auto-vivify entries.
inline unsigned int operator[](const label) const; inline unsigned int operator[](const label i) const;
//- Set value at index I. //- Set value at index I.
// Returns iterator to perform the actual operation. // Returns iterator to perform the actual operation.
// Does not auto-vivify entries, but will when assigned to. // Does not auto-vivify entries, but will when assigned to.
inline iteratorBase operator[](const label); inline iteratorBase operator[](const label i);
//- Assignment of all entries to the given value. Takes linear time. //- Assignment of all entries to the given value. Takes linear time.
inline void operator=(const unsigned int val); inline void operator=(const unsigned int val);
//- Assignment operator. //- Assignment operator.
void operator=(const PackedList<nBits>&); void operator=(const PackedList<nBits>& lst);
//- Assignment operator. //- Assignment operator.
void operator=(const labelUList&); void operator=(const labelUList& lst);
//- Assignment operator. //- Assignment operator.
void operator=(const UIndirectList<label>&); void operator=(const UIndirectList<label>& lst);
// Iterators and helpers // Iterators and helpers

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.
@ -148,9 +148,17 @@ public:
typedef label size_type; typedef label size_type;
// Writing
//- Write the List, with line-breaks in ASCII if the list length
// exceeds shortListLen. Using '0' suppresses line-breaks entirely.
// Binary output is currently still a bit of an annoyance.
Ostream& writeList(Ostream& os, const label shortListLen=0) const;
// Ostream operator // Ostream operator
//- Write List to Ostream, as per write() method with shortListLen=10 //- Write List to Ostream, as per writeList() with shortListLen=10
friend Ostream& operator<< <T> friend Ostream& operator<< <T>
( (
Ostream& os, Ostream& os,

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-2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,15 +28,17 @@ License
#include "token.H" #include "token.H"
#include "contiguous.H" #include "contiguous.H"
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class T> template<class T>
Foam::Ostream& Foam::operator<< Foam::Ostream& Foam::UIndirectList<T>::writeList
( (
Foam::Ostream& os, Ostream& os,
const Foam::UIndirectList<T>& L const label shortListLen
) ) const
{ {
const UIndirectList<T>& L = *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>())
{ {
@ -65,7 +67,11 @@ Foam::Ostream& Foam::operator<<
// Write end delimiter // Write end delimiter
os << token::END_BLOCK; os << token::END_BLOCK;
} }
else if (L.size() <= 1 || (L.size() < 11 && contiguous<T>())) else if
(
L.size() <= 1 || !shortListLen
|| (L.size() <= shortListLen && contiguous<T>())
)
{ {
// Write size and start delimiter // Write size and start delimiter
os << L.size() << token::BEGIN_LIST; os << L.size() << token::BEGIN_LIST;
@ -83,16 +89,16 @@ Foam::Ostream& Foam::operator<<
else else
{ {
// Write size and start delimiter // Write size and start delimiter
os << nl << L.size() << nl << token::BEGIN_LIST; os << nl << L.size() << nl << token::BEGIN_LIST << nl;
// Write contents // Write contents
forAll(L, i) forAll(L, i)
{ {
os << nl << L[i]; os << L[i] << nl;
} }
// Write end delimiter // Write end delimiter
os << nl << token::END_LIST << nl; os << token::END_LIST << nl;
} }
} }
else else
@ -115,10 +121,23 @@ Foam::Ostream& Foam::operator<<
} }
// Check state of IOstream // Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const UIndirectList&)"); os.check("UIndirectList::writeList(Ostream&)");
return os; return os;
} }
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class T>
Foam::Ostream& Foam::operator<<
(
Foam::Ostream& os,
const Foam::UIndirectList<T>& L
)
{
return L.writeList(os, 10);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -372,11 +372,14 @@ public:
//- Write the List as a dictionary entry with keyword //- Write the List as a dictionary entry with keyword
void writeEntry(const word& keyword, Ostream& os) const; void writeEntry(const word& keyword, Ostream& os) const;
//- Write the List, with line-breaks in ASCII if the list length
// exceeds shortListLen. Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortListLen=0) const;
// IOstream operators // IOstream operators
//- Write List to Ostream, as per write() method with shortListLen=10 //- Write List to Ostream, as per writeList() with shortListLen=10
friend Ostream& operator<< <T> friend Ostream& operator<< <T>
( (
Ostream& os, Ostream& os,

View File

@ -67,11 +67,15 @@ void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
} }
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class T> template<class T>
Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L) Foam::Ostream& Foam::UList<T>::writeList
(
Ostream& os,
const label shortListLen
) const
{ {
const UList<T>& L = *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>())
{ {
@ -100,7 +104,11 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
// Write end delimiter // Write end delimiter
os << token::END_BLOCK; os << token::END_BLOCK;
} }
else if (L.size() <= 1 || (L.size() < 11 && contiguous<T>())) else if
(
L.size() <= 1 || !shortListLen
|| (L.size() <= shortListLen && contiguous<T>())
)
{ {
// Write size and start delimiter // Write size and start delimiter
os << L.size() << token::BEGIN_LIST; os << L.size() << token::BEGIN_LIST;
@ -118,16 +126,16 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
else else
{ {
// Write size and start delimiter // Write size and start delimiter
os << nl << L.size() << nl << token::BEGIN_LIST; os << nl << L.size() << nl << token::BEGIN_LIST << nl;
// Write contents // Write contents
forAll(L, i) forAll(L, i)
{ {
os << nl << L[i]; os << L[i] << nl;
} }
// Write end delimiter // Write end delimiter
os << nl << token::END_LIST << nl; os << token::END_LIST << nl;
} }
} }
else else
@ -143,12 +151,21 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
} }
// Check state of IOstream // Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const UList&)"); os.check("UList<T>::writeList(Ostream&)");
return os; return os;
} }
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class T>
Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
{
return L.writeList(os, 10);
}
template<class T> template<class T>
Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L) Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
{ {