diff --git a/applications/test/flatOutput1/Make/files b/applications/test/flatOutput1/Make/files
new file mode 100644
index 0000000000..0179cbe0cc
--- /dev/null
+++ b/applications/test/flatOutput1/Make/files
@@ -0,0 +1,3 @@
+Test-flatOuput1.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-flatOuput1
diff --git a/applications/test/flatOutput1/Make/options b/applications/test/flatOutput1/Make/options
new file mode 100644
index 0000000000..18e6fe47af
--- /dev/null
+++ b/applications/test/flatOutput1/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = */
+/* EXE_LIBS = */
diff --git a/applications/test/flatOutput1/Test-flatOuput1.C b/applications/test/flatOutput1/Test-flatOuput1.C
new file mode 100644
index 0000000000..58e2f7d594
--- /dev/null
+++ b/applications/test/flatOutput1/Test-flatOuput1.C
@@ -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 .
+
+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;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/ListOps/FlatOutput.H b/src/OpenFOAM/containers/Lists/ListOps/FlatOutput.H
deleted file mode 100644
index d6a88aae1a..0000000000
--- a/src/OpenFOAM/containers/Lists/ListOps/FlatOutput.H
+++ /dev/null
@@ -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 .
-
-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 FlatOutput;
-template
-Ostream& operator<<(Ostream& os, const FlatOutput& obj);
-
-
-/*---------------------------------------------------------------------------*\
- Class FlatOutput Declaration
-\*---------------------------------------------------------------------------*/
-
-template
-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& wrapped
- )
- {
- return wrapped.ref_.writeList(os, wrapped.len_);
- }
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-//- Global flatOutput function
-template
-FlatOutput flatOutput(const Container& obj, label len=0)
-{
- return FlatOutput(obj, len);
-}
-
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/output/FlatOutput.H b/src/OpenFOAM/db/IOstreams/output/FlatOutput.H
new file mode 100644
index 0000000000..399dd081bd
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/output/FlatOutput.H
@@ -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 .
+
+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 OutputAdaptor;
+
+} // End namespace FlatOutput
+
+
+// Forward Declarations
+template
+inline Ostream& operator<<
+(
+ Ostream&,
+ const FlatOutput::OutputAdaptor&
+);
+
+
+namespace FlatOutput
+{
+
+/*---------------------------------------------------------------------------*\
+ Class Decorators Declaration
+\*---------------------------------------------------------------------------*/
+
+//- List decorators with \c open, \c close and \c separator characters
+template
+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 {};
+
+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 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& adaptor
+ )
+ {
+ return adaptor.write(os);
+ }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace FlatOutput
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+//- Global flatOutput() function with specified output delimiters
+template
+inline FlatOutput::OutputAdaptor
+flatOutput
+(
+ const Container& obj,
+ Delimiters delim
+)
+{
+ return FlatOutput::OutputAdaptor(obj);
+}
+
+
+//- Global flatOutput() function with default (parenthesis/space) delimiters
+template
+inline FlatOutput::OutputAdaptor
+flatOutput
+(
+ const Container& obj
+)
+{
+ return FlatOutput::OutputAdaptor(obj);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/global/debug/debug.C b/src/OpenFOAM/global/debug/debug.C
index 419b247e7f..d3e5c79f7a 100644
--- a/src/OpenFOAM/global/debug/debug.C
+++ b/src/OpenFOAM/global/debug/debug.C
@@ -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);
}
}
}