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

	
19 19
#ifndef LEMON_GRAPH_TO_EPS_H
20 20
#define LEMON_GRAPH_TO_EPS_H
21 21

	
22 22
#include<iostream>
23 23
#include<fstream>
24 24
#include<sstream>
25 25
#include<algorithm>
26 26
#include<vector>
27 27

	
28 28
#ifndef WIN32
29 29
#include<sys/time.h>
30 30
#include<ctime>
31 31
#else
32
#ifndef WIN32_LEAN_AND_MEAN
32 33
#define WIN32_LEAN_AND_MEAN
34
#endif
35
#ifndef NOMINMAX
33 36
#define NOMINMAX
37
#endif
34 38
#include<windows.h>
35 39
#endif
36 40

	
37 41
#include<lemon/math.h>
38 42
#include<lemon/core.h>
39 43
#include<lemon/dim2.h>
40 44
#include<lemon/maps.h>
41 45
#include<lemon/color.h>
42 46
#include<lemon/bits/bezier.h>
43 47
#include<lemon/error.h>
44 48

	
45 49

	
46 50
///\ingroup eps_io
47 51
///\file
48 52
///\brief A well configurable tool for visualizing graphs
49 53

	
50 54
namespace lemon {
51 55

	
52 56
  namespace _graph_to_eps_bits {
53 57
    template<class MT>
54 58
    class _NegY {
55 59
    public:
56 60
      typedef typename MT::Key Key;
57 61
      typedef typename MT::Value Value;
58 62
      const MT &map;
59 63
      int yscale;
60 64
      _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {}
61 65
      Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);}
62 66
    };
63 67
  }
64 68

	
65 69
///Default traits class of GraphToEps
66 70

	
67 71
///Default traits class of \ref GraphToEps.
68 72
///
69 73
///\c G is the type of the underlying graph.
70 74
template<class G>
71 75
struct DefaultGraphToEpsTraits
72 76
{
73 77
  typedef G Graph;
74 78
  typedef typename Graph::Node Node;
75 79
  typedef typename Graph::NodeIt NodeIt;
76 80
  typedef typename Graph::Arc Arc;
77 81
  typedef typename Graph::ArcIt ArcIt;
78 82
  typedef typename Graph::InArcIt InArcIt;
79 83
  typedef typename Graph::OutArcIt OutArcIt;
80 84

	
81 85

	
82 86
  const Graph &g;
83 87

	
84 88
  std::ostream& os;
85 89

	
86 90
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
87 91
  CoordsMapType _coords;
88 92
  ConstMap<typename Graph::Node,double > _nodeSizes;
89 93
  ConstMap<typename Graph::Node,int > _nodeShapes;
90 94

	
91 95
  ConstMap<typename Graph::Node,Color > _nodeColors;
92 96
  ConstMap<typename Graph::Arc,Color > _arcColors;
93 97

	
94 98
  ConstMap<typename Graph::Arc,double > _arcWidths;
95 99

	
96 100
  double _arcWidthScale;
97 101

	
98 102
  double _nodeScale;
99 103
  double _xBorder, _yBorder;
100 104
  double _scale;
101 105
  double _nodeBorderQuotient;
102 106

	
103 107
  bool _drawArrows;
104 108
  double _arrowLength, _arrowWidth;
105 109

	
106 110
  bool _showNodes, _showArcs;
107 111

	
108 112
  bool _enableParallel;
109 113
  double _parArcDist;
110 114

	
111 115
  bool _showNodeText;
112 116
  ConstMap<typename Graph::Node,bool > _nodeTexts;
113 117
  double _nodeTextSize;
114 118

	
115 119
  bool _showNodePsText;
116 120
  ConstMap<typename Graph::Node,bool > _nodePsTexts;
117 121
  char *_nodePsTextsPreamble;
118 122

	
119 123
  bool _undirected;
120 124

	
121 125
  bool _pleaseRemoveOsStream;
122 126

	
123 127
  bool _scaleToA4;
124 128

	
125 129
  std::string _title;
126 130
  std::string _copyright;
127 131

	
128 132
  enum NodeTextColorType
129 133
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
130 134
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
131 135

	
132 136
  bool _autoNodeScale;
133 137
  bool _autoArcWidthScale;
134 138

	
135 139
  bool _absoluteNodeSizes;
136 140
  bool _absoluteArcWidths;
137 141

	
138 142
  bool _negY;
139 143

	
140 144
  bool _preScale;
141 145
  ///Constructor
142 146

	
143 147
  ///Constructor
144 148
  ///\param _g  Reference to the graph to be printed.
145 149
  ///\param _os Reference to the output stream.
146 150
  ///\param _os Reference to the output stream.
147 151
  ///By default it is <tt>std::cout</tt>.
148 152
  ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
149 153
  ///will be explicitly deallocated by the destructor.
150 154
  DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
151 155
                          bool _pros=false) :
