Scippy

SoPlex

Sequential object-oriented simPlex

spxout.h
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the class library */
4/* SoPlex --- the Sequential object-oriented simPlex. */
5/* */
6/* Copyright (c) 1996-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SoPlex; see the file LICENSE. If not email to soplex@zib.de. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file spxout.h
26 * @brief Wrapper for different output streams and verbosity levels.
27 */
28#ifndef _SPXOUT_H_
29#define _SPXOUT_H_
30
31#include <iostream>
32#include <iomanip>
33#include <assert.h>
34#include "soplex/fmt.hpp"
35
36#include "soplex/spxdefines.h"
37
38// ----------------------------------------------------------------------
39// class SPxOut
40// ----------------------------------------------------------------------
41
42namespace soplex
43{
44
46{
47};
48
49/**@class SPxOut
50 @ingroup Elementary
51
52 @brief Wrapper for several output streams.
53 A verbosity level is used to decide which stream to use and whether to
54 really print a given message. Regardless of whether the verbosity level
55 is set via a manipulator or via the member function, it is persistent
56 until a new value is set.
57
58 Most ostream member functions are not provided here; use the corresponding
59 stream manipulators (e.g., @c setprecision()) instead. These are passed on
60 to the <em>current</em> ostream, which is chosen according to the verbosity
61 level. In particular, this means that the first element in an output stream
62 should always be the verbosity. For instance, use
63 @code
64 spxout << verb( SPxOut::WARNING ) << std::setw( 15 ) << 42 << std::endl;
65 @endcode
66 or
67 @code
68 spxout.setVerbosity( SPxOut::WARNING );
69 spxout << std::setw( 15 ) << 42 << std::endl;
70 @endcode
71 instead of
72 @code
73 spxout << std::setw( 15 ) << verb( SPxOut::WARNING ) << 42 << std::endl;
74 @endcode
75 in order to make sure that @c std::setw( 15 ) is applied to the warning stream.
76*/
77class SPxOut
78{
79public:
80
81
82 //-----------------------------------
83 /**@name Output control types */
84 ///@{
85 /// Verbosity level
86 typedef enum
87 {
88 // Note: the implementation uses the fact that ERROR == 0
89 // and that the verbosity levels are subsequent numbers.
90 // If you change this, change the implementation as well.
91 ERROR = 0,
93 DEBUG = 2,
94 INFO1 = 3,
95 INFO2 = 4,
96 INFO3 = 5
98
99 /// helper struct for the output operator
101 {
102 /// verbosity level
104 };
105 ///@}
106
107 //-----------------------------------
108 /**@name Construction / destruction */
109 ///@{
110 /// constructor
111 SPxOut();
112 /// destructor
113 virtual ~SPxOut();
114 /// copy constructor
115 SPxOut(const SPxOut&);
116 /// assignment operator
117 SPxOut& operator=(const SPxOut&);
118 ///@}
119
120 //-----------------------------------
121 /**@name Verbosity */
122 ///@{
123 ///
124 virtual void
126 {
127 m_verbosity = v;
128 }
129 ///
130 inline Verbosity
132 const
133 {
134 return m_verbosity;
135 }
136
137 ///@}
138
139 //----------------------------------------
140 /**@name Wrappers for the current stream */
141 ///@{
142 ///
143 inline bool good() const
144 {
145 return getCurrentStream().good();
146 }
147 ///
148 inline bool operator !() const
149 {
150 return ! getCurrentStream();
151 }
152 ///
153 inline std::streamsize precision() const
154 {
155 return getCurrentStream().precision();
156 }
157 ///@}
158
159 //-----------------------------------
160 /**@name Getting / setting streams */
161 ///@{
162 /// Sets the stream for the specified verbosity level.
163 virtual void
164 setStream(const Verbosity& verbosity,
165 std::ostream& stream)
166 {
167 m_streams[ verbosity ] = &stream;
168 }
169 /// Returns the stream for the specified verbosity level.
170 inline std::ostream&
171 getStream(const Verbosity& verbosity)
172 const
173 {
174 return *(m_streams[ verbosity ]);
175 }
176 /// Returns the stream for the current verbosity.
177 inline std::ostream&
179 const
180 {
181 return getStream(getVerbosity());
182 }
183
184 /// Sets the precision of the stream to 16 and the floatfield to scientifix.
185 static inline void setScientific(std::ostream& stream, int precision = 8)
186 {
187 stream << std::setprecision(precision) << std::scientific;
188 }
189
190 /// Sets the precision of the stream to 8 and the floatfield to fixed.
191 static inline void setFixed(std::ostream& stream, int precision = 8)
192 {
193 stream << std::setprecision(precision) << std::fixed;
194 }
195
196 // select with SFINAE to print debug output or depending on whether the class
197 // type of the pointer inherits from the marker struct EnableDebugOutput
198
199 template < typename T, typename... Args,
200 typename std::enable_if <
201 !std::is_base_of<EnableDebugOutput, T>::value, int >::type = 0 >
202 static void
203 debug(const T*, Args && ... args)
204 {
205 }
206
207 template <typename T, typename... Args,
208 typename std::enable_if<
209 std::is_base_of<EnableDebugOutput, T>::value, int>::type = 0>
210 static void
211 debug(const T*, Args && ... args)
212 {
213 fmt::print(std::forward<Args>(args)...);
214 }
215 ///@}
216
217private:
218
219 //-----------------------------------
220 /**@name Private data */
221 ///@{
222 /// verbosity level
224 /// array of pointers to internal streams, indexed by verbosity level
225 std::ostream** m_streams;
226 ///@}
227};
228
229// ---------------------------------------------------------
230// Manipulators
231// ---------------------------------------------------------
232
233
234//-------------------------------------------
235/**@name Verbosity manipulator
236 Manipulators are implemented in a similar way as done for @c setw(),
237 @c setprecision(), etc. in the standard library file iomanip. For
238 instance, the non-member function \ref soplex::verb() "verb(v)"
239 returns a struct struct_Verbosity which contains only the verbosity level.
240 Calling
241 @code
242 SPxOut spxout;
243 spxout << verb( SPxOut::ERROR ) << "This is an error!" << std::endl;
244 @endcode
245 passes such a struct to the output operator defined below, which
246 extracts the verbosity level from the struct and passes it to the
247 member function SPxOut::setVerbosity().
248*/
249///@{
250/// manipulator to be used in an output statement
253{
254 SPxOut::struct_Verbosity verbosity;
255 verbosity.v_ = v;
256 return verbosity;
257}
258
259/// output operator with verbosity level struct
260inline SPxOut&
261operator<< (SPxOut& stream,
262 const SPxOut::struct_Verbosity& verbosity)
263{
264 stream.setVerbosity(verbosity.v_);
265 return stream;
266}
267///@}
268
269//--------------------------------------------------------
270/**@name Output of standard manipulators and other types
271 *
272 * We have to define an output operator for many kinds of numeric
273 * types here because they can all be more or less casted into each
274 * other. When using only a template type, it is not clear what the
275 * compiler makes out of it (according to lint).
276 */
277///@{
278///
279/// Passes instances of type \p Type to the current stream.
280inline SPxOut& operator<< (SPxOut& _spxout, long t)
281{
282 _spxout.getCurrentStream() << t;
283 return _spxout;
284}
285
286inline SPxOut& operator<< (SPxOut& _spxout, unsigned long t)
287{
288 _spxout.getCurrentStream() << t;
289 return _spxout;
290}
291
292inline SPxOut& operator<< (SPxOut& _spxout, bool t)
293{
294 _spxout.getCurrentStream() << t;
295 return _spxout;
296}
297
298inline SPxOut& operator<< (SPxOut& _spxout, short t)
299{
300 _spxout.getCurrentStream() << t;
301 return _spxout;
302}
303
304inline SPxOut& operator<< (SPxOut& _spxout, unsigned short t)
305{
306 _spxout.getCurrentStream() << t;
307 return _spxout;
308}
309
310inline SPxOut& operator<< (SPxOut& _spxout, int t)
311{
312 _spxout.getCurrentStream() << t;
313 return _spxout;
314}
315
316inline SPxOut& operator<< (SPxOut& _spxout, unsigned int t)
317{
318 _spxout.getCurrentStream() << t;
319 return _spxout;
320}
321
322inline SPxOut& operator<< (SPxOut& _spxout, double t)
323{
324 _spxout.getCurrentStream() << t;
325 return _spxout;
326}
327
328inline SPxOut& operator<< (SPxOut& _spxout, float t)
329{
330 _spxout.getCurrentStream() << t;
331 return _spxout;
332}
333
334inline SPxOut& operator<< (SPxOut& _spxout, long double t)
335{
336 _spxout.getCurrentStream() << t;
337 return _spxout;
338}
339
340inline SPxOut& operator<< (SPxOut& _spxout, const void* t)
341{
342 _spxout.getCurrentStream() << t;
343 return _spxout;
344}
345
346/// Passes standard manipulators without arguments, like @c std::endl
347/// or @c std::ios::right to the current stream.
348inline SPxOut&
349operator<< (SPxOut& _spxout,
350 std::ostream & (*manip)(std::ostream&))
351{
352 _spxout.getCurrentStream() << manip;
353 return _spxout;
354}
355
356//lint -e{818} (pointer could be made const; this is ok.)
357/// Passes everything else to the current stream. In particular,
358/// this includes structs corresponding to manipulators with arguments,
359/// such as the struct @c _Setw for the @c setw() manipulator.
360template <typename T>
361inline SPxOut& operator<< (SPxOut& _spxout, T t)
362{
363 _spxout.getCurrentStream() << t;
364 return _spxout;
365}
366
367///@}
368
369} // namespace soplex
370
371#endif // _SPXOUT_H_
Wrapper for several output streams. A verbosity level is used to decide which stream to use and wheth...
Definition: spxout.h:78
std::ostream ** m_streams
array of pointers to internal streams, indexed by verbosity level
Definition: spxout.h:225
Verbosity getVerbosity() const
Definition: spxout.h:131
std::ostream & getStream(const Verbosity &verbosity) const
Returns the stream for the specified verbosity level.
Definition: spxout.h:171
std::streamsize precision() const
Definition: spxout.h:153
bool operator!() const
Definition: spxout.h:148
SPxOut & operator=(const SPxOut &)
assignment operator
Definition: spxout.cpp:52
static void setFixed(std::ostream &stream, int precision=8)
Sets the precision of the stream to 8 and the floatfield to fixed.
Definition: spxout.h:191
virtual void setVerbosity(const Verbosity &v)
Definition: spxout.h:125
bool good() const
Definition: spxout.h:143
Verbosity
Verbosity level.
Definition: spxout.h:87
std::ostream & getCurrentStream() const
Returns the stream for the current verbosity.
Definition: spxout.h:178
virtual void setStream(const Verbosity &verbosity, std::ostream &stream)
Sets the stream for the specified verbosity level.
Definition: spxout.h:164
SPxOut()
constructor
Definition: spxout.cpp:32
virtual ~SPxOut()
destructor
Definition: spxout.cpp:47
static void debug(const T *, Args &&... args)
Definition: spxout.h:203
Verbosity m_verbosity
verbosity level
Definition: spxout.h:223
static void setScientific(std::ostream &stream, int precision=8)
Sets the precision of the stream to 16 and the floatfield to scientifix.
Definition: spxout.h:185
Everything should be within this namespace.
std::ostream & operator<<(std::ostream &s, const VectorBase< R > &vec)
Output operator.
Definition: basevectors.h:1143
SPxOut::struct_Verbosity verb(const SPxOut::Verbosity &v)
manipulator to be used in an output statement
Definition: spxout.h:252
Debugging, floating point type and parameter definitions.
helper struct for the output operator
Definition: spxout.h:101
Verbosity v_
verbosity level
Definition: spxout.h:103