gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 5 4
merge default
0 files changed with 961 insertions and 370 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#ifndef LEMON_COUNTER_H
20
#define LEMON_COUNTER_H
21

	
22
#include <string>
23
#include <iostream>
24

	
25
///\ingroup timecount
26
///\file
27
///\brief Tools for counting steps and events
28

	
29
namespace lemon 
30
{
31

	
32
  template<class P> class _NoSubCounter;
33

	
34
  template<class P>
35
  class _SubCounter 
36
  {
37
    P &_parent;
38
    std::string _title;
39
    std::ostream &_os;
40
    int count;
41
  public:
42

	
43
    typedef _SubCounter<_SubCounter<P> > SubCounter;
44
    typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
45

	
46
    _SubCounter(P &parent)
47
      : _parent(parent), _title(), _os(std::cerr), count(0) {}
48
    _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
49
      : _parent(parent), _title(title), _os(os), count(0) {}
50
    _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
51
      : _parent(parent), _title(title), _os(os), count(0) {}
52
    ~_SubCounter() { 
53
      _os << _title << count <<std::endl;
54
      _parent+=count;
55
    }
56
    _SubCounter &operator++() { count++; return *this;}
57
    int operator++(int) { return count++; }
58
    _SubCounter &operator--() { count--; return *this;}
59
    int operator--(int) { return count--; }
60
    _SubCounter &operator+=(int c) { count+=c; return *this;}
61
    _SubCounter &operator-=(int c) { count-=c; return *this;}
62
    void reset(int c=0) {count=c;}
63
    operator int() {return count;}
64
  };
65

	
66
  template<class P>
67
  class _NoSubCounter 
68
  {
69
    P &_parent;
70
  public:
71
    typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
72
    typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
73
  
74
    _NoSubCounter(P &parent) :_parent(parent) {}
75
    _NoSubCounter(P &parent,std::string,std::ostream &) 
76
      :_parent(parent) {}
77
    _NoSubCounter(P &parent,std::string) 
78
      :_parent(parent) {}
79
    _NoSubCounter(P &parent,const char *,std::ostream &)
80
      :_parent(parent) {}
81
    _NoSubCounter(P &parent,const char *)
82
      :_parent(parent) {}
83
    ~_NoSubCounter() {}
84
    _NoSubCounter &operator++() { ++_parent; return *this;}
85
    int operator++(int) { _parent++; return 0;}
86
    _NoSubCounter &operator--() { --_parent; return *this;}
87
    int operator--(int) { _parent--; return 0;}
88
    _NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
89
    _NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
90
    void reset(int) {}
91
    void reset() {}
92
    operator int() {return 0;}
93
  };
94

	
95

	
96
  /// \addtogroup timecount
97
  /// @{
98

	
99
  ///A counter class
100

	
101
  ///This class makes it easier to count certain events. You can increment
102
  ///or decrement the counter using operator++ and operator--.
103
  ///A report is automatically printed on destruction.
104
  ///\todo More doc
105
  class Counter 
106
  {
107
    std::string _title;
108
    std::ostream &_os;
109
    int count;
110
  public:
111
    ///\e
112

	
113
    ///\todo document please.
114
    ///
115
    typedef _SubCounter<Counter> SubCounter;
116
    ///\e
117

	
118
    ///\todo document please.
119
    ///
120
    typedef _NoSubCounter<Counter> NoSubCounter;
121

	
122
    ///\e
123
    Counter() : _title(), _os(std::cerr), count(0) {}
124
    ///\e
125
    Counter(std::string title,std::ostream &os=std::cerr) 
126
      : _title(title), _os(os), count(0) {}
127
    ///\e
128
    Counter(const char *title,std::ostream &os=std::cerr)
129
      : _title(title), _os(os), count(0) {}
130
    ///Destructor. Prints the given title and the value of the counter.
131
    ~Counter() {
132
      _os << _title << count <<std::endl;
133
    }
134
    ///\e
135
    Counter &operator++() { count++; return *this;}
136
    ///\e
137
    int operator++(int) { return count++;}
138
    ///\e
139
    Counter &operator--() { count--; return *this;}
140
    ///\e
141
    int operator--(int) { return count--;}
142
    ///\e
143
    Counter &operator+=(int c) { count+=c; return *this;}
144
    ///\e
145
    Counter &operator-=(int c) { count-=c; return *this;}
146
    ///\e
147
    void reset(int c=0) {count=c;}
148
    ///\e
149
    operator int() {return count;}
150
  };
151

	
152
  ///'Do nothing' version of \ref Counter
153

	
154
  ///'Do nothing' version of \ref Counter.
155
  ///\sa Counter
156
  class NoCounter
157
  {
158
  public:
159
    typedef _NoSubCounter<NoCounter> SubCounter;
160
    typedef _NoSubCounter<NoCounter> NoSubCounter;
161

	
162
    NoCounter() {}
163
    NoCounter(std::string,std::ostream &) {}
164
    NoCounter(const char *,std::ostream &) {}
165
    NoCounter(std::string) {}
166
    NoCounter(const char *) {}
167
    NoCounter &operator++() { return *this; }
168
    int operator++(int) { return 0; }
169
    NoCounter &operator--() { return *this; }
170
    int operator--(int) { return 0; }
171
    NoCounter &operator+=(int) { return *this;}
172
    NoCounter &operator-=(int) { return *this;}
173
    void reset(int) {}
174
    void reset() {}
175
    operator int() {return 0;}
176
  };
177

	
178
  ///@}
179
}
180

	
181
#endif
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#ifndef LEMON_TIME_MEASURE_H
20
#define LEMON_TIME_MEASURE_H
21

	
22
///\ingroup timecount
23
///\file
24
///\brief Tools for measuring cpu usage
25

	
26
#include <sys/times.h>
27

	
28
#include <sys/time.h>
29
#include <fstream>
30
#include <iostream>
31
#include <unistd.h>
32

	
33
namespace lemon {
34

	
35
  /// \addtogroup timecount
36
  /// @{
37

	
38
  /// A class to store (cpu)time instances.
39

	
40
  /// This class stores five time values.
41
  /// - a real time
42
  /// - a user cpu time
43
  /// - a system cpu time
44
  /// - a user cpu time of children
45
  /// - a system cpu time of children
46
  ///
47
  /// TimeStamp's can be added to or substracted from each other and
48
  /// they can be pushed to a stream.
49
  ///
50
  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
51
  /// class is what you want to use instead.
52
  ///
53
  ///\author Alpar Juttner
54

	
55
  class TimeStamp
56
  {
57
    struct rtms 
58
    {
59
      double tms_utime;
60
      double tms_stime;
61
      double tms_cutime;
62
      double tms_cstime;
63
      rtms() {}
64
      rtms(tms ts) : tms_utime(ts.tms_utime), tms_stime(ts.tms_stime),
65
		     tms_cutime(ts.tms_cutime), tms_cstime(ts.tms_cstime) {}
66
    };
67
    rtms ts;
68
    double real_time;
69
  
70
    rtms &getTms() {return ts;}
71
    const rtms &getTms() const {return ts;}
72

	
73
    void _reset() { 
74
      ts.tms_utime = ts.tms_stime = ts.tms_cutime = ts.tms_cstime = 0; 
75
      real_time = 0;
76
    }
77

	
78
  public:
79

	
80
    ///Read the current time values of the process
81
    void stamp()
82
    {
83
      timeval tv;
84
      tms _ts;
85
      times(&_ts);
86
      gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
87
      ts=_ts;
88
    }
89
  
90
    /// Constructor initializing with zero
91
    TimeStamp()
92
    { _reset(); }
93
    ///Constructor initializing with the current time values of the process
94
    TimeStamp(void *) { stamp();}
95
  
96
    ///Set every time value to zero
97
    TimeStamp &reset() {_reset();return *this;}
98

	
99
    ///\e
100
    TimeStamp &operator+=(const TimeStamp &b)
101
    {
102
      ts.tms_utime+=b.ts.tms_utime;
103
      ts.tms_stime+=b.ts.tms_stime;
104
      ts.tms_cutime+=b.ts.tms_cutime;
105
      ts.tms_cstime+=b.ts.tms_cstime;
106
      real_time+=b.real_time;
107
      return *this;
108
    }
109
    ///\e
110
    TimeStamp operator+(const TimeStamp &b) const
111
    {
112
      TimeStamp t(*this);
113
      return t+=b;
114
    }
115
    ///\e
116
    TimeStamp &operator-=(const TimeStamp &b)
117
    {
118
      ts.tms_utime-=b.ts.tms_utime;
119
      ts.tms_stime-=b.ts.tms_stime;
120
      ts.tms_cutime-=b.ts.tms_cutime;
121
      ts.tms_cstime-=b.ts.tms_cstime;
122
      real_time-=b.real_time;
123
      return *this;
124
    }
125
    ///\e
126
    TimeStamp operator-(const TimeStamp &b) const
127
    {
128
      TimeStamp t(*this);
129
      return t-=b;
130
    }
131
    ///\e
132
    TimeStamp &operator*=(double b)
133
    {
134
      ts.tms_utime*=b;
135
      ts.tms_stime*=b;
136
      ts.tms_cutime*=b;
137
      ts.tms_cstime*=b;
138
      real_time*=b;
139
      return *this;
140
    }
141
    ///\e
142
    TimeStamp operator*(double b) const
143
    {
144
      TimeStamp t(*this);
145
      return t*=b;
146
    }
147
    friend TimeStamp operator*(double b,const TimeStamp &t);
148
    ///\e
149
    TimeStamp &operator/=(double b)
150
    {
151
      ts.tms_utime/=b;
152
      ts.tms_stime/=b;
153
      ts.tms_cutime/=b;
154
      ts.tms_cstime/=b;
155
      real_time/=b;
156
      return *this;
157
    }
158
    ///\e
159
    TimeStamp operator/(double b) const
160
    {
161
      TimeStamp t(*this);
162
      return t/=b;
163
    }
164
    ///The time ellapsed since the last call of stamp()
165
    TimeStamp ellapsed() const
166
    {
167
      TimeStamp t(NULL);
168
      return t-*this;
169
    }
170
  
171
    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
172
  
173
    ///Gives back the user time of the process
174
    double userTime() const
175
    {
176
      return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
177
    }
178
    ///Gives back the system time of the process
179
    double systemTime() const
180
    {
181
      return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
182
    }
183
    ///Gives back the user time of the process' children
184
    double cUserTime() const
185
    {
186
      return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
187
    }
188
    ///Gives back the user time of the process' children
189
    double cSystemTime() const
190
    {
191
      return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
192
    }
193
    ///Gives back the real time
194
    double realTime() const {return real_time;}
195
  };
196

	
197
  TimeStamp operator*(double b,const TimeStamp &t) 
198
  {
199
    return t*b;
200
  }
201
  
202
  ///Prints the time counters
203

	
204
  ///Prints the time counters in the following form:
205
  ///
206
  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
207
  ///
208
  /// where the values are the
209
  /// \li \c u: user cpu time,
210
  /// \li \c s: system cpu time,
211
  /// \li \c cu: user cpu time of children,
212
  /// \li \c cs: system cpu time of children,
213
  /// \li \c real: real time.
214
  /// \relates TimeStamp
215
  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
216
  {
217
    long cls = sysconf(_SC_CLK_TCK);
218
    os << "u: " << double(t.getTms().tms_utime)/cls <<
219
      "s, s: " << double(t.getTms().tms_stime)/cls <<
220
      "s, cu: " << double(t.getTms().tms_cutime)/cls <<
221
      "s, cs: " << double(t.getTms().tms_cstime)/cls <<
222
      "s, real: " << t.realTime() << "s";
223
    return os;
224
  }
225

	
226
  ///Class for measuring the cpu time and real time usage of the process
227

	
228
  ///Class for measuring the cpu time and real time usage of the process.
229
  ///It is quite easy-to-use, here is a short example.
230
  ///\code
231
  /// #include<lemon/time_measure.h>
232
  /// #include<iostream>
233
  ///
234
  /// int main()
235
  /// {
236
  ///
237
  ///   ...
238
  ///
239
  ///   Timer t;
240
  ///   doSomething();
241
  ///   std::cout << t << '\n';
242
  ///   t.restart();
243
  ///   doSomethingElse();
244
  ///   std::cout << t << '\n';
245
  ///
246
  ///   ...
247
  ///
248
  /// }
249
  ///\endcode
250
  ///
251
  ///The \ref Timer can also be \ref stop() "stopped" and
252
  ///\ref start() "started" again, so it is possible to compute collected
253
  ///running times.
254
  ///
255
  ///\warning Depending on the operation system and its actual configuration
256
  ///the time counters have a certain (10ms on a typical Linux system)
257
  ///granularity.
258
  ///Therefore this tool is not appropriate to measure very short times.
259
  ///Also, if you start and stop the timer very frequently, it could lead to
260
  ///distorted results.
261
  ///
262
  ///\note If you want to measure the running time of the execution of a certain
263
  ///function, consider the usage of \ref TimeReport instead.
264
  ///
265
  ///\todo This shouldn't be Unix (Linux) specific.
266
  ///\sa TimeReport
267
  ///
268
  ///\author Alpar Juttner
269
  class Timer
270
  {
271
    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
272
    TimeStamp start_time; //This is the relativ start-time if the timer
273
                          //is _running, the collected _running time otherwise.
274
    
275
    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
276
  
277
  public: 
278
    ///Constructor.
279

	
280
    ///\param run indicates whether or not the timer starts immediately.
281
    ///
282
    Timer(bool run=true) :_running(run) {_reset();}
283

	
284
    ///\name Control the state of the timer
285
    ///Basically a Timer can be either running or stopped,
286
    ///but it provides a bit finer control on the execution.
287
    ///The \ref Timer also counts the number of \ref start()
288
    ///executions, and is stops only after the same amount (or more)
289
    ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
290
    ///of recursive functions.
291
    ///
292

	
293
    ///@{
294

	
295
    ///Reset and stop the time counters
296

	
297
    ///This function resets and stops the time counters
298
    ///\sa restart()
299
    void reset()
300
    {
301
      _running=0;
302
      _reset();
303
    }
304

	
305
    ///Start the time counters
306
    
307
    ///This function starts the time counters.
308
    ///
309
    ///If the timer is started more than ones, it will remain running
310
    ///until the same amount of \ref stop() is called.
311
    ///\sa stop()
312
    void start() 
313
    {
314
      if(_running) _running++;
315
      else {
316
	_running=1;
317
	TimeStamp t;
318
	t.stamp();
319
	start_time=t-start_time;
320
      }
321
    }
322

	
323
    
324
    ///Stop the time counters
325

	
326
    ///This function stops the time counters. If start() was executed more than
327
    ///once, then the same number of stop() execution is necessary the really
328
    ///stop the timer.
329
    /// 
330
    ///\sa halt()
331
    ///\sa start()
332
    ///\sa restart()
333
    ///\sa reset()
334

	
335
    void stop() 
336
    {
337
      if(_running && !--_running) {
338
	TimeStamp t;
339
	t.stamp();
340
	start_time=t-start_time;
341
      }
342
    }
343

	
344
    ///Halt (i.e stop immediately) the time counters
345

	
346
    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
347
    ///is a faster
348
    ///equivalent of the following.
349
    ///\code
350
    ///  while(t.running()) t.stop()
351
    ///\endcode
352
    ///
353
    ///
354
    ///\sa stop()
355
    ///\sa restart()
356
    ///\sa reset()
357

	
358
    void halt() 
359
    {
360
      if(_running) {
361
	_running=0;
362
	TimeStamp t;
363
	t.stamp();
364
	start_time=t-start_time;
365
      }
366
    }
367

	
368
    ///Returns the running state of the timer
369

	
370
    ///This function returns the number of stop() exections that is
371
    ///necessary to really stop the timer.
372
    ///For example the timer
373
    ///is running if and only if the return value is \c true
374
    ///(i.e. greater than
375
    ///zero).
376
    int running()  { return _running; }
377
    
378
    
379
    ///Restart the time counters
380

	
381
    ///This function is a shorthand for
382
    ///a reset() and a start() calls.
383
    ///
384
    void restart() 
385
    {
386
      reset();
387
      start();
388
    }
389
    
390
    ///@}
391

	
392
    ///\name Query Functions for the ellapsed time
393

	
394
    ///@{
395

	
396
    ///Gives back the ellapsed user time of the process
397
    double userTime() const
398
    {
399
      return operator TimeStamp().userTime();
400
    }
401
    ///Gives back the ellapsed system time of the process
402
    double systemTime() const
403
    {
404
      return operator TimeStamp().systemTime();
405
    }
406
    ///Gives back the ellapsed user time of the process' children
407
    double cUserTime() const
408
    {
409
      return operator TimeStamp().cUserTime();
410
    }
411
    ///Gives back the ellapsed user time of the process' children
412
    double cSystemTime() const
413
    {
414
      return operator TimeStamp().cSystemTime();
415
    }
416
    ///Gives back the ellapsed real time
417
    double realTime() const
418
    {
419
      return operator TimeStamp().realTime();
420
    }
421
    ///Computes the ellapsed time
422

	
423
    ///This conversion computes the ellapsed time, therefore you can print
424
    ///the ellapsed time like this.
425
    ///\code
426
    ///  Timer t;
427
    ///  doSomething();
428
    ///  std::cout << t << '\n';
429
    ///\endcode
430
    operator TimeStamp () const
431
    {
432
      TimeStamp t;
433
      t.stamp();
434
      return _running?t-start_time:start_time;
435
    }
436

	
437

	
438
    ///@}
439
  };
440

	
441
  ///Same as \ref Timer but prints a report on destruction.
442

	
443
  ///Same as \ref Timer but prints a report on destruction.
444
  ///This example shows its usage.
445
  ///\code
446
  ///  void myAlg(ListGraph &g,int n)
447
  ///  {
448
  ///    TimeReport tr("Running time of myAlg: ");
449
  ///    ... //Here comes the algorithm
450
  ///  }
451
  ///\endcode
452
  ///
453
  ///\sa Timer
454
  ///\sa NoTimeReport
455
  ///\todo There is no test case for this
456
  class TimeReport : public Timer 
457
  {
458
    std::string _title;
459
    std::ostream &_os;
460
  public:
461
    ///\e
462

	
463
    ///\param title This text will be printed before the ellapsed time.
464
    ///\param os The stream to print the report to.
465
    ///\param run Sets whether the timer should start immediately.
466

	
467
    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 
468
      : Timer(run), _title(title), _os(os){}
469
    ///\e Prints the ellapsed time on destruction.
470
    ~TimeReport() 
471
    {
472
      _os << _title << *this << std::endl;
473
    }
474
  };
475
      
476
  ///'Do nothing' version of \ref TimeReport
477

	
478
  ///\sa TimeReport
479
  ///
480
  class NoTimeReport
481
  {
482
  public:
483
    ///\e
484
    NoTimeReport(std::string,std::ostream &,bool) {}
485
    ///\e
486
    NoTimeReport(std::string,std::ostream &) {}
487
    ///\e
488
    NoTimeReport(std::string) {}
489
    ///\e Do nothing.
490
    ~NoTimeReport() {}
491

	
492
    operator TimeStamp () const { return TimeStamp(); }
493
    void reset() {}
494
    void start() {}
495
    void stop() {}
496
    void halt() {} 
497
    int running() { return 0; }
498
    void restart() {}
499
    double userTime() const { return 0; }
500
    double systemTime() const { return 0; }
501
    double cUserTime() const { return 0; }
502
    double cSystemTime() const { return 0; }
503
    double realTime() const { return 0; }
504
  };
505
      
506
  ///Tool to measure the running time more exactly.
507
  
508
  ///This function calls \c f several times and returns the average
509
  ///running time. The number of the executions will be choosen in such a way
510
  ///that the full real running time will be roughly between \c min_time
511
  ///and <tt>2*min_time</tt>.
512
  ///\param f the function object to be measured.
513
  ///\param min_time the minimum total running time.
514
  ///\retval num if it is not \c NULL, then the actual
515
  ///        number of execution of \c f will be written into <tt>*num</tt>.
516
  ///\retval full_time if it is not \c NULL, then the actual
517
  ///        total running time will be written into <tt>*full_time</tt>.
518
  ///\return The average running time of \c f.
519
  
520
  template<class F>
521
  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
522
                            TimeStamp *full_time=NULL)