152 156
    g(_g), os(_os),
153 157
    _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
154 158
    _nodeColors(WHITE), _arcColors(BLACK),
155 159
    _arcWidths(1.0), _arcWidthScale(0.003),
156 160
    _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0),
157 161
    _nodeBorderQuotient(.1),
158 162
    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
159 163
    _showNodes(true), _showArcs(true),
160 164
    _enableParallel(false), _parArcDist(1),
161 165
    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
162 166
    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
163 167
    _undirected(lemon::UndirectedTagIndicator<G>::value),
164 168
    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
165 169
    _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
166 170
    _autoNodeScale(false),
167 171
    _autoArcWidthScale(false),
168 172
    _absoluteNodeSizes(false),
169 173
    _absoluteArcWidths(false),
170 174
    _negY(false),
171 175
    _preScale(true)
172 176
  {}
173 177
};
174 178

	
175 179
///Auxiliary class to implement the named parameters of \ref graphToEps()
176 180

	
177 181
///Auxiliary class to implement the named parameters of \ref graphToEps().
178 182
///
179 183
///For detailed examples see the \ref graph_to_eps_demo.cc demo file.
180 184
template<class T> class GraphToEps : public T
181 185
{
182 186
  // Can't believe it is required by the C++ standard
183 187
  using T::g;
184 188
  using T::os;
185 189

	
186 190
  using T::_coords;
187 191
  using T::_nodeSizes;
188 192
  using T::_nodeShapes;
189 193
  using T::_nodeColors;
190 194
  using T::_arcColors;
191 195
  using T::_arcWidths;
192 196

	
193 197
  using T::_arcWidthScale;
194 198
  using T::_nodeScale;
195 199
  using T::_xBorder;
196 200
  using T::_yBorder;
197 201
  using T::_scale;
198 202
  using T::_nodeBorderQuotient;
199 203

	
200 204
  using T::_drawArrows;
201 205
  using T::_arrowLength;
202 206
  using T::_arrowWidth;
203 207

	
204 208
  using T::_showNodes;
205 209
  using T::_showArcs;
206 210

	
207 211
  using T::_enableParallel;
208 212
  using T::_parArcDist;
209 213

	
210 214
  using T::_showNodeText;
211 215
  using T::_nodeTexts;
212 216
  using T::_nodeTextSize;
213 217

	
214 218
  using T::_showNodePsText;
215 219
  using T::_nodePsTexts;
216 220
  using T::_nodePsTextsPreamble;
217 221

	
218 222
  using T::_undirected;
219 223

	
220 224
  using T::_pleaseRemoveOsStream;
221 225

	
222 226
  using T::_scaleToA4;
223 227

	
224 228
  using T::_title;
225 229
  using T::_copyright;
226 230

	
227 231
  using T::NodeTextColorType;
228 232
  using T::CUST_COL;
229 233
  using T::DIST_COL;
230 234
  using T::DIST_BW;
231 235
  using T::_nodeTextColorType;
232 236
  using T::_nodeTextColors;
233 237

	
234 238
  using T::_autoNodeScale;
235 239
  using T::_autoArcWidthScale;
236 240

	
237 241
  using T::_absoluteNodeSizes;
238 242
  using T::_absoluteArcWidths;
239 243

	
240 244

	
241 245
  using T::_negY;
242 246
  using T::_preScale;
243 247

	
244 248
  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
245 249

	
246 250
  typedef typename T::Graph Graph;
247 251
  typedef typename Graph::Node Node;
248 252
  typedef typename Graph::NodeIt NodeIt;
249 253
  typedef typename Graph::Arc Arc;
250 254
  typedef typename Graph::ArcIt ArcIt;
251 255
  typedef typename Graph::InArcIt InArcIt;
252 256
  typedef typename Graph::OutArcIt OutArcIt;
253 257

	
254 258
  static const int INTERPOL_PREC;
255 259
  static const double A4HEIGHT;
256 260
  static const double A4WIDTH;
257 261
  static const double A4BORDER;
258 262

	
259 263
  bool dontPrint;
260 264

	
261 265
public:
262 266
  ///Node shapes
263 267

	
264 268
  ///Node shapes.
265 269
  ///
266 270
  enum NodeShapes {
267 271
    /// = 0
268 272
    ///\image html nodeshape_0.png
269 273
    ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
270 274
    CIRCLE=0,
271 275
    /// = 1
272 276
    ///\image html nodeshape_1.png
273 277
    ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
274 278
    ///
275 279
    SQUARE=1,
276 280
    /// = 2
277 281
    ///\image html nodeshape_2.png
278 282
    ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
279 283
    ///
280 284
    DIAMOND=2,
281 285
    /// = 3
282 286
    ///\image html nodeshape_3.png
283 287
    ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
284 288
    ///
285 289
    MALE=3,
286 290
    /// = 4
287 291
    ///\image html nodeshape_4.png
288 292
    ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
289 293
    ///
290 294
    FEMALE=4
291 295
  };
292 296

	
293 297
private:
294 298
  class arcLess {
295 299
    const Graph &g;
296 300
  public:
297 301
    arcLess(const Graph &_g) : g(_g) {}
298 302
    bool operator()(Arc a,Arc b) const
299 303
    {
300 304
      Node ai=std::min(g.source(a),g.target(a));
301 305
      Node aa=std::max(g.source(a),g.target(a));
302 306
      Node bi=std::min(g.source(b),g.target(b));
303 307
      Node ba=std::max(g.source(b),g.target(b));
304 308
      return ai<bi ||
305 309
        (ai==bi && (aa < ba ||
306 310
                    (aa==ba && ai==g.source(a) && bi==g.target(b))));
307 311
    }
308 312
  };
309 313
  bool isParallel(Arc e,Arc f) const
310 314
  {
311 315
    return (g.source(e)==g.source(f)&&
312 316
            g.target(e)==g.target(f)) ||
313 317
      (g.source(e)==g.target(f)&&
314 318
       g.target(e)==g.source(f));
315 319
  }
316 320
  template<class TT>
317 321
  static std::string psOut(const dim2::Point<TT> &p)
318 322
    {
319 323
      std::ostringstream os;
320 324
      os << p.x << ' ' << p.y;
321 325
      return os.str();
322 326
    }
323 327
  static std::string psOut(const Color &c)
324 328
    {
325 329
      std::ostringstream os;
326 330
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
327 331
      return os.str();
328 332
    }
329 333

	
330 334
public:
331 335
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
332 336

	
333 337
  template<class X> struct CoordsTraits : public T {
334 338
  typedef X CoordsMapType;
335 339
    const X &_coords;
336 340
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
337 341
  };
338 342
  ///Sets the map of the node coordinates
339 343

	
340 344
  ///Sets the map of the node coordinates.
341 345
  ///\param x must be a node map with \ref dim2::Point "dim2::Point<double>" or
342 346
  ///\ref dim2::Point "dim2::Point<int>" values.
343 347
  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
344 348
    dontPrint=true;
345 349
    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
346 350
  }
