ENH: improve flexiblity for flat output of items (#1929)
- change to a templated implementation instead of relying on the container's writeList() method. This inlines the generation while also adding the flexibility to define different delimiters (at compile time) without the performance penalty of passing run-time parameters.
This commit is contained in:
parent
d2f1690536
commit
0de32a6e6f
3
applications/test/flatOutput1/Make/files
Normal file
3
applications/test/flatOutput1/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-flatOuput1.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-flatOuput1
|
2
applications/test/flatOutput1/Make/options
Normal file
2
applications/test/flatOutput1/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
103
applications/test/flatOutput1/Test-flatOuput1.C
Normal file
103
applications/test/flatOutput1/Test-flatOuput1.C
Normal file
@ -0,0 +1,103 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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/>.
|
||||
|
||||
Description
|
||||
Simple test of FlatOutput
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "wordList.H"
|
||||
#include "ListOps.H"
|
||||
#include "FlatOutput.H"
|
||||
#include "IOstreams.H"
|
||||
#include "macros.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// For testing various pre-defined formatting
|
||||
#define printFlatOutput(Content, Format) \
|
||||
STRINGIFY(Format) << ": " << flatOutput(Content, FlatOutput::Format{})
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
wordList words1
|
||||
{
|
||||
"ab", "cd", "ef", "gh",
|
||||
"ij", "kl", "mn", "op",
|
||||
"qr", "st", "uv", "wx", "yz"
|
||||
};
|
||||
|
||||
{
|
||||
Info<< nl
|
||||
<< "regular" << nl
|
||||
<< "#----------------" << nl;
|
||||
|
||||
Info<< nl << "operator<< " << words1 << nl;
|
||||
|
||||
Info<< nl << "writeList: ";
|
||||
words1.writeList(Info) << nl;
|
||||
}
|
||||
|
||||
Info<< nl
|
||||
<< "Using c++ " << int(__cplusplus) << nl;
|
||||
|
||||
{
|
||||
Info<< nl
|
||||
<< "flatOutput" << nl
|
||||
<< "#----------------" << nl;
|
||||
|
||||
Info<< nl << "operator<< " << flatOutput(words1) << nl;
|
||||
|
||||
Info<< nl << "write: ";
|
||||
flatOutput(words1).write(Info) << nl;
|
||||
|
||||
Info<< nl << printFlatOutput(words1, BareComma) << nl;
|
||||
Info<< nl << printFlatOutput(words1, BareSpace) << nl;
|
||||
|
||||
Info<< nl << printFlatOutput(words1, BraceComma) << nl;
|
||||
Info<< nl << printFlatOutput(words1, BraceSpace) << nl;
|
||||
|
||||
Info<< nl << printFlatOutput(words1, ParenComma) << nl;
|
||||
Info<< nl << printFlatOutput(words1, ParenSpace) << nl;
|
||||
|
||||
Info<< nl << printFlatOutput(words1, PointyComma) << nl;
|
||||
Info<< nl << printFlatOutput(words1, PointySpace) << nl;
|
||||
|
||||
Info<< nl << printFlatOutput(words1, SquareComma) << nl;
|
||||
Info<< nl << printFlatOutput(words1, SquareSpace) << nl;
|
||||
}
|
||||
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -1,98 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
// ************************************************************************* //
|
247
src/OpenFOAM/db/IOstreams/output/FlatOutput.H
Normal file
247
src/OpenFOAM/db/IOstreams/output/FlatOutput.H
Normal file
@ -0,0 +1,247 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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/>.
|
||||
|
||||
Namespace
|
||||
Foam::FlatOutput
|
||||
|
||||
Description
|
||||
Various output adaptors, principally to output a list of items
|
||||
on a single line.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FlatOutput_H
|
||||
#define FlatOutput_H
|
||||
|
||||
#include "Ostream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace FlatOutput
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
template<class Container, class Delimiters> class OutputAdaptor;
|
||||
|
||||
} // End namespace FlatOutput
|
||||
|
||||
|
||||
// Forward Declarations
|
||||
template<class Container, class Delimiters>
|
||||
inline Ostream& operator<<
|
||||
(
|
||||
Ostream&,
|
||||
const FlatOutput::OutputAdaptor<Container, Delimiters>&
|
||||
);
|
||||
|
||||
|
||||
namespace FlatOutput
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Decorators Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- List decorators with \c open, \c close and \c separator characters
|
||||
template<char OpenChar, char CloseChar, char SepChar>
|
||||
struct Decorators
|
||||
{
|
||||
static constexpr char open = OpenChar;
|
||||
static constexpr char close = CloseChar;
|
||||
static constexpr char separator = SepChar;
|
||||
};
|
||||
|
||||
|
||||
#undef makeDecorator
|
||||
#define makeDecorator(Name, Open, Close, Sep) \
|
||||
/*! \brief Surround with \c Open and \c Close separate with \c Sep */ \
|
||||
struct Name : public Decorators<Open, Close, Sep> {};
|
||||
|
||||
makeDecorator(BareComma, '\0','\0', ',');
|
||||
makeDecorator(BareSpace, '\0','\0', ' ');
|
||||
|
||||
makeDecorator(BraceComma, '{','}', ',');
|
||||
makeDecorator(BraceSpace, '{','}', ' ');
|
||||
|
||||
makeDecorator(ParenComma, '(',')', ',');
|
||||
makeDecorator(ParenSpace, '(',')', ' '); // Normal default
|
||||
|
||||
makeDecorator(PointyComma, '<','>', ',');
|
||||
makeDecorator(PointySpace, '<','>', ' ');
|
||||
|
||||
makeDecorator(SquareComma,'[',']', ',');
|
||||
makeDecorator(SquareSpace,'[',']', ' ');
|
||||
|
||||
#undef makeDecorator
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class OutputAdaptor Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
//- An output adaptor with a write method and an Ostream operator.
|
||||
//
|
||||
// Generate single line (flat) output using the characters specified by
|
||||
// the templated Delimiters.
|
||||
// Normally called with the global flatOutput() function.
|
||||
// For example,
|
||||
// \code
|
||||
//
|
||||
// /* With default parenthesis/space delimiters */
|
||||
// Info<< "Names: " << flatOutput(names) << nl;
|
||||
//
|
||||
// /* Other delimiters */
|
||||
// Info<< flatOutput(names, FlatOutput::SquareComma{}) << nl;
|
||||
//
|
||||
// /* User-specified delimiters */
|
||||
// Info<< flatOutput(names, FlatOutput::Decorators<'[',')',':'>{}) << nl;
|
||||
//
|
||||
// \endcode
|
||||
//
|
||||
// \noop
|
||||
template<class Container, class Delimiters>
|
||||
class OutputAdaptor
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The container of values for output
|
||||
const Container& values;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from component
|
||||
explicit OutputAdaptor(const Container& obj)
|
||||
:
|
||||
values(obj)
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Write list using \c open, \c close and \c separator characters
|
||||
//- specified by Delimiters template, which generally results in
|
||||
//- a single line without line breaks.
|
||||
//
|
||||
// \note Suppresses nul char output.
|
||||
// No special handling for newline separators.
|
||||
inline Ostream& write(Ostream& os) const
|
||||
{
|
||||
bool started = false;
|
||||
|
||||
// In c++17, can use constexpr if
|
||||
|
||||
if (Delimiters::open)
|
||||
{
|
||||
os << Delimiters::open;
|
||||
}
|
||||
for (const auto& item : values)
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
if (Delimiters::separator)
|
||||
{
|
||||
os << Delimiters::separator;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
started = true;
|
||||
}
|
||||
os << item;
|
||||
}
|
||||
if (Delimiters::close)
|
||||
{
|
||||
os << Delimiters::close;
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// Operators
|
||||
|
||||
//- Ostream Operator
|
||||
inline friend Ostream&
|
||||
operator<<
|
||||
(
|
||||
Ostream& os,
|
||||
const OutputAdaptor<Container, Delimiters>& adaptor
|
||||
)
|
||||
{
|
||||
return adaptor.write(os);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace FlatOutput
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
//- Global flatOutput() function with specified output delimiters
|
||||
template<class Container, class Delimiters>
|
||||
inline FlatOutput::OutputAdaptor<Container, Delimiters>
|
||||
flatOutput
|
||||
(
|
||||
const Container& obj,
|
||||
Delimiters delim
|
||||
)
|
||||
{
|
||||
return FlatOutput::OutputAdaptor<Container, Delimiters>(obj);
|
||||
}
|
||||
|
||||
|
||||
//- Global flatOutput() function with default (parenthesis/space) delimiters
|
||||
template<class Container>
|
||||
inline FlatOutput::OutputAdaptor<Container, FlatOutput::ParenSpace>
|
||||
flatOutput
|
||||
(
|
||||
const Container& obj
|
||||
)
|
||||
{
|
||||
return FlatOutput::OutputAdaptor<Container, FlatOutput::ParenSpace>(obj);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -348,10 +348,26 @@ Foam::simpleObjectRegistry& Foam::debug::dimensionedConstantObjects()
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Print the switch status
|
||||
static inline void printStatus
|
||||
(
|
||||
const char * const message,
|
||||
const wordList& list
|
||||
)
|
||||
{
|
||||
// Use writeList with length = -1 to ensure we always have newlines,
|
||||
// even for short lists
|
||||
|
||||
Info<< message << nl;
|
||||
list.writeList(Info, -1) << nl;
|
||||
}
|
||||
|
||||
|
||||
// Write the switch names.
|
||||
//
|
||||
// Use flatOutput with -1 for the length to ensure we always have newlines,
|
||||
// Use writeList with -1 for the length to ensure we always have newlines,
|
||||
// even if the lists are short
|
||||
|
||||
static void listSwitches
|
||||
(
|
||||
const wordList& debugSwitches,
|
||||
@ -373,7 +389,7 @@ static void listSwitches
|
||||
controlDict.merge(dictionary(is));
|
||||
}
|
||||
|
||||
// Use a HashSet to track switches that have not been set
|
||||
// HashSet to track switches that have not been set
|
||||
wordHashSet hashed;
|
||||
|
||||
// DebugSwitches
|
||||
@ -381,9 +397,7 @@ static void listSwitches
|
||||
{
|
||||
hashed = debugSwitches;
|
||||
hashed.unset(controlDict.subDict("DebugSwitches").toc());
|
||||
|
||||
Info<< "Unset DebugSwitches"
|
||||
<< flatOutput(hashed.sortedToc(), -1) << nl;
|
||||
printStatus("Unset DebugSwitches", hashed.sortedToc());
|
||||
}
|
||||
|
||||
// InfoSwitches
|
||||
@ -391,9 +405,7 @@ static void listSwitches
|
||||
{
|
||||
hashed = infoSwitches;
|
||||
hashed.unset(controlDict.subDict("InfoSwitches").toc());
|
||||
|
||||
Info<< "Unset InfoSwitches"
|
||||
<< flatOutput(hashed.sortedToc(), -1) << nl;
|
||||
printStatus("Unset InfoSwitches", hashed.sortedToc());
|
||||
}
|
||||
|
||||
// OptimisationSwitches
|
||||
@ -401,9 +413,7 @@ static void listSwitches
|
||||
{
|
||||
hashed = optSwitches;
|
||||
hashed.unset(controlDict.subDict("OptimisationSwitches").toc());
|
||||
|
||||
Info<< "Unset OptimisationSwitches"
|
||||
<< flatOutput(hashed.sortedToc(), -1) << nl;
|
||||
printStatus("Unset OptimisationSwitches", hashed.sortedToc());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -411,22 +421,19 @@ static void listSwitches
|
||||
// DebugSwitches
|
||||
if (notNull(debugSwitches))
|
||||
{
|
||||
Info<< "DebugSwitches"
|
||||
<< flatOutput(debugSwitches, -1) << nl;
|
||||
printStatus("DebugSwitches", debugSwitches);
|
||||
}
|
||||
|
||||
// InfoSwitches
|
||||
if (notNull(infoSwitches))
|
||||
{
|
||||
Info<< "InfoSwitches"
|
||||
<< flatOutput(infoSwitches, -1) << nl;
|
||||
printStatus("InfoSwitches", infoSwitches);
|
||||
}
|
||||
|
||||
// OptimisationSwitches
|
||||
if (notNull(optSwitches))
|
||||
{
|
||||
Info<< "OptimisationSwitches"
|
||||
<< flatOutput(optSwitches, -1) << nl;
|
||||
printStatus("OptimisationSwitches", optSwitches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user