523
  {
524
    TimeStamp full;
525
    unsigned int total=0;
526
    Timer t;
527
    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
528
      for(;total<tn;total++) f();
529
      full=t;
530
    }
531
    if(num) *num=total;
532
    if(full_time) *full_time=full;
533
    return full/total;
534
  }
535
  
536
  /// @}  
537

	
538

	
539
} //namespace lemon
540

	
541
#endif //LEMON_TIME_MEASURE_H
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <lemon/counter.h>
20

	
21
///\file \brief Test cases for time_measure.h
22
///
23
///\todo To be extended
24

	
25

	
26
int fibonacci(int f) 
27
{
28
  static lemon::Counter count("Fibonacci steps: ");
29
  count++;
30
  if(f<1) return 0;
31
  else if(f==1) return 1;
32
  else return fibonacci(f-1)+fibonacci(f-2);
33
}
34

	
35
int main()
36
{
37
  fibonacci(10);
38
  
39
  {  
40
    typedef lemon::Counter MyCounter;
41
    MyCounter c("Main counter: ");
42
    c++;
43
    c++;
44
    MyCounter::SubCounter d(c,"Subcounter: ");
45
    d++;
46
    d++;
47
    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
48
    e++;
49
    e++;
50
  }
51
  
52
  {
53
    typedef lemon::NoCounter MyCounter;
54
    MyCounter c("Main counter: ");
55
    c++;
56
    c++;
57
    MyCounter::SubCounter d(c,"Subcounter: ");
58
    d++;
59
    d++;
60
    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
61
    e++;
62
    e++;
63
  }
64

	
65
  return 0;
66
}
Ignore white space 6 line context
1
/* -*- C++ -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <lemon/time_measure.h>
20

	
21
///\file \brief Test cases for time_measure.h
22
///
23
///\todo To be extended
24

	
25

	
26
using namespace lemon;
27

	
28
void f() 
29
{
30
  double d=0;
31
  for(int i=0;i<1000;i++)
32
    d+=0.1;
33
}
34

	
35
void g() 
36
{
37
  static Timer T;
38
  
39
  for(int i=0;i<1000;i++)
40
    TimeStamp x(T);
41
}
42

	
43
int main()
44
{
45
  Timer T;
46
  unsigned int n;
47
  for(n=0;T.realTime()<1.0;n++) ;
48
  std::cout << T << " (" << n << " time queries)\n";
49
  T.restart();
50
  while(T.realTime()<2.0) ;
51
  std::cout << T << '\n';
52
  TimeStamp full;
53
  TimeStamp t;
54
  t=runningTimeTest(f,1,&n,&full);
55
  std::cout << t << " (" << n << " tests)\n";
56
  std::cout << "Total: " << full << "\n";
57
  
58
  t=runningTimeTest(g,1,&n,&full);
59
  std::cout << t << " (" << n << " tests)\n";
60
  std::cout << "Total: " << full << "\n";
61
  
62
  return 0;
63
}
Ignore white space 6 line context
... ...
@@ -20,6 +20,7 @@
20 20
	lemon/assert.h \
21 21
        lemon/bfs.h \
22 22
        lemon/bin_heap.h \
23
        lemon/counter.h \
23 24
        lemon/dfs.h \
24 25
        lemon/dijkstra.h \
25 26
        lemon/dim2.h \
... ...
@@ -32,6 +33,7 @@
32 33
	lemon/path.h \
33 34
        lemon/random.h \
34 35
	lemon/smart_graph.h \
36
        lemon/time_measure.h \
35 37
        lemon/tolerance.h \
36 38
	lemon/unionfind.h
37 39

	
Ignore white space 6 line context
... ...
@@ -27,71 +27,6 @@
27 27

	
28 28
namespace lemon {
29 29

	
30
  /// @{
31

	
32
  ///\e
33
  class AssertionFailedError : public LogicError {
34
  protected:
35
    const char *_assertion;
36
    const char *_file;
37
    int _line;
38
    const char *_function;
39
    const char *_message;
40

	
41
    mutable ExceptionMember<std::string> _message_holder;
42
  public:
43
    ///\e
44
    AssertionFailedError(const char *file, int line, const char *function,
45
			 const char *msg, const char *assertion = 0) :
46
      _assertion(assertion), _file(file), _line(line), 
47
      _function(function), _message(msg) {}
48

	
49
    ///\e
50
    const char* assertion() const { return _assertion; }
51
    ///\e
52
    const char* message() const { return _message; }
53
    ///\e
54
    const char* file() const { return _file; }
55
    ///\e
56
    const char* function() const { return _function; }
57
    ///\e
58
    int line() const { return _line; }
59

	
60

	
61
    virtual const char* what() const throw() {
62
      try {
63
	std::ostringstream ostr;
64
	ostr << _file << ":" << _line << ": ";
65
	if (_function)
66
	  ostr << _function << ": ";
67
	ostr << _message;
68
	if (_assertion)
69
	   ostr << " (assertion '" << _assertion << "' failed)";
70
	_message_holder.set(ostr.str());
71
	return ostr.str().c_str();
72
      }
73
      catch(...) {}
74
      if( _message_holder.valid() ) return _message_holder.get().c_str();
75
      return "lemon::AssertionFailedError";
76
    }
77
    virtual ~AssertionFailedError() throw() {}
78
  };
79

	
80

	
81
  inline void assert_fail_log(const char *file, int line,
82
			      const char *function,
83
			      const std::exception& exception, 
84
			      const char *assertion)
85
  {
86
    std::cerr << file << ":" << line << ": ";
87
    if (function)
88
      std::cerr << function << ": ";
89
    std::cerr << exception.what();
90
    if (assertion)
91
      std::cerr << " (assertion '" << assertion << "' failed)";
92
    std::cerr << std::endl;
93
  }
94

	
95 30
  inline void assert_fail_log(const char *file, int line, const char *function,
96 31
			      const char *message, const char *assertion)
97 32
  {
... ...
@@ -104,21 +39,6 @@
104 39
    std::cerr << std::endl;
105 40
  }
106 41

	
107
  inline void assert_fail_log(const char *file, int line, const char *function, 
108
			      const std::string& message, const char *assertion)
109
  {
110
    assert_fail_log(file, line, function, message.c_str(), assertion);
111
  }
112

	
113
  inline void assert_fail_abort(const char *file, int line, 
114
				const char *function,
115
				const std::exception& exception,
116
				const char *assertion)
117
  {
118
    assert_fail_log(file, line, function, exception, assertion);
119
    std::abort();
120
  }
121

	
122 42
  inline void assert_fail_abort(const char *file, int line,
123 43
				const char *function, const char* message,
124 44
				const char *assertion)
... ...
@@ -127,86 +47,37 @@
127 47
    std::abort();
128 48
  }
129 49

	
130
  inline void assert_fail_abort(const char *file, int line, 
131
				const char *function, 
132
				const std::string& message,
133
				const char *assertion)
134
  {
135
    assert_fail_log(file, line, function, message.c_str(), assertion);
136
    std::abort();
50
  namespace _assert_bits {
51
    
52
    
53
    inline const char* cstringify(const std::string& str) {
54
      return str.c_str();
55
    }
56

	
57
    inline const char* cstringify(const char* str) {
58
      return str;
59
    }    
137 60
  }
61
}
138 62

	
139
  inline void assert_fail_error(const char *file, int line, 
140
				  const char *function,
141
				  const std::exception& exception,
142
				  const char *assertion)
143
  {
144
    throw AssertionFailedError(file, line, function, 
145
			       exception.what(), assertion);
146
  }
147

	
148
  inline void assert_fail_error(const char *file, int line,
149
				  const char *function, const char *message,
150
				  const char *assertion)
151
  {
152
    throw AssertionFailedError(file, line, function, message, assertion);
153
  }
154

	
155
  inline void assert_fail_error(const char *file, int line,
156
				  const char *function, 
157
				  const std::string& message,
158
				  const char *assertion)
159
  {
160
    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
161
  }
162

	
163
  template <typename Exception>
164
  inline void assert_fail_exception(const char *, int, const char *,
165
				    const Exception& exception,
166
				    const char *, const std::exception* = 
167
				    static_cast<const Exception*>(0))
168
  {
169
    throw exception;
170
  }
171

	
172
  inline void assert_fail_exception(const char *file, int line,
173
				    const char *function, const char *message,
174
				    const char *assertion)
175
  {
176
    throw AssertionFailedError(file, line, function, message, assertion);
177
  }
178

	
179
  inline void assert_fail_exception(const char *file, int line, 
180
				    const char *function, 
181
				    const std::string& message,
182
				    const char *assertion)
183
  {
184
    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
185
  }
186

	
187
/// @}
188

	
189
}
190 63
#endif // LEMON_ASSERT_H
191 64

	
192 65
#undef LEMON_ASSERT
193 66
#undef LEMON_FIXME
67
#undef LEMON_DEBUG
194 68

	
195 69
#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
196 70
  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
197
  (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
198
  (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +		\
199 71
  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
200 72
#error "LEMON assertion system is not set properly"
201 73
#endif
202 74

	
203 75
#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
204 76
     (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
205
     (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
206
     (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +	\
207 77
     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||	\
208 78
     defined(LEMON_ENABLE_ASSERTS)) &&			\
209
  defined(LEMON_DISABLE_ASSERTS)
79
  (defined(LEMON_DISABLE_ASSERTS) ||			\
80
   defined(NDEBUG))
210 81
#error "LEMON assertion system is not set properly"
211 82
#endif
212 83

	
... ...
@@ -217,26 +88,20 @@
217 88
#elif defined LEMON_ASSERT_ABORT
218 89
#  undef LEMON_ASSERT_HANDLER
219 90
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
220
#elif defined LEMON_ASSERT_ERROR
221
#  undef LEMON_ASSERT_HANDLER
222
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
223
#elif defined LEMON_ASSERT_EXCEPTION
224
#  undef LEMON_ASSERT_HANDLER
225
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
226 91
#elif defined LEMON_ASSERT_CUSTOM
227 92
#  undef LEMON_ASSERT_HANDLER
228 93
#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
229 94
#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
230 95
#  endif
231 96
#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
232
#elif defined LEMON_ENABLE_ASSERTS
97
#elif defined LEMON_DISABLE_ASSERTS
233 98
#  undef LEMON_ASSERT_HANDLER
99
#elif defined NDEBUG
100
#  undef LEMON_ASSERT_HANDLER
101
#else
234 102
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
235
#else
236
#  undef LEMON_ASSERT_HANDLER
237 103
#endif
238 104

	
239

	
240 105
#ifndef LEMON_FUNCTION_NAME
241 106
#  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
242 107
#endif
... ...
@@ -247,24 +112,24 @@
247 112
///
248 113
/// \brief Macro for assertion with customizable message
249 114
///
250
/// Macro for assertion with customizable message.  
251
/// \param exp An expression that must be convertible to \c bool.
252
/// If it is \c false, then an assertion is raised. The concrete
253
/// behaviour depends on the settings of the assertion system.
254
/// \param msg A <tt>const char*</tt>, a <tt>const std::string&</tt> or
255
/// a <tt>const std::exception&</tt> parameter, which can be used to
256
/// provide information about the circumstances of the failed assertion.
115
/// Macro for assertion with customizable message.  \param exp An
116
/// expression that must be convertible to \c bool.  If it is \c
117
/// false, then an assertion is raised. The concrete behaviour depends
118
/// on the settings of the assertion system.  \param msg A <tt>const
119
/// char*</tt> parameter, which can be used to provide information
120
/// about the circumstances of the failed assertion.
257 121
///
258
/// The assertions are disabled in the default behaviour.
259
/// You can enable them with the following code:
122
/// The assertions are enabled in the default behaviour.
123
/// You can disable them with the following code:
260 124
/// \code
261
/// #define LEMON_ENABLE_ASSERTS
125
/// #define LEMON_DISABLE_ASSERTS
262 126
/// \endcode
263 127
/// or with compilation parameters:
264 128
/// \code
265
/// g++ -DLEMON_ENABLE_ASSERTS
266
/// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS'
129
/// g++ -DLEMON_DISABLE_ASSERTS
130
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
267 131
/// \endcode
132
/// The checking is also disabled when the standard macro \c NDEBUG is defined.
268 133
/// 
269 134
/// The LEMON assertion system has a wide range of customization
270 135
/// properties. As a default behaviour the failed assertion prints a
... ...
@@ -274,38 +139,22 @@
274 139
///
275 140
/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
276 141
///   message to the standard error and continues the execution.
277
/// - \c LEMON_ASSERT_ABORT This mode is similar to the
278
///   \c LEMON_ASSERT_LOG, but it aborts the program. It is the default
279
///   behaviour mode when the assertions are enabled with
280
///   \c LEMON_ENABLE_ASSERTS.
281
/// - \c LEMON_ASSERT_ERROR The assertion throws an
282
///   \ref lemon::AssertionFailedError "AssertionFailedError".
283
///   If the \c msg parameter is an exception, then the result of the
284
///   \ref lemon::Exception::what() "what()" member function is passed
285
///   as error message.
286
/// - \c LEMON_ASSERT_EXCEPTION If the specified \c msg is an
287
///   exception, then it raised directly (solving that the exception
288
///   can not be thrown polymorphically), otherwise an \ref
289
///   lemon::AssertionFailedError "AssertionFailedError" is thrown with
290
///   the given parameters.
142
/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
143
///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
144
///   behaviour.
291 145
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
292
///   functions. Three overloaded functions should be defined with the
293
///   following parameter lists:
146
///   function.
294 147
///   \code
295 148
///     void custom_assert_handler(const char* file, int line, const char* function,
296 149
///                                const char* message, const char* assertion);
297
///     void custom_assert_handler(const char* file, int line, const char* function,
298
///                                const std::string& message, const char* assertion);
299
///     void custom_assert_handler(const char* file, int line, const char* function,
300
///                                const std::exception& message, const char* assertion);
301 150
///   \endcode
302
///   The name of the functions should be defined as the \c
151
///   The name of the function should be defined as the \c
303 152
///   LEMON_CUSTOM_ASSERT_HANDLER macro name. 
304 153
///   \code
305 154
///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
306 155
///   \endcode
307
///   Whenever an assertion is occured, one of the custom assertion
308
///   handlers is called with appropiate parameters.
156
///   Whenever an assertion is occured, the custom assertion
157
///   handler is called with appropiate parameters.
309 158
///
310 159
/// The assertion mode can also be changed within one compilation unit.
311 160
/// If the macros are redefined with other settings and the
... ...
@@ -315,8 +164,7 @@
315 164
  (static_cast<void> (!!(exp) ? 0 : (					\
316 165
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,				\
317 166
			 LEMON_FUNCTION_NAME,				\
318
			 msg, #exp), 0)))
319

	
167
			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
320 168

	
321 169
/// \ingroup exceptions
322 170
///
... ...
@@ -327,26 +175,80 @@
327 175
/// \code
328 176
///   LEMON_ASSERT(false, msg);
329 177
/// \endcode
178
///
179
/// \see LEMON_ASSERT 
330 180
#  define LEMON_FIXME(msg)						\
331
       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
332
			     "FIXME: " msg, static_cast<const char*>(0)))
181
  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
182
			::lemon::_assert_bits::cstringify(msg),		\
183
			static_cast<const char*>(0)))
184

	
185
/// \ingroup exceptions
186
///
187
/// \brief Macro for internal assertions
188
///
189
/// Macro for internal assertions, it is used in the library to check
190
/// the consistency of results of algorithms, several pre- and
191
/// postconditions and invariants. The checking is disabled by
192
/// default, but it can be turned on with the macro \c
193
/// LEMON_ENABLE_DEBUG.
194
/// \code
195
/// #define LEMON_ENABLE_DEBUG
196
/// \endcode
197
/// or with compilation parameters:
198
/// \code
199
/// g++ -DLEMON_ENABLE_DEBUG
200
/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
201
/// \endcode
202
///
203
/// This macro works like the \c LEMON_ASSERT macro, therefore the
204
/// current behaviour depends on the settings of \c LEMON_ASSERT
205
/// macro.
206
///
207
/// \see LEMON_ASSERT 
208
#  define LEMON_DEBUG(exp, msg)						\
209
  (static_cast<void> (!!(exp) ? 0 : (					\
210
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
211
			 LEMON_FUNCTION_NAME,				\
212
			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
333 213

	
334 214
#else
335 215

	
336 216
#  ifndef LEMON_ASSERT_HANDLER
337 217
#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
338 218
#    define LEMON_FIXME(msg) (static_cast<void>(0))
219
#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
339 220
#  else
340
#    define LEMON_ASSERT(exp, msg)                 \
341
       (static_cast<void> (!!(exp) ? 0 : (         \
342
         LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
343
                              LEMON_FUNCTION_NAME, \
344
                              msg, #exp), 0)))
345
#    define LEMON_FIXME(msg) \
221
#    define LEMON_ASSERT(exp, msg)					\
222
       (static_cast<void> (!!(exp) ? 0 : (				\
223
        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
224
			     LEMON_FUNCTION_NAME,			\
225
			     ::lemon::_assert_bits::cstringify(msg),	\
226
			     #exp), 0)))
227
#    define LEMON_FIXME(msg)						\
346 228
       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
347
			     "FIXME: " msg,  static_cast<const char*>(0)))
229
			     ::lemon::_assert_bits::cstringify(msg),	\
230
			     static_cast<const char*>(0)))
231

	
232
#    if LEMON_ENABLE_DEBUG
233
#      define LEMON_DEBUG(exp, msg)
234
         (static_cast<void> (!!(exp) ? 0 : (         \
235
           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
236
                                LEMON_FUNCTION_NAME, \
237
				::lemon::_assert_bits::cstringify(msg),	\
238
				#exp), 0)))
239
#    else
240
#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
241
#    endif
348 242
#  endif
349 243

	
350 244
#endif
351 245

	
246
#ifdef DOXYGEN
352 247

	
248

	
249
#else
250

	
251

	
252
#endif
253

	
254

	
Ignore white space 6 line context
... ...
@@ -21,13 +21,13 @@
21 21

	
22 22
// Boost enable_if library
23 23

	
24
// Copyright 2003 � The Trustees of Indiana University.
24
// Copyright 2003 (c) The Trustees of Indiana University.
25 25

	
26 26
// Use, modification, and distribution is subject to the Boost Software
27 27
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
28 28
// http://www.boost.org/LICENSE_1_0.txt)
29 29

	
30
//    Authors: Jaakko J�rvi (jajarvi at osl.iu.edu)
30
//    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
31 31
//             Jeremiah Willcock (jewillco at osl.iu.edu)
32 32
//             Andrew Lumsdaine (lums at osl.iu.edu)
33 33

	
Ignore white space 6 line context
... ...
@@ -9,6 +9,7 @@
9 9

	
10 10
check_PROGRAMS += \
11 11
	test/bfs_test \
12
        test/counter_test \
12 13
	test/dfs_test \
13 14
	test/digraph_test \
14 15
        test/dim_test \
... ...
@@ -20,12 +21,14 @@
20 21
        test/path_test \
21 22
        test/test_tools_fail \
22 23
        test/test_tools_pass \
24
        test/time_measure_test \
23 25
	test/unionfind_test
24 26

	
25 27
TESTS += $(check_PROGRAMS)
26 28
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
27 29

	
28 30
test_bfs_test_SOURCES = test/bfs_test.cc
31
test_counter_test_SOURCES = test/counter_test.cc
29 32
test_dfs_test_SOURCES = test/dfs_test.cc
30 33
test_digraph_test_SOURCES = test/digraph_test.cc
31 34
test_dim_test_SOURCES = test/dim_test.cc
... ...
@@ -38,4 +41,5 @@
38 41
test_random_test_SOURCES = test/random_test.cc
39 42
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
40 43
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
44
test_time_measure_test_SOURCES = test/time_measure_test.cc
41 45
test_unionfind_test_SOURCES = test/unionfind_test.cc
Ignore white space 6 line context
... ...
@@ -39,165 +39,21 @@
39 39
  LEMON_ASSERT(true, "This is a fault message");
40 40
}
41 41

	
42
void no_assertion_exception_disable() {
43
  LEMON_ASSERT(true, Exception());
44
}
45

	
46 42
void assertion_text_disable() {
47 43
  LEMON_ASSERT(false, "This is a fault message");
48 44
}
49 45

	
50
void assertion_exception_disable() {
51
  LEMON_ASSERT(false, Exception());
52
}
53

	
54 46
void fixme_disable() {
55 47
  LEMON_FIXME("fixme_disable() is fixme!");
56 48
}
57 49

	
58 50
void check_assertion_disable() {
59 51
  no_assertion_text_disable();
60
  no_assertion_exception_disable();
61
  assertion_exception_disable();
62 52
  assertion_text_disable();
63 53
  fixme_disable();
64 54
}
65 55
#undef LEMON_DISABLE_ASSERTS
66 56

	
67

	
68
#define LEMON_ASSERT_ERROR
69
#include <lemon/assert.h>
70

	
71
void no_assertion_text_error() {
72
  LEMON_ASSERT(true, "This is a fault message");
73
}
74

	
75
void no_assertion_exception_error() {
76
  LEMON_ASSERT(true, Exception());
77
}
78

	
79
void assertion_text_error() {
80
  LEMON_ASSERT(false, "This is a fault message");
81
}
82

	
83
void assertion_exception_error() {
84
  LEMON_ASSERT(false, Exception());
85
}
86

	
87
void fixme_error() {
88
  LEMON_FIXME("fixme_error() is fixme!");
89
}
90

	
91
void check_assertion_error() {
92
  no_assertion_text_error();
93
  no_assertion_exception_error();
94
  try {
95
    assertion_exception_error();
96
    check(false, "Assertion error");
97
  } catch (const AssertionFailedError& e) {
98
  }
99

	
100
  try {
101
    assertion_text_error();
102
    check(false, "Assertion error");
103
  } catch (const AssertionFailedError& e) {
104
  }
105

	
106
  try {
107
    fixme_error();
108
    check(false, "Assertion error");
109
  } catch (const AssertionFailedError& e) {
110
  }
111
}
112
#undef LEMON_ASSERT_ERROR
113

	
114
#define LEMON_ASSERT_EXCEPTION
115
#include <lemon/assert.h>
116

	
117
void no_assertion_text_exception() {
118
  LEMON_ASSERT(true, "This is a fault message");
119
}
120

	
121
void no_assertion_exception_exception() {
122
  LEMON_ASSERT(true, Exception());
123
}
124

	
125
void assertion_text_exception() {
126
  LEMON_ASSERT(false, "This is a fault message");
127
}
128

	
129
void assertion_exception_exception() {
130
  LEMON_ASSERT(false, Exception());
131
}
132

	
133
void fixme_exception() {
134
  LEMON_FIXME("fixme_exception() is fixme!");
135
}
136

	
137
void check_assertion_exception() {
138
  no_assertion_text_exception();
139
  no_assertion_exception_exception();
140
  try {
141
    assertion_exception_exception();
142
    check(false, "Assertion error");
143
  } catch (const Exception& e) {
144
  }
145

	
146
  try {
147
    assertion_text_exception();
148
    check(false, "Assertion error");
149
  } catch (const AssertionFailedError& e) {
150
  }
151

	
152
  try {
153
    assertion_text_exception();
154
    check(false, "Assertion error");
155
  } catch (const AssertionFailedError& e) {
156
  }
157

	
158
  try {
159
    fixme_exception();
160
    check(false, "Assertion error");
161
  } catch (const AssertionFailedError& e) {
162
  }
163
}
164
#undef LEMON_ASSERT_EXCEPTION
165

	
166
#define LEMON_ASSERT_LOG
167

	
168
#include <lemon/assert.h>
169

	
170
void no_assertion_text_log() {
171
  LEMON_ASSERT(true, "This is a fault message");
172
}
173

	
174
void no_assertion_exception_log() {
175
  LEMON_ASSERT(true, Exception());
176
}
177

	
178
void assertion_text_log() {
179
  LEMON_ASSERT(false, "This is a fault message");
180
}
181

	
182
void assertion_exception_log() {
183
  LEMON_ASSERT(false, Exception());
184
}
185

	
186
void fixme_log() {
187
  LEMON_FIXME("fixme_log() is fixme!");
188
}
189

	
190
void check_assertion_log() {
191
  no_assertion_text_log();
192
  no_assertion_exception_log();
193
  std::cerr << "The next 3 failure messages are expected: " << std::endl;
194
  assertion_exception_log();
195
  assertion_text_log();
196
  fixme_log();
197
  std::cerr << "End of expected error messages" << std::endl;
198
}
199
#undef LEMON_ASSERT_LOG
200

	
201 57
#define LEMON_ASSERT_CUSTOM
202 58

	
203 59
static int cnt = 0;
... ...
@@ -206,17 +62,6 @@
206 62
  ++cnt;
207 63
}
208 64

	
209
void my_assert_handler(const char*, int, const char*, 
210
		       const std::exception&, const char*) {
211
  ++cnt;
212
}
213

	
214
void my_assert_handler(const char*, int, const char*, 
215
		       const std::string&, const char*) {
216
  ++cnt;
217
}
218

	
219

	
220 65
#define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
221 66
#include <lemon/assert.h>
222 67

	
... ...
@@ -224,29 +69,19 @@
224 69
  LEMON_ASSERT(true, "This is a fault message");
225 70
}
226 71

	
227
void no_assertion_exception_custom() {
228
  LEMON_ASSERT(true, Exception());
229
}
230

	
231 72
void assertion_text_custom() {
232 73
  LEMON_ASSERT(false, "This is a fault message");
233 74
}
234 75

	
235
void assertion_exception_custom() {
236
  LEMON_ASSERT(false, Exception());
237
}
238

	
239 76
void fixme_custom() {
240 77
  LEMON_FIXME("fixme_custom() is fixme!");
241 78
}
242 79

	
243 80
void check_assertion_custom() {
244 81
  no_assertion_text_custom();
245
  no_assertion_exception_custom();
246
  assertion_exception_custom();
247 82
  assertion_text_custom();
248 83
  fixme_custom();
249
  check(cnt == 3, "The custom assert handler does not work");
84
  check(cnt == 2, "The custom assert handler does not work");
250 85
}
251 86

	
252 87
#undef LEMON_ASSERT_CUSTOM
... ...
@@ -254,9 +89,6 @@
254 89

	
255 90
int main() {
256 91
  check_assertion_disable();
257
  check_assertion_error();
258
  check_assertion_exception();
259
  check_assertion_log();
260 92
  check_assertion_custom();
261 93

	
262 94
  return 0;
0 comments (0 inline)