347 351
  template<class X> struct NodeSizesTraits : public T {
348 352
    const X &_nodeSizes;
349 353
    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
350 354
  };
351 355
  ///Sets the map of the node sizes
352 356

	
353 357
  ///Sets the map of the node sizes.
354 358
  ///\param x must be a node map with \c double (or convertible) values.
355 359
  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
356 360
  {
357 361
    dontPrint=true;
358 362
    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
359 363
  }
360 364
  template<class X> struct NodeShapesTraits : public T {
361 365
    const X &_nodeShapes;
362 366
    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
363 367
  };
364 368
  ///Sets the map of the node shapes
365 369

	
366 370
  ///Sets the map of the node shapes.
367 371
  ///The available shape values
368 372
  ///can be found in \ref NodeShapes "enum NodeShapes".
369 373
  ///\param x must be a node map with \c int (or convertible) values.
370 374
  ///\sa NodeShapes
371 375
  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
372 376
  {
373 377
    dontPrint=true;
374 378
    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
375 379
  }
376 380
  template<class X> struct NodeTextsTraits : public T {
377 381
    const X &_nodeTexts;
378 382
    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
379 383
  };
380 384
  ///Sets the text printed on the nodes
381 385

	
382 386
  ///Sets the text printed on the nodes.
383 387
  ///\param x must be a node map with type that can be pushed to a standard
