gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Resolve several MSVC related compilation problems
0 3 0
default
3 files changed with 6 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- C++ -*-
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
///\ingroup demos
20 20
///\file
21 21
///\brief Demonstrating graph input and output
22 22
///
23 23
/// This simple demo program gives an example of how to read and write
24 24
/// a graph and additional maps (on the nodes or the edges) from/to a
25 25
/// stream. 
26 26
///
27 27
/// \include reader_writer_demo.cc
28 28

	
29 29
#include <iostream>
30 30
#include <lemon/smart_graph.h>
31 31
#include <lemon/lgf_reader.h>
32 32
#include <lemon/lgf_writer.h>
33 33
#include <lemon/random.h>
34 34

	
35 35

	
36 36
using namespace lemon;
37 37

	
38 38
int main(int argc, const char *argv[]) {
39 39
  const int n = argc > 1 ? std::atoi(argv[1]) : 20;
40
  const int e = argc > 2 ? std::atoi(argv[2]) : static_cast<int>(n * log(n));
40
  const int e = argc > 2 ? std::atoi(argv[2]) : static_cast<int>(n * std::log(double(n)));
41 41
  const int m = argc > 3 ? std::atoi(argv[3]) : 100;
42 42

	
43 43
  SmartDigraph digraph;
44 44

	
45 45
  std::stringstream ss;
46 46

	
47 47
  try {
48 48

	
49 49
    typedef SmartDigraph Digraph;
50 50
    typedef Digraph::Node Node;
51 51
    typedef Digraph::Arc Arc;
52 52
    typedef Digraph::ArcIt ArcIt;
53 53

	
54 54
    typedef Digraph::NodeMap<int> PotentialMap;
55 55
    typedef Digraph::ArcMap<int> CapacityMap;
56 56
    typedef Digraph::ArcMap<std::string> NameMap;
57 57

	
58 58
    Digraph digraph;
59 59
    PotentialMap potential(digraph);
60 60
    CapacityMap capacity(digraph);
61 61
    NameMap name(digraph);
62 62

	
63 63
    std::vector<Node> nodes;
64 64
    for (int i = 0; i < n; ++i) {
65 65
      Node node = digraph.addNode();
66 66
      potential[node] = rnd[m];
67 67
      nodes.push_back(node);
68 68
    }
69 69

	
70 70
    std::vector<Arc> arcs;
71 71
    for (int i = 0; i < e; ++i) {
72 72
      int s = rnd[n];
73 73
      int t = rnd[n];
74 74
      int c = rnd[m];
75 75
      Arc arc = digraph.addArc(nodes[s], nodes[t]);
76 76
      capacity[arc] = c;
77 77
      std::ostringstream os;
78 78
      os << "arc \t" << i << std::endl;
79 79
      name[arc] = os.str();
80 80
      arcs.push_back(arc);
81 81
    }
82 82

	
83 83

	
84 84
    DigraphWriter<Digraph>(ss, digraph).
85 85
      nodeMap("potential", potential).
86 86
      arcMap("capacity", capacity).
87 87
      arcMap("name", name).
88 88
      node("source", nodes[0]).
89 89
      node("target", nodes[1]).
90 90
      arc("bottleneck", arcs[e / 2]).
91 91
      attribute("creator", "lemon library").
92 92
      run();
93 93

	
94 94
  } catch (DataFormatError& error) {
95 95
    std::cerr << error.what() << std::endl;
96 96
  }
97 97

	
98 98
  try {
99 99

	
100 100
    typedef SmartDigraph Digraph;
101 101
    typedef Digraph::Node Node;
102 102
    typedef Digraph::Arc Arc;
103 103
    typedef Digraph::ArcIt ArcIt;
104 104

	
105 105
    typedef Digraph::NodeMap<int> LabelMap;
106 106
    typedef Digraph::NodeMap<int> PotentialMap;
107 107
    typedef Digraph::ArcMap<int> CapacityMap;
108 108
    typedef Digraph::ArcMap<std::string> NameMap;
109 109

	
110 110
    Digraph digraph;
111 111
    LabelMap label(digraph);
112 112
    PotentialMap potential(digraph);
113 113
    CapacityMap capacity(digraph);
114 114
    NameMap name(digraph);
115 115

	
116 116
    Node s, t;
117 117
    Arc a;
118 118
    
119 119
    std::string creator;
120 120

	
121 121
    for (int i = 0; i < n; ++i) {
122 122
      Node node = digraph.addNode();
123 123
      label[node] = i;
124 124
    }
125 125
    
126 126
    DigraphReader<Digraph>(ss, digraph).
127 127
      useNodes(label).
128 128
      nodeMap("potential", potential).
129 129
      arcMap("capacity", capacity).
130 130
      arcMap("name", name).
131 131
      node("source", s).
132 132
      node("target", t).
133 133
      arc("bottleneck", a).
134 134
      attribute("creator", creator).
135 135
      run();
136 136

	
137 137
    DigraphWriter<Digraph>(std::cout, digraph).
138 138
      nodeMap("potential", potential).
139 139
      arcMap("capacity", capacity).
140 140
      arcMap("name", name).
141 141
      node("source", s).
142 142
      node("target", t).
143 143
      arc("bottleneck", a).
144 144
      attribute("creator", creator).
145 145
      run();
146 146

	
147 147
  } catch (DataFormatError& error) {
148 148
    std::cerr << error.what() << std::endl;
149 149
  }
150 150

	
151 151

	
152 152
  return 0;
153 153
}
Ignore white space 6 line context
1 1
/* -*- C++ -*-
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
#define WIN32_LEAN_AND_MEAN
33
#define NOMINMAX
32 34
#include<windows.h>
33 35
#endif
34 36

	
35 37
#include<lemon/math.h>
36 38
#include<lemon/bits/invalid.h>
37 39
#include<lemon/dim2.h>
38 40
#include<lemon/maps.h>
39 41
#include<lemon/color.h>
40 42
#include<lemon/bits/bezier.h>
41 43

	
42 44

	
43 45
///\ingroup eps_io
44 46
///\file
45 47
///\brief A well configurable tool for visualizing graphs
46 48

	
47 49
namespace lemon {
48 50

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

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

	
79 81
  const Graph &g;
80 82

	
81 83
  std::ostream& os;
82 84
  
83 85
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
84 86
  CoordsMapType _coords;
85 87
  ConstMap<typename Graph::Node,double > _nodeSizes;
86 88
  ConstMap<typename Graph::Node,int > _nodeShapes;
87 89

	
88 90
  ConstMap<typename Graph::Node,Color > _nodeColors;
89 91
  ConstMap<typename Graph::Arc,Color > _arcColors;
90 92

	
91 93
  ConstMap<typename Graph::Arc,double > _arcWidths;
92 94

	
93 95
  double _arcWidthScale;
94 96
  
95 97
  double _nodeScale;
96 98
  double _xBorder, _yBorder;
97 99
  double _scale;
98 100
  double _nodeBorderQuotient;
99 101
  
100 102
  bool _drawArrows;
101 103
  double _arrowLength, _arrowWidth;
102 104
  
103 105
  bool _showNodes, _showArcs;
104 106

	
105 107
  bool _enableParallel;
106 108
  double _parArcDist;
107 109

	
108 110
  bool _showNodeText;
109 111
  ConstMap<typename Graph::Node,bool > _nodeTexts;  
110 112
  double _nodeTextSize;
111 113

	
112 114
  bool _showNodePsText;
113 115
  ConstMap<typename Graph::Node,bool > _nodePsTexts;  
114 116
  char *_nodePsTextsPreamble;
115 117
  
116 118
  bool _undirected;
117 119

	
118 120
  bool _pleaseRemoveOsStream;
119 121

	
120 122
  bool _scaleToA4;
121 123

	
122 124
  std::string _title;
123 125
  std::string _copyright;
124 126

	
125 127
  enum NodeTextColorType 
126 128
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
127 129
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
128 130

	
129 131
  bool _autoNodeScale;
130 132
  bool _autoArcWidthScale;
131 133

	
132 134
  bool _absoluteNodeSizes;
133 135
  bool _absoluteArcWidths;
134 136

	
135 137
  bool _negY;
136 138

	
137 139
  bool _preScale;
138 140
  ///Constructor
139 141

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

	
172 174
///Auxiliary class to implement the named parameters of \ref graphToEps()
173 175

	
174 176
///Auxiliary class to implement the named parameters of \ref graphToEps()
175 177
template<class T> class GraphToEps : public T 
176 178
{
177 179
  // Can't believe it is required by the C++ standard
178 180
  using T::g;
179 181
  using T::os;
180 182

	
181 183
  using T::_coords;
182 184
  using T::_nodeSizes;
183 185
  using T::_nodeShapes;
184 186
  using T::_nodeColors;
185 187
  using T::_arcColors;
186 188
  using T::_arcWidths;
187 189

	
188 190
  using T::_arcWidthScale;
189 191
  using T::_nodeScale;
190 192
  using T::_xBorder;
191 193
  using T::_yBorder;
192 194
  using T::_scale;
193 195
  using T::_nodeBorderQuotient;
194 196
  
195 197
  using T::_drawArrows;
196 198
  using T::_arrowLength;
197 199
  using T::_arrowWidth;
198 200
  
199 201
  using T::_showNodes;
200 202
  using T::_showArcs;
201 203

	
202 204
  using T::_enableParallel;
203 205
  using T::_parArcDist;
204 206

	
205 207
  using T::_showNodeText;
206 208
  using T::_nodeTexts;  
207 209
  using T::_nodeTextSize;
208 210

	
209 211
  using T::_showNodePsText;
210 212
  using T::_nodePsTexts;  
211 213
  using T::_nodePsTextsPreamble;
212 214
  
213 215
  using T::_undirected;
214 216

	
215 217
  using T::_pleaseRemoveOsStream;
216 218

	
217 219
  using T::_scaleToA4;
218 220

	
219 221
  using T::_title;
220 222
  using T::_copyright;
221 223

	
222 224
  using T::NodeTextColorType;
223 225
  using T::CUST_COL;
224 226
  using T::DIST_COL;
225 227
  using T::DIST_BW;
226 228
  using T::_nodeTextColorType;
227 229
  using T::_nodeTextColors;
228 230

	
229 231
  using T::_autoNodeScale;
230 232
  using T::_autoArcWidthScale;
231 233

	
232 234
  using T::_absoluteNodeSizes;
233 235
  using T::_absoluteArcWidths;
234 236

	
235 237

	
236 238
  using T::_negY;
237 239
  using T::_preScale;
238 240

	
239 241
  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
240 242

	
241 243
  typedef typename T::Graph Graph;
242 244
  typedef typename Graph::Node Node;
243 245
  typedef typename Graph::NodeIt NodeIt;
244 246
  typedef typename Graph::Arc Arc;
245 247
  typedef typename Graph::ArcIt ArcIt;
246 248
  typedef typename Graph::InArcIt InArcIt;
247 249
  typedef typename Graph::OutArcIt OutArcIt;
248 250

	
249 251
  static const int INTERPOL_PREC;
250 252
  static const double A4HEIGHT;
251 253
  static const double A4WIDTH;
252 254
  static const double A4BORDER;
253 255

	
254 256
  bool dontPrint;
255 257

	
256 258
public:
257 259
  ///Node shapes
258 260

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

	
288 290
private:
289 291
  class arcLess {
290 292
    const Graph &g;
291 293
  public:
292 294
    arcLess(const Graph &_g) : g(_g) {}
293 295
    bool operator()(Arc a,Arc b) const 
294 296
    {
295 297
      Node ai=std::min(g.source(a),g.target(a));
296 298
      Node aa=std::max(g.source(a),g.target(a));
297 299
      Node bi=std::min(g.source(b),g.target(b));
298 300
      Node ba=std::max(g.source(b),g.target(b));
299 301
      return ai<bi ||
300 302
	(ai==bi && (aa < ba || 
301 303
		    (aa==ba && ai==g.source(a) && bi==g.target(b))));
302 304
    }
303 305
  };
304 306
  bool isParallel(Arc e,Arc f) const
305 307
  {
306 308
    return (g.source(e)==g.source(f)&&
307 309
	    g.target(e)==g.target(f)) ||
308 310
      (g.source(e)==g.target(f)&&
309 311
       g.target(e)==g.source(f));
310 312
  }
311 313
  template<class TT>
312 314
  static std::string psOut(const dim2::Point<TT> &p) 
313 315
    {
314 316
      std::ostringstream os;	
315 317
      os << p.x << ' ' << p.y;
316 318
      return os.str();
317 319
    }
318 320
  static std::string psOut(const Color &c) 
319 321
    {
320 322
      std::ostringstream os;	
321 323
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
322 324
      return os.str();
323 325
    }
324 326
  
325 327
public:
326 328
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
327 329
  
328 330
  template<class X> struct CoordsTraits : public T {
329 331
  typedef X CoordsMapType;
330 332
    const X &_coords;
331 333
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
332 334
  };
333 335
  ///Sets the map of the node coordinates
334 336

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

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

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

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

	
392 394
  ///With this command it is possible to insert a verbatim PostScript
393 395
  ///block to the nodes.
394 396
  ///The PS current point will be moved to the centre of the node before
395 397
  ///the PostScript block inserted.
396 398
  ///
397 399
  ///Before and after the block a newline character is inserted so you
398 400
  ///don't have to bother with the separators.
399 401
  ///
400 402
  ///\param x must be a node map with type that can be pushed to a standard
401 403
  ///ostream.
402 404
  ///
403 405
  ///\sa nodePsTextsPreamble()
404 406
  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
405 407
  {
406 408
    dontPrint=true;
407 409
    _showNodePsText=true;
408 410
    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
409 411
  }
410 412
  template<class X> struct ArcWidthsTraits : public T {
411 413
    const X &_arcWidths;
412 414
    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
413 415
  };
414 416
  ///Sets the map of the arc widths
415 417

	
Ignore white space 768 line context
1 1
/* -*- C++ -*-
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
#define WIN32_LEAN_AND_MEAN
28
#define NOMINMAX
27 29
#include <windows.h>
28 30
#include <cmath>
29 31
#else
30 32
#include <sys/times.h>
31 33
#include <sys/time.h>
32 34
#endif
33 35

	
36
#include <string>
34 37
#include <fstream>
35 38
#include <iostream>
36 39

	
37 40
namespace lemon {
38 41

	
39 42
  /// \addtogroup timecount
40 43
  /// @{
41 44

	
42 45
  /// A class to store (cpu)time instances.
43 46

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

	
59 62
  class TimeStamp
60 63
  {
61 64
    double utime;
62 65
    double stime;
63 66
    double cutime;
64 67
    double cstime;
65 68
    double rtime;
66 69
  
67 70
    void _reset() { 
68 71
      utime = stime = cutime = cstime = rtime = 0;
69 72
    }
70 73

	
71 74
  public:
72 75

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

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

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

	
96 99
      FILETIME create, exit, kernel, user;
97 100
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
98 101
	utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
99 102
	stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
100 103
	cutime = 0;
101 104
	cstime = 0;
102 105
      } else {
103 106
	rtime = 0;
104 107
	utime = 0;
105 108
	stime = 0;
106 109
	cutime = 0;
107 110
	cstime = 0;
108 111
      }
109 112
#endif      
110 113
    }
111 114
  
112 115
    /// Constructor initializing with zero
113 116
    TimeStamp()
114 117
    { _reset(); }
115 118
    ///Constructor initializing with the current time values of the process
116 119
    TimeStamp(void *) { stamp();}
117 120
  
118 121
    ///Set every time value to zero
119 122
    TimeStamp &reset() {_reset();return *this;}
120 123

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

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

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

	
225 228
  TimeStamp operator*(double b,const TimeStamp &t) 
226 229
  {
227 230
    return t*b;
228 231
  }
229 232
  
230 233
  ///Prints the time counters
231 234

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

	
255 258
  ///Class for measuring the cpu time and real time usage of the process
256 259

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

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

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

	
322 325
    ///@{
323 326

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

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

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

	
352 355
    
353 356
    ///Stop the time counters
354 357

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

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

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

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

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

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

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

	
410 413
    ///This function is a shorthand for
411 414
    ///a reset() and a start() calls.
412 415
    ///
413 416
    void restart() 
414 417
    {
415 418
      reset();
416 419
      start();
417 420
    }
0 comments (0 inline)