@@ -31,17 +31,17 @@ class Output;
3131
3232#include " bout/multiostream.hxx"
3333#include < fstream>
34- #include < functional>
3534#include < iostream>
3635#include < string>
3736
3837#include " bout/assert.hxx"
39- #include " bout/boutexception.hxx"
40- #include " bout/sys/gettext.hxx" // for gettext _() macro
38+ #include " bout/sys/gettext.hxx" // IWYU pragma: keep for gettext _() macro
4139#include " bout/unused.hxx"
4240
4341#include " fmt/core.h"
4442
43+ #include < utility>
44+
4545using std::endl;
4646
4747// / Class for text output to stdout and/or log file
@@ -61,22 +61,28 @@ using std::endl;
6161class Output : private multioutbuf_init <char , std::char_traits<char >>,
6262 public std::basic_ostream<char , std::char_traits<char >> {
6363
64- using _Tr = std::char_traits<char >;
65- using multioutbuf_init = ::multioutbuf_init<char , _Tr >;
64+ using Tr = std::char_traits<char >;
65+ using multioutbuf_init = ::multioutbuf_init<char , Tr >;
6666
6767public:
68- Output () : multioutbuf_init(), std::basic_ostream<char , _Tr >(multioutbuf_init::buf()) {
68+ Output () : multioutbuf_init(), std::basic_ostream<char , Tr >(multioutbuf_init::buf()) {
6969 Output::enable ();
7070 }
7171
72+ Output (const Output&) = delete ;
73+ Output (Output&&) = delete ;
74+ Output& operator =(const Output&) = delete ;
75+ Output& operator =(Output&&) = delete ;
76+
7277 // / Specify a log file to open
7378 Output (const std::string& filename) {
7479 Output::enable ();
7580 open (filename);
7681 }
7782
7883 template <class S , class ... Args>
79- Output (const S& format, const Args&... args) : Output(fmt::format(format, args...)) {}
84+ Output (const S& format, Args&&... args)
85+ : Output(fmt::format(format, std::forward<decltype (args)>(args)...)) {}
8086
8187 ~Output () override { close (); }
8288
@@ -87,8 +93,8 @@ public:
8793 int open (const std::string& filename);
8894
8995 template <class S , class ... Args>
90- int open (const S& format, const Args&... args) {
91- return open (fmt::format (format, args...));
96+ int open (const S& format, Args& &... args) {
97+ return open (fmt::format (format, std::forward< decltype ( args)>(args) ...));
9298 }
9399
94100 // / Close the log file
@@ -98,24 +104,22 @@ public:
98104 virtual void write (const std::string& message);
99105
100106 template <class S , class ... Args>
101- void write (const S& format, const Args&... args) {
102- write (fmt::format (format, args...));
107+ void write (const S& format, Args& &... args) {
108+ write (fmt::format (format, std::forward< decltype ( args)>(args) ...));
103109 }
104110 // / Same as write, but only to screen
105111 virtual void print (const std::string& message);
106112
107113 template <class S , class ... Args>
108- void print (const S& format, const Args&... args) {
109- print (fmt::format (format, args...));
114+ void print (const S& format, Args& &... args) {
115+ print (fmt::format (format, std::forward< decltype ( args)>(args) ...));
110116 }
111117
112118 // / Add an output stream. All output will be sent to all streams
113- void add (std::basic_ostream<char , _Tr >& str) { multioutbuf_init::buf ()->add (str); }
119+ void add (std::basic_ostream<char , Tr >& str) { multioutbuf_init::buf ()->add (str); }
114120
115121 // / Remove an output stream
116- void remove (std::basic_ostream<char , _Tr>& str) {
117- multioutbuf_init::buf ()->remove (str);
118- }
122+ void remove (std::basic_ostream<char , Tr>& str) { multioutbuf_init::buf ()->remove (str); }
119123
120124 static Output* getInstance (); // /< Return pointer to instance
121125
@@ -126,7 +130,7 @@ protected:
126130
127131private:
128132 std::ofstream file; // /< Log file stream
129- bool enabled; // /< Whether output to stdout is enabled
133+ bool enabled{}; // /< Whether output to stdout is enabled
130134};
131135
132136// / Class which behaves like Output, but has no effect.
@@ -136,14 +140,14 @@ private:
136140class DummyOutput : public Output {
137141public:
138142 template <class S , class ... Args>
139- void write ([[maybe_unused]] const S& format, [[maybe_unused]] const Args&... args){};
143+ void write ([[maybe_unused]] const S& format, [[maybe_unused]] Args&& ... args) {};
140144 template <class S , class ... Args>
141- void print ([[maybe_unused]] const S& format, [[maybe_unused]] const Args&... args){};
142- void write ([[maybe_unused]] const std::string& message) override {};
143- void print ([[maybe_unused]] const std::string& message) override {};
144- void enable () override {};
145- void disable () override {};
146- void enable ([[maybe_unused]] bool enable){};
145+ void print ([[maybe_unused]] const S& format, [[maybe_unused]] Args&& ... args) {};
146+ void write ([[maybe_unused]] const std::string& message) override {};
147+ void print ([[maybe_unused]] const std::string& message) override {};
148+ void enable () override {};
149+ void disable () override {};
150+ void enable ([[maybe_unused]] bool enable) {};
147151 bool isEnabled () override { return false ; }
148152};
149153
@@ -170,10 +174,10 @@ public:
170174 void write (const std::string& message) override ;
171175
172176 template <class S , class ... Args>
173- void write (const S& format, const Args&... args) {
177+ void write (const S& format, Args& &... args) {
174178 if (enabled) {
175179 ASSERT1 (base != nullptr );
176- base->write (fmt::format (format, args...));
180+ base->write (fmt::format (format, std::forward< decltype ( args)>(args) ...));
177181 }
178182 }
179183
@@ -182,10 +186,10 @@ public:
182186 void print (const std::string& message) override ;
183187
184188 template <class S , class ... Args>
185- void print (const S& format, const Args&... args) {
189+ void print (const S& format, Args& &... args) {
186190 if (enabled) {
187191 ASSERT1 (base != nullptr );
188- base->print (fmt::format (format, args...));
192+ base->print (fmt::format (format, std::forward< decltype ( args)>(args) ...));
189193 }
190194 }
191195
@@ -216,8 +220,6 @@ private:
216220 // / The lower-level Output to send output to
217221 Output* base;
218222
219- protected:
220- friend class WithQuietOutput ;
221223 // / Does this instance output anything?
222224 bool enabled;
223225};
@@ -276,18 +278,23 @@ ConditionalOutput& operator<<(ConditionalOutput& out, const T* t) {
276278// / // output now enabled
277279class WithQuietOutput {
278280public:
279- explicit WithQuietOutput (ConditionalOutput& output_in) : output(output_in) {
280- state = output.enabled ;
281- output.disable ();
281+ WithQuietOutput (const WithQuietOutput&) = delete ;
282+ WithQuietOutput (WithQuietOutput&&) = delete ;
283+ WithQuietOutput& operator =(const WithQuietOutput&) = delete ;
284+ WithQuietOutput& operator =(WithQuietOutput&&) = delete ;
285+ explicit WithQuietOutput (ConditionalOutput& output_in)
286+ : output(&output_in), state(output->isEnabled ()) {
287+ output->disable ();
282288 }
283289
284- ~WithQuietOutput () { output. enable (state); }
290+ ~WithQuietOutput () { output-> enable (state); }
285291
286292private:
287- ConditionalOutput& output;
293+ ConditionalOutput* output;
288294 bool state;
289295};
290296
297+ // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
291298// / To allow statements like "output.write(...)" or "output << ..."
292299// / Output for debugging
293300#ifdef BOUT_USE_OUTPUT_DEBUG
@@ -303,5 +310,6 @@ extern ConditionalOutput output_verbose; ///< less interesting messages
303310
304311// / Generic output, given the same level as output_progress
305312extern ConditionalOutput output;
313+ // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
306314
307315#endif // BOUT_OUTPUT_H
0 commit comments