384 388
  ///\c ostream.
385 389
  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
386 390
  {
387 391
    dontPrint=true;
388 392
    _showNodeText=true;
389 393
    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
390 394
  }
391 395
  template<class X> struct NodePsTextsTraits : public T {
392 396
    const X &_nodePsTexts;
393 397
    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
394 398
  };
395 399
  ///Inserts a PostScript block to the nodes
396 400

	
397 401
  ///With this command it is possible to insert a verbatim PostScript
398 402
  ///block to the nodes.
399 403
  ///The PS current point will be moved to the center of the node before
400 404
  ///the PostScript block inserted.
401 405
  ///
402 406
  ///Before and after the block a newline character is inserted so you
403 407
  ///don't have to bother with the separators.
404 408
  ///
405 409
  ///\param x must be a node map with type that can be pushed to a standard
406 410
  ///\c ostream.
407 411
  ///
408 412
  ///\sa nodePsTextsPreamble()
409 413
  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
410 414
  {
411 415
    dontPrint=true;
412 416
    _showNodePsText=true;
413 417
    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
414 418
  }
415 419
  template<class X> struct ArcWidthsTraits : public T {
416 420
    const X &_arcWidths;
417 421
    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
Ignore white space 768 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_TIME_MEASURE_H
20 20
#define LEMON_TIME_MEASURE_H
21 21

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

	
26 26
#ifdef WIN32
27
#ifndef WIN32_LEAN_AND_MEAN
27 28
#define WIN32_LEAN_AND_MEAN
29
#endif
30
#ifndef NOMINMAX
28 31
#define NOMINMAX
32
#endif
29 33
#include <windows.h>
30 34
#include <cmath>
31 35
#else
32 36
#include <unistd.h>
33 37
#include <sys/times.h>
34 38
#include <sys/time.h>
35 39
#endif
36 40

	
37 41
#include <string>
38 42
#include <fstream>
39 43
#include <iostream>
40 44

	
41 45
namespace lemon {
42 46

	
43 47
  /// \addtogroup timecount
44 48
  /// @{
45 49

	
46 50
  /// A class to store (cpu)time instances.
47 51

	
48 52
  /// This class stores five time values.
49 53
  /// - a real time
50 54
  /// - a user cpu time
51 55
  /// - a system cpu time
52 56
  /// - a user cpu time of children
53 57
  /// - a system cpu time of children
54 58
  ///
55 59
  /// TimeStamp's can be added to or substracted from each other and
56 60
  /// they can be pushed to a stream.
57 61
  ///
58 62
  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
59 63
  /// class is what you want to use instead.
60 64

	
61 65
  class TimeStamp
62 66
  {
63 67
    double utime;
64 68
    double stime;
65 69
    double cutime;
66 70
    double cstime;
67 71
    double rtime;
68 72

	
69 73
    void _reset() {
70 74
      utime = stime = cutime = cstime = rtime = 0;
71 75
    }
72 76

	
73 77
  public:
74 78

	
75 79
    ///Read the current time values of the process
76 80
    void stamp()
77 81
    {
78 82
#ifndef WIN32
79 83
      timeval tv;
80 84
      gettimeofday(&tv, 0);
81 85
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
82 86

	
83 87
      tms ts;
84 88
      double tck=sysconf(_SC_CLK_TCK);
85 89
      times(&ts);
86 90
      utime=ts.tms_utime/tck;
87 91
      stime=ts.tms_stime/tck;
88 92
      cutime=ts.tms_cutime/tck;
89 93
      cstime=ts.tms_cstime/tck;
90 94
#else
91 95
      static const double ch = 4294967296.0e-7;
92 96
      static const double cl = 1.0e-7;
93 97

	
94 98
      FILETIME system;
95 99
      GetSystemTimeAsFileTime(&system);
96 100
      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
97 101

	
98 102
      FILETIME create, exit, kernel, user;
99 103
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
100 104
        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
101 105
        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
102 106
        cutime = 0;
103 107
        cstime = 0;
104 108
      } else {
105 109
        rtime = 0;
106 110
        utime = 0;
107 111
        stime = 0;
108 112
        cutime = 0;
109 113
        cstime = 0;
110 114
      }
111 115
#endif
112 116
    }
113 117

	
114 118
    /// Constructor initializing with zero
115 119
    TimeStamp()
116 120
    { _reset(); }
117 121
    ///Constructor initializing with the current time values of the process
118 122
    TimeStamp(void *) { stamp();}
119 123

	
120 124
    ///Set every time value to zero
121 125
    TimeStamp &reset() {_reset();return *this;}
122 126

	
123 127
    ///\e
124 128
    TimeStamp &operator+=(const TimeStamp &b)
125 129
    {
126 130
      utime+=b.utime;
127 131
      stime+=b.stime;
128 132
      cutime+=b.cutime;
129 133
      cstime+=b.cstime;
130 134
      rtime+=b.rtime;
131 135
      return *this;
132 136
    }
133 137
    ///\e
134 138
    TimeStamp operator+(const TimeStamp &b) const
135 139
    {
136 140
      TimeStamp t(*this);
137 141
      return t+=b;
138 142
    }
139 143
    ///\e
140 144
    TimeStamp &operator-=(const TimeStamp &b)
141 145
    {
142 146
      utime-=b.utime;
143 147
      stime-=b.stime;
144 148
      cutime-=b.cutime;
145 149
      cstime-=b.cstime;
146 150
      rtime-=b.rtime;
147 151
      return *this;
148 152
    }
149 153
    ///\e
150 154
    TimeStamp operator-(const TimeStamp &b) const
151 155
    {
152 156
      TimeStamp t(*this);
153 157
      return t-=b;
154 158
    }
155 159
    ///\e
156 160
    TimeStamp &operator*=(double b)
157 161
    {
158 162
      utime*=b;
159 163
      stime*=b;
160 164
      cutime*=b;
161 165
      cstime*=b;
162 166
      rtime*=b;
163 167
      return *this;
164 168
    }
165 169
    ///\e
166 170
    TimeStamp operator*(double b) const
167 171
    {
168 172
      TimeStamp t(*this);
169 173
      return t*=b;
170 174
    }
171 175
    friend TimeStamp operator*(double b,const TimeStamp &t);
172 176
    ///\e
173 177
    TimeStamp &operator/=(double b)
174 178
    {
175 179
      utime/=b;
176 180
      stime/=b;
177 181
      cutime/=b;
178 182
      cstime/=b;
179 183
      rtime/=b;
180 184
      return *this;
181 185
    }
182 186
    ///\e
183 187
    TimeStamp operator/(double b) const
184 188
    {
185 189
      TimeStamp t(*this);
186 190
      return t/=b;
187 191
    }
188 192
    ///The time ellapsed since the last call of stamp()
189 193
    TimeStamp ellapsed() const
190 194
    {
191 195
      TimeStamp t(NULL);
192 196
      return t-*this;
193 197
    }
194 198

	
195 199
    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
196 200

	
197 201
    ///Gives back the user time of the process
198 202
    double userTime() const
199 203
    {
200 204
      return utime;
201 205
    }
202 206
    ///Gives back the system time of the process
203 207
    double systemTime() const
204 208
    {
205 209
      return stime;
206 210
    }
207 211
    ///Gives back the user time of the process' children
208 212

	
209 213
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
210 214
    ///
211 215
    double cUserTime() const
212 216
    {
213 217
      return cutime;
214 218
    }
215 219
    ///Gives back the user time of the process' children
216 220

	
217 221
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
218 222
    ///
219 223
    double cSystemTime() const
220 224
    {
221 225
      return cstime;
222 226
    }
223 227
    ///Gives back the real time
224 228
    double realTime() const {return rtime;}
225 229
  };
226 230

	
227 231
  TimeStamp operator*(double b,const TimeStamp &t)
228 232
  {
229 233
    return t*b;
230 234
  }
231 235

	
232 236
  ///Prints the time counters
233 237

	
234 238
  ///Prints the time counters in the following form:
235 239
  ///
236 240
  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
237 241
  ///
238 242
  /// where the values are the
239 243
  /// \li \c u: user cpu time,
240 244
  /// \li \c s: system cpu time,
241 245
  /// \li \c cu: user cpu time of children,
242 246
  /// \li \c cs: system cpu time of children,
243 247
  /// \li \c real: real time.
244 248
  /// \relates TimeStamp
245 249
  /// \note On <tt>WIN32</tt> platform the cummulative values are not
246 250
  /// calculated.
247 251
  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
248 252
  {
249 253
    os << "u: " << t.userTime() <<
250 254
      "s, s: " << t.systemTime() <<
251 255
      "s, cu: " << t.cUserTime() <<
252 256
      "s, cs: " << t.cSystemTime() <<
253 257
      "s, real: " << t.realTime() << "s";
254 258
    return os;
255 259
  }
256 260

	
257 261
  ///Class for measuring the cpu time and real time usage of the process
258 262

	
259 263
  ///Class for measuring the cpu time and real time usage of the process.
260 264
  ///It is quite easy-to-use, here is a short example.
261 265
  ///\code
262 266
  /// #include<lemon/time_measure.h>
263 267
  /// #include<iostream>
264 268
  ///
265 269
  /// int main()
266 270
  /// {
267 271
  ///
268 272
  ///   ...
269 273
  ///
270 274
  ///   Timer t;
271 275
  ///   doSomething();
272 276
  ///   std::cout << t << '\n';
273 277
  ///   t.restart();
274 278
  ///   doSomethingElse();
275 279
  ///   std::cout << t << '\n';
276 280
  ///
277 281
  ///   ...
278 282
  ///
279 283
  /// }
280 284
  ///\endcode
281 285
  ///
282 286
  ///The \ref Timer can also be \ref stop() "stopped" and
283 287
  ///\ref start() "started" again, so it is possible to compute collected
284 288
  ///running times.
285 289
  ///
286 290
  ///\warning Depending on the operation system and its actual configuration
287 291
  ///the time counters have a certain (10ms on a typical Linux system)
288 292
  ///granularity.
289 293
  ///Therefore this tool is not appropriate to measure very short times.
290 294
  ///Also, if you start and stop the timer very frequently, it could lead to
291 295
  ///distorted results.
292 296
  ///
293 297
  ///\note If you want to measure the running time of the execution of a certain
294 298
  ///function, consider the usage of \ref TimeReport instead.
295 299
  ///
296 300
  ///\sa TimeReport
297 301
  class Timer
298 302
  {
299 303
    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
300 304
    TimeStamp start_time; //This is the relativ start-time if the timer
301 305
                          //is _running, the collected _running time otherwise.
302 306

	
303 307
    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
304 308

	
305 309
  public:
306 310
    ///Constructor.
307 311

	
308 312
    ///\param run indicates whether or not the timer starts immediately.
309 313
    ///
310 314
    Timer(bool run=true) :_running(run) {_reset();}
311 315

	
312 316
    ///\name Control the state of the timer
313 317
    ///Basically a Timer can be either running or stopped,
314 318
    ///but it provides a bit finer control on the execution.
315 319
    ///The \ref lemon::Timer "Timer" also counts the number of
316 320
    ///\ref lemon::Timer::start() "start()" executions, and it stops
317 321
    ///only after the same amount (or more) \ref lemon::Timer::stop()
318 322
    ///"stop()"s. This can be useful e.g. to compute the running time
319 323
    ///of recursive functions.
320 324

	
321 325
    ///@{
322 326

	
323 327
    ///Reset and stop the time counters
324 328

	
325 329
    ///This function resets and stops the time counters
326 330
    ///\sa restart()
327 331
    void reset()
328 332
    {
329 333
      _running=0;
330 334
      _reset();
331 335
    }
332 336

	
333 337
    ///Start the time counters
334 338

	
335 339
    ///This function starts the time counters.
336 340
    ///
337 341
    ///If the timer is started more than ones, it will remain running
338 342
    ///until the same amount of \ref stop() is called.
339 343
    ///\sa stop()
340 344
    void start()
341 345
    {
342 346
      if(_running) _running++;
343 347
      else {
344 348
        _running=1;
345 349
        TimeStamp t;
346 350
        t.stamp();
347 351
        start_time=t-start_time;
348 352
      }
349 353
    }
350 354

	
351 355

	
352 356
    ///Stop the time counters
353 357

	
354 358
    ///This function stops the time counters. If start() was executed more than
355 359
    ///once, then the same number of stop() execution is necessary the really
356 360
    ///stop the timer.
357 361
    ///
358 362
    ///\sa halt()
359 363
    ///\sa start()
360 364
    ///\sa restart()
361 365
    ///\sa reset()
362 366

	
363 367
    void stop()
364 368
    {
365 369
      if(_running && !--_running) {
366 370
        TimeStamp t;
367 371
        t.stamp();
368 372
        start_time=t-start_time;
369 373
      }
370 374
    }
371 375

	
372 376
    ///Halt (i.e stop immediately) the time counters
373 377

	
374 378
    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
375 379
    ///is a faster
376 380
    ///equivalent of the following.
377 381
    ///\code
378 382
    ///  while(t.running()) t.stop()
379 383
    ///\endcode
380 384
    ///
381 385
    ///
382 386
    ///\sa stop()
383 387
    ///\sa restart()
384 388
    ///\sa reset()
385 389

	
386 390
    void halt()
387 391
    {
388 392
      if(_running) {
389 393
        _running=0;
390 394
        TimeStamp t;
391 395
        t.stamp();
392 396
        start_time=t-start_time;
393 397
      }
394 398
    }
395 399

	
396 400
    ///Returns the running state of the timer
397 401

	
398 402
    ///This function returns the number of stop() exections that is
399 403
    ///necessary to really stop the timer.
400 404
    ///For example the timer
401 405
    ///is running if and only if the return value is \c true
402 406
    ///(i.e. greater than
403 407
    ///zero).
404 408
    int running()  { return _running; }
405 409

	
406 410

	
407 411
    ///Restart the time counters
408 412

	
409 413
    ///This function is a shorthand for
410 414
    ///a reset() and a start() calls.
411 415
    ///
412 416
    void restart()
0 comments (0 inline)