bug.hh 7.02 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef RADIX_RADIXBUG_BUG_HH_
#define RADIX_RADIXBUG_BUG_HH_

#ifndef DEBUG_OUTPUT
#define DEBUG_OUTPUT 0
#define DEBUG_CALL(c)
#else
#define DEBUG_CALL(c) c
#endif

// default to c++ compiler
/*
 * @file:   bug.hh
 * @author: Jordan P. Lefebvre, lefebvrejp@ornl.gov
 * @brief Debug functionality for including debug output \
 * in your source without a performance penalty.
 * This is an include ONLY package. There is no library to link against
 * Each function is preprocessed to be included or not.
 * If DEBUG_OUTPUT is defined the MACROs are included.
 *
 * Available MACROs:
 * radix(arg) - std::cerr << arg - Pushes content to stderr
23
24
25
26
27
 * radix_line(arg) - std::cerr << arg << std::endl - Push newline terminated
 * content to stderr radix(arg) - std::cerr << arg - Pushes content to stderr
 * radix_warning(arg) - std::cerr << arg << std::endl - Push newline terminated
 * content to stderr radix_tagged_line(arg) - Same as radixLine, prefixed with
 * FILE and LINE radix_tagged(arg) - Same as radix, prefixed with FILE and LINE
28
29
30
31
 * radix_tagged_warning(arg) - Same as radixWarning, prefixed with FILE and Line
 * radix_block(block) - block - Simply places code block in preprocessor
 */
#include <cstdio>
32
#include <iostream>
33
#if DEBUG_OUTPUT & 1
34
35
36
37
38
#ifndef radix_stream
#define radix_stream std::cerr
#endif
#define radix_define_stream
#define radix_line(arg) radix_stream << arg << std::endl
39
40
41
#define radix_flush_line(arg)       \
  radix_stream << arg << std::endl; \
  fflush(stderr)
42
43
#define radix(arg) radix_stream << arg
#define radix_warning(arg) radix_stream << arg << std::endl
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#define radix_tagged_warning(arg) \
  radix_stream << __FILE__ << ":" << __LINE__ << ": " << arg << std::endl
#define radix_flush_warning(arg)    \
  radix_stream << arg << std::endl; \
  fflush(stderr)
#define radix_tagged_line(arg) \
  radix_stream << __FILE__ << ":" << __LINE__ << ": " << arg << std::endl
#define radix_flush_tagged_line(arg)                                       \
  radix_stream << __FILE__ << ":" << __LINE__ << ": " << arg << std::endl; \
  fflush(stderr)
#define radix_tagged(arg) \
  radix_stream << __FILE__ << ":" << __LINE__ << ": " << arg
#define radix_flush_tagged_warning(arg)                                    \
  radix_stream << __FILE__ << ":" << __LINE__ << ": " << arg << std::endl; \
  fflush(stderr)
#define radix_tagged_block(block)                                  \
  radix_stream << __FILE__ << ":" << __LINE__ << ":" << std::endl; \
  block
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#define radix_block(block) block
#else
#define radix(arg)
#define radix_line(arg)
#define radix_flush_line(arg)
#define radix_warning(arg)
#define radix_flush_warning(arg)
#define radix_tagged_line(arg)
#define radix_flush_tagged_line(arg)
#define radix_tagged(arg)
#define radix_tagged_warning(arg)
#define radix_flush_tagged_warning(arg)
#define radix_tagged_block(block)
#define radix_block(block)
#endif /* DEBUG_OUTPUT */

#include <sstream>
79
#include <stdexcept>
80
81
82
83
84
85
86
87
88
89
90
91
#ifndef RADIX_DBC
#define RADIX_DBC 0
#endif

//
// Defined all levels of RADIX_DBC
// RADIX_DBC = 1 enables Require
// RADIX_DBC = 2 enables Check
// RADIX_DBC = 4 enables Remember & Ensure
// RADIX_DBC = 7 enables all
// Insist is always enabled
#if RADIX_DBC & 1
92
93
94
95
96
97
98
#define radix_require(c)                                             \
  if (!(c)) {                                                        \
    std::ostringstream stream;                                       \
    stream << __FILE__ << ":" << __LINE__ << " radix_require(" << #c \
           << ") failed." << std::endl;                              \
    throw std::runtime_error(stream.str());                          \
  }
