Dune Core Modules (2.3.1)

debugstream.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// $Id$
4
5#ifndef DUNE_DEBUGSTREAM_HH
6#define DUNE_DEBUGSTREAM_HH
7
12#include <iostream>
13#include <stack>
14
16
17namespace Dune {
18
117 typedef unsigned int DebugLevel;
118
128 template <DebugLevel current, DebugLevel threshold>
130 static const bool value = (current >= threshold);
131 };
132
133
140 template <DebugLevel current, DebugLevel mask>
141 struct common_bits {
142 enum {value = ((current & mask)!=0) };
143 };
144
145
147 class DebugStreamError : public IOError {};
148
149 class StreamWrap {
150 public:
151 StreamWrap(std::ostream& _out) : out(_out) { };
152 std::ostream& out;
153 StreamWrap *next;
154 };
155
158 // !!! should be protected somehow but that won't be easy
159 public:
161 StreamWrap* current;
162
165
167 bool _tied;
168
170 unsigned int _tied_streams;
171 };
172
187 template <DebugLevel thislevel = 1,
188 DebugLevel dlevel = 1,
189 DebugLevel alevel = 1,
190 template<DebugLevel, DebugLevel> class activator = greater_or_equal>
192 public:
198 DebugStream(std::ostream& out = std::cerr) {
199 // start a new list of streams
200 current = new StreamWrap(out);
201 current->next = 0;
202
203 // check if we are above the default activation level
204 _active = activator<thislevel,alevel>::value;
205
206 // we're not tied to another DebugStream
207 _tied = false;
208
209 // no child streams yet
210 _tied_streams = 0;
211 };
212
219 std::ostream& fallback = std::cerr)
220 {
221 // start a new list of streams
222 current = new StreamWrap(fallback);
223 current->next = 0;
224
225 // check if we are above the default activation level
226 _active = activator<thislevel,alevel>::value;
227 _tied_streams = 0;
228
229 // tie to the provided stream
230 _tied = true;
231 tiedstate = &master;
232 tiedstate->_tied_streams++;
233 };
234
242 // untie
243 if (_tied)
244 tiedstate->_tied_streams--;
245 else {
246 // check if somebody still ties to us...
247 if (_tied_streams != 0)
249 "There are streams still tied to this stream!");
250 };
251
252 // remove ostream-stack
253 while (current != 0) {
254 StreamWrap *s = current;
255 current = current->next;
256 delete s;
257 };
258 };
259
261 template <class T>
262 DebugStream& operator<<(const T data) {
263 // remove the following code if stream wasn't compiled active
264 if (activator<thislevel, dlevel>::value) {
265 if (! _tied) {
266 if (_active)
267 current->out << data;
268 } else {
269 if (_active && tiedstate->_active)
270 tiedstate->current->out << data;
271 };
272 };
273
274 return *this;
275 }
276
284 DebugStream& operator<<(const int data) {
285 // remove the following code if stream wasn't compiled active
286 if (activator<thislevel, dlevel>::value) {
287 if (! _tied) {
288 if (_active)
289 current->out << data;
290 } else {
291 if (_active && tiedstate->_active)
292 tiedstate->current->out << data;
293 };
294 };
295
296 return *this;
297 }
298
300 DebugStream& operator<<(std::ostream& (*f)(std::ostream&)) {
301 if (activator<thislevel, dlevel>::value) {
302 if (! _tied) {
303 if (_active)
304 f(current->out);
305 } else {
306 if (_active && tiedstate->_active)
307 f(tiedstate->current->out);
308 };
309 }
310
311 return *this;
312 };
313
316 if (activator<thislevel, dlevel>::value) {
317 if (! _tied) {
318 if (_active)
319 current->out.flush();
320 } else {
321 if (_active && tiedstate->_active)
322 tiedstate->current->out.flush();
323 };
324 }
325
326 return *this;
327 };
328
330 void push(bool b) {
331 // are we at all active?
332 if (activator<thislevel,alevel>::value) {
333 _actstack.push(_active);
334 _active = b;
335 } else {
336 // stay off
337 _actstack.push(false);
338 };
339 };
340
342 void pop() throw(DebugStreamError) {
343 if (_actstack.empty())
344 DUNE_THROW(DebugStreamError, "No previous activation setting!");
345
346 _active = _actstack.top();
347 _actstack.pop();
348 };
349
356 bool active() const {
357 return activator<thislevel, dlevel>::value && _active;
358 };
359
364 void attach(std::ostream& stream) {
365 if (_tied)
366 DUNE_THROW(DebugStreamError, "Cannot attach to a tied stream!");
367
368 StreamWrap* newcurr = new StreamWrap(stream);
369 newcurr->next = current;
370 current = newcurr;
371 };
372
374 void detach() throw(DebugStreamError) {
375 if (current->next == 0)
376 DUNE_THROW(DebugStreamError, "Cannot detach initial stream!");
377 if (_tied)
378 DUNE_THROW(DebugStreamError, "Cannot detach a tied stream!");
379
380 StreamWrap* old = current;
381 current = current->next;
382 delete old;
383 };
384
385 // \brief Tie a stream to this one.
386 void tie(DebugStreamState& to) throw(DebugStreamError) {
387 if (to._tied)
388 DUNE_THROW(DebugStreamError, "Cannot tie to an already tied stream!");
389 if (_tied)
390 DUNE_THROW(DebugStreamError, "Stream already tied: untie first!");
391
392 _tied = true;
393 tiedstate = &to;
394
395 // tell master class
396 tiedstate->_tied_streams++;
397 };
398
400 void untie() throw(DebugStreamError) {
401 if(! _tied)
402 DUNE_THROW(DebugStreamError, "Cannot untie, stream is not tied!");
403
404 tiedstate->_tied_streams--;
405 _tied = false;
406 tiedstate = 0;
407 };
408
409 private:
411 DebugStreamState* tiedstate;
412
417 std::stack<bool> _actstack;
418 };
419
421}
422
423
424#endif
standard exception for the debugstream
Definition: debugstream.hh:147
Intermediate class to implement tie-operation of DebugStream.
Definition: debugstream.hh:157
Generic class to implement debug output streams.
Definition: debugstream.hh:191
Default exception class for I/O errors.
Definition: exceptions.hh:257
A few common exception classes.
DebugStream(std::ostream &out=std::cerr)
Create a DebugStream and set initial output stream.
Definition: debugstream.hh:198
void untie()
Untie stream.
Definition: debugstream.hh:400
DebugStream & flush()
pass on flush to underlying output stream
Definition: debugstream.hh:315
void attach(std::ostream &stream)
set output to a different stream.
Definition: debugstream.hh:364
void detach()
detach current output stream and restore to previous stream
Definition: debugstream.hh:374
void pop()
restore previously set activation flag
Definition: debugstream.hh:342
bool active() const
reports if this stream will produce output
Definition: debugstream.hh:356
bool _active
flag to switch output during runtime
Definition: debugstream.hh:164
unsigned int _tied_streams
how many streams are tied to this state
Definition: debugstream.hh:170
void push(bool b)
set activation flag and store old value
Definition: debugstream.hh:330
unsigned int DebugLevel
Type for debug levels.
Definition: debugstream.hh:117
bool _tied
are we tied to another DebugStream?
Definition: debugstream.hh:167
StreamWrap * current
current output stream and link to possibly pushed old output streams
Definition: debugstream.hh:161
DebugStream & operator<<(const T data)
Generic types are passed on to current output stream.
Definition: debugstream.hh:262
~DebugStream()
Destroy stream.
Definition: debugstream.hh:241
DebugStream(DebugStreamState &master, std::ostream &fallback=std::cerr)
Create a DebugStream and directly tie to another DebugStream.
Definition: debugstream.hh:218
DebugStream & operator<<(const int data)
explicit specialization so that enums can be printed
Definition: debugstream.hh:284
DebugStream & operator<<(std::ostream &(*f)(std::ostream &))
pass on manipulators to underlying output stream
Definition: debugstream.hh:300
#define DUNE_THROW(E, m)
Definition: exceptions.hh:244
Dune namespace.
Definition: alignment.hh:14
activate if current and mask have common bits switched on.
Definition: debugstream.hh:141
Greater or equal template test.
Definition: debugstream.hh:129
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)