99
100
101
102
#else
#define radix_require(c)
#endif
#if RADIX_DBC & 2
103
104
105
106
107
108
109
#define radix_check(c)                                             \
  if (!(c)) {                                                      \
    std::ostringstream stream;                                     \
    stream << __FILE__ << ":" << __LINE__ << " radix_check(" << #c \
           << ") failed." << std::endl;                            \
    throw std::runtime_error(stream.str());                        \
  }
110
111
112
113
#else
#define radix_check(c)
#endif
#if RADIX_DBC & 4
114
115
116
117
118
119
120
#define radix_ensure(c)                                             \
  if (!(c)) {                                                       \
    std::ostringstream stream;                                      \
    stream << __FILE__ << ":" << __LINE__ << " radix_ensure(" << #c \
           << ") failed." << std::endl;                             \
    throw std::runtime_error(stream.str());                         \
  }
121
122
123
124
125
126
#define radix_remember(c) c
#else
#define radix_ensure(c)
#define radix_remember(c)
#endif

127
128
129
130
131
132
133
134
#define radix_insist(c, msg)                                       \
  if (!(c)) {                                                      \
    std::ostringstream stream;                                     \
    stream << __FILE__ << ":" << __LINE__ << "radix_insist(" << #c \
           << ") failed with this message:" << std::endl           \
           << msg << std::endl;                                    \
    throw std::runtime_error(stream.str());                        \
  }
135

136
137
138
139
140
141
142
/// set default timing to off
#ifndef RADIX_TIMING
#define RADIX_TIMING 0
#endif

#include <chrono>
#include <ctime>
143
144
145
146
147
148
149
150
151
152
namespace radix {
class Timer {
 private:
  bool mRunning;
  std::chrono::steady_clock::time_point mStart;
  std::chrono::steady_clock::time_point mEnd;
  std::chrono::nanoseconds mDuration;
  size_t mIntervals;

 public:
153
154
155
156
  Timer()
      : mRunning(false)
      , mDuration(0)
      , mIntervals(0) {}
157
158
159
160
161
162
163
164
165
166
167
168
169
  void start() {
    radix_check(!mRunning);
    mRunning = true;
    mIntervals++;
    mStart = std::chrono::steady_clock::now();
  }
  void stop() {
    radix_check(mRunning);
    mEnd     = std::chrono::steady_clock::now();
    mRunning = false;
    mDuration +=
        std::chrono::duration_cast<std::chrono::nanoseconds>(mEnd - mStart);
  }
170

171
172
173
174
175
176
177
  double duration() const {
    radix_check(!mRunning);
    return mDuration.count();
  }
  size_t intervals() const { return mIntervals; }
};  // class Timer
}  // namespace radix
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

#if RADIX_TIMING > 0
#define radix_timer(name) radix::Timer name
#define radix_timer_start(name) name.start()
#define radix_timer_stop(name) name.stop()
#define radix_timer_block(content) content
#else
#define radix_timer(name)
#define radix_timer_start(name)
#define radix_timer_stop(name)
#define radix_timer_block(content)
#endif
#if RADIX_TIMING > 1
#define radix_timer_2(name) radix::Timer name
#define radix_timer_start_2(name) name.start()
#define radix_timer_stop_2(name) name.stop()
#define radix_timer_block_2(content) content
#else
#define radix_timer_2(name)
#define radix_timer_start_2(name)
#define radix_timer_stop_2(name)
#define radix_timer_block_2(content)
#endif

#if RADIX_TIMING > 2
#define radix_timer_3(name) radix::Timer name
#define radix_timer_start_3(name) name.start()
#define radix_timer_stop_3(name) name.stop()
#define radix_timer_block_3(content) content
#else
#define radix_timer_3(name)
#define radix_timer_start_3(name)
#define radix_timer_stop_3(name)
#define radix_timer_block_3(content)
#endif
213

214
#endif /* RADIX_RADIXBUG_BUG_HH_*/