gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 5 2
merge 1.0
0 files changed with 186 insertions and 68 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
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
///\file
20
///\brief Some basic non-inline functions and static global data.
21

	
22
#include<lemon/bits/windows.h>
23

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

	
39
#include <cmath>
40
#include <sstream>
41

	
42
namespace lemon {
43
  namespace bits {
44
    void getWinProcTimes(double &rtime,
45
                         double &utime, double &stime,
46
                         double &cutime, double &cstime)
47
    {
48
#ifdef WIN32
49
      static const double ch = 4294967296.0e-7;
50
      static const double cl = 1.0e-7;
51

	
52
      FILETIME system;
53
      GetSystemTimeAsFileTime(&system);
54
      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
55

	
56
      FILETIME create, exit, kernel, user;
57
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
58
        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
59
        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
60
        cutime = 0;
61
        cstime = 0;
62
      } else {
63
        rtime = 0;
64
        utime = 0;
65
        stime = 0;
66
        cutime = 0;
67
        cstime = 0;
68
      }
69
#else
70
      timeval tv;
71
      gettimeofday(&tv, 0);
72
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
73

	
74
      tms ts;
75
      double tck=sysconf(_SC_CLK_TCK);
76
      times(&ts);
77
      utime=ts.tms_utime/tck;
78
      stime=ts.tms_stime/tck;
79
      cutime=ts.tms_cutime/tck;
80
      cstime=ts.tms_cstime/tck;
81
#endif
82
    }
83

	
84
    std::string getWinFormattedDate()
85
    {
86
      std::ostringstream os;
87
#ifdef WIN32
88
      SYSTEMTIME time;
89
      GetSystemTime(&time);
90
#if defined(_MSC_VER) && (_MSC_VER < 1500)
91
      LPWSTR buf1, buf2, buf3;
92
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
93
                        L"ddd MMM dd", buf1, 11) &&
94
          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
95
                        L"HH':'mm':'ss", buf2, 9) &&
96
          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
97
                        L"yyyy", buf3, 5)) {
98
        os << buf1 << ' ' << buf2 << ' ' << buf3;
99
      }
100
#else
101
      char buf1[11], buf2[9], buf3[5];
102
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
103
                        "ddd MMM dd", buf1, 11) &&
104
          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
105
                        "HH':'mm':'ss", buf2, 9) &&
106
          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
107
                        "yyyy", buf3, 5)) {
108
        os << buf1 << ' ' << buf2 << ' ' << buf3;
109
      }
110
#endif
111
      else os << "unknown";
112
#else
113
      timeval tv;
114
      gettimeofday(&tv, 0);
115

	
116
      char cbuf[26];
117
      ctime_r(&tv.tv_sec,cbuf);
118
      os << cbuf;
119
#endif
120
      return os.str();
121
    }
122

	
123
    int getWinRndSeed()
124
    {
125
#ifdef WIN32
126
      FILETIME time;
127
      GetSystemTimeAsFileTime(&time);
128
      return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
129
#else
130
      timeval tv;
131
      gettimeofday(&tv, 0);
132
      return getpid() + tv.tv_sec + tv.tv_usec;
133
#endif
134
    }
135
  }
136
}
Ignore white space 192 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
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_WINDOWS_H
20
#define LEMON_WINDOWS_H
21

	
22
#include <string>
23

	
24
namespace lemon {
25
  namespace bits {
26
    void getWinProcTimes(double &rtime,
27
                         double &utime, double &stime,
28
                         double &cutime, double &cstime);
29
    std::string getWinFormattedDate();
30
    int getWinRndSeed();
31
  }
32
}
33

	
34
#endif
Ignore white space 192 line context
1 1
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
2 2

	
3 3
ADD_LIBRARY(lemon
4 4
  arg_parser.cc
5 5
  base.cc
6 6
  color.cc
7
  random.cc)
7
  random.cc
8
  bits/windows.cc
9
)
8 10

	
9 11
INSTALL(
10 12
  TARGETS lemon
11 13
  ARCHIVE DESTINATION lib
12 14
  COMPONENT library)
13 15

	
14 16
INSTALL(
15 17
  DIRECTORY . bits concepts
16 18
  DESTINATION include/lemon
17 19
  COMPONENT headers
18 20
  FILES_MATCHING PATTERN "*.h")
Ignore white space 192 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3 3
	lemon/CMakeLists.txt
4 4

	
5 5
pkgconfig_DATA += lemon/lemon.pc
6 6

	
7 7
lib_LTLIBRARIES += lemon/libemon.la
8 8

	
9 9
lemon_libemon_la_SOURCES = \
10 10
        lemon/arg_parser.cc \
11 11
        lemon/base.cc \
12 12
        lemon/color.cc \
13
        lemon/random.cc
13
        lemon/random.cc \
14
	lemon/bits/windows.cc
14 15

	
15 16
#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
16 17
#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
17 18

	
18 19
lemon_HEADERS += \
19 20
        lemon/arg_parser.h \
20 21
	lemon/assert.h \
21 22
        lemon/bfs.h \
22 23
        lemon/bin_heap.h \
23 24
        lemon/color.h \
24 25
	lemon/concept_check.h \
25 26
        lemon/counter.h \
26 27
	lemon/core.h \
27 28
        lemon/dfs.h \
28 29
        lemon/dijkstra.h \
29 30
        lemon/dim2.h \
30 31
	lemon/error.h \
31 32
        lemon/graph_to_eps.h \
32 33
	lemon/kruskal.h \
33 34
	lemon/lgf_reader.h \
34 35
	lemon/lgf_writer.h \
35 36
	lemon/list_graph.h \
36 37
	lemon/maps.h \
37 38
	lemon/math.h \
38 39
	lemon/path.h \
39 40
        lemon/random.h \
40 41
	lemon/smart_graph.h \
41 42
        lemon/time_measure.h \
42 43
        lemon/tolerance.h \
43
	lemon/unionfind.h
44
	lemon/unionfind.h \
45
	lemon/bits/windows.h
44 46

	
45 47
bits_HEADERS += \
46 48
	lemon/bits/alteration_notifier.h \
47 49
	lemon/bits/array_map.h \
48 50
	lemon/bits/base_extender.h \
49 51
        lemon/bits/bezier.h \
50 52
	lemon/bits/default_map.h \
51 53
        lemon/bits/enable_if.h \
52 54
	lemon/bits/graph_extender.h \
53 55
	lemon/bits/map_extender.h \
54 56
	lemon/bits/path_dump.h \
55 57
	lemon/bits/traits.h \
56 58
	lemon/bits/vector_map.h
57 59

	
58 60
concept_HEADERS += \
59 61
	lemon/concepts/digraph.h \
60 62
	lemon/concepts/graph.h \
61 63
	lemon/concepts/graph_components.h \
62 64
	lemon/concepts/heap.h \
63 65
	lemon/concepts/maps.h \
64 66
	lemon/concepts/path.h
Ignore white space 192 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
33
#define WIN32_LEAN_AND_MEAN
34
#endif
35
#ifndef NOMINMAX
36
#define NOMINMAX
37
#endif
38
#include<windows.h>
32
#include<lemon/bits/windows.h>
39 33
#endif
40 34

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

	
49 43

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

	
54 48
namespace lemon {
55 49

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

	
69 63
///Default traits class of GraphToEps
70 64

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

	
85 79

	
86 80
  const Graph &g;
87 81

	
88 82
  std::ostream& os;
89 83

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

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

	
98 92
  ConstMap<typename Graph::Arc,double > _arcWidths;
99 93

	
100 94
  double _arcWidthScale;
101 95

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

	
107 101
  bool _drawArrows;
108 102
  double _arrowLength, _arrowWidth;
109 103

	
110 104
  bool _showNodes, _showArcs;
111 105

	
112 106
  bool _enableParallel;
113 107
  double _parArcDist;
114 108

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

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

	
123 117
  bool _undirected;
124 118

	
125 119
  bool _pleaseRemoveOsStream;
126 120

	
127 121
  bool _scaleToA4;
128 122

	
129 123
  std::string _title;
130 124
  std::string _copyright;
131 125

	
132 126
  enum NodeTextColorType
133 127
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
134 128
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
... ...
@@ -590,227 +584,205 @@
590 584
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
591 585

	
592 586
  ///Sets the size of the node texts
593 587
  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
594 588

	
595 589
  ///Sets the color of the node texts to be different from the node color
596 590

	
597 591
  ///Sets the color of the node texts to be as different from the node color
598 592
  ///as it is possible.
599 593
  GraphToEps<T> &distantColorNodeTexts()
600 594
  {_nodeTextColorType=DIST_COL;return *this;}
601 595
  ///Sets the color of the node texts to be black or white and always visible.
602 596

	
603 597
  ///Sets the color of the node texts to be black or white according to
604 598
  ///which is more different from the node color.
605 599
  GraphToEps<T> &distantBWNodeTexts()
606 600
  {_nodeTextColorType=DIST_BW;return *this;}
607 601

	
608 602
  ///Gives a preamble block for node Postscript block.
609 603

	
610 604
  ///Gives a preamble block for node Postscript block.
611 605
  ///
612 606
  ///\sa nodePsTexts()
613 607
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
614 608
    _nodePsTextsPreamble=str ;return *this;
615 609
  }
616 610
  ///Sets whether the graph is undirected
617 611

	
618 612
  ///Sets whether the graph is undirected.
619 613
  ///
620 614
  ///This setting is the default for undirected graphs.
621 615
  ///
622 616
  ///\sa directed()
623 617
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
624 618

	
625 619
  ///Sets whether the graph is directed
626 620

	
627 621
  ///Sets whether the graph is directed.
628 622
  ///Use it to show the edges as a pair of directed ones.
629 623
  ///
630 624
  ///This setting is the default for digraphs.
631 625
  ///
632 626
  ///\sa undirected()
633 627
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
634 628

	
635 629
  ///Sets the title.
636 630

	
637 631
  ///Sets the title of the generated image,
638 632
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
639 633
  ///the EPS file.
640 634
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
641 635
  ///Sets the copyright statement.
642 636

	
643 637
  ///Sets the copyright statement of the generated image,
644 638
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
645 639
  ///the EPS file.
646 640
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
647 641

	
648 642
protected:
649 643
  bool isInsideNode(dim2::Point<double> p, double r,int t)
650 644
  {
651 645
    switch(t) {
652 646
    case CIRCLE:
653 647
    case MALE:
654 648
    case FEMALE:
655 649
      return p.normSquare()<=r*r;
656 650
    case SQUARE:
657 651
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
658 652
    case DIAMOND:
659 653
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
660 654
    }
661 655
    return false;
662 656
  }
663 657

	
664 658
public:
665 659
  ~GraphToEps() { }
666 660

	
667 661
  ///Draws the graph.
668 662

	
669 663
  ///Like other functions using
670 664
  ///\ref named-templ-func-param "named template parameters",
671 665
  ///this function calls the algorithm itself, i.e. in this case
672 666
  ///it draws the graph.
673 667
  void run() {
674 668
    const double EPSILON=1e-9;
675 669
    if(dontPrint) return;
676 670

	
677 671
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
678 672
      mycoords(_coords,_negY);
679 673

	
680 674
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
681 675
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
682 676
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
683 677
    os << "%%Creator: LEMON, graphToEps()\n";
684 678

	
685 679
    {
680
      os << "%%CreationDate: ";
686 681
#ifndef WIN32
687 682
      timeval tv;
688 683
      gettimeofday(&tv, 0);
689 684

	
690 685
      char cbuf[26];
691 686
      ctime_r(&tv.tv_sec,cbuf);
692
      os << "%%CreationDate: " << cbuf;
687
      os << cbuf;
693 688
#else
694
      SYSTEMTIME time;
695
      GetSystemTime(&time);
696
#if defined(_MSC_VER) && (_MSC_VER < 1500)
697
      LPWSTR buf1, buf2, buf3;
698
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
699
                        L"ddd MMM dd", buf1, 11) &&
700
          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
701
                        L"HH':'mm':'ss", buf2, 9) &&
702
          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
703
                        L"yyyy", buf3, 5)) {
704
        os << "%%CreationDate: " << buf1 << ' '
705
           << buf2 << ' ' << buf3 << std::endl;
706
      }
707
#else
708
        char buf1[11], buf2[9], buf3[5];
709
        if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
710
                          "ddd MMM dd", buf1, 11) &&
711
            GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
712
                          "HH':'mm':'ss", buf2, 9) &&
713
            GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
714
                          "yyyy", buf3, 5)) {
715
          os << "%%CreationDate: " << buf1 << ' '
716
             << buf2 << ' ' << buf3 << std::endl;
717
        }
718
#endif
689
      os << bits::getWinFormattedDate();
719 690
#endif
720 691
    }
692
    os << std::endl;
721 693

	
722 694
    if (_autoArcWidthScale) {
723 695
      double max_w=0;
724 696
      for(ArcIt e(g);e!=INVALID;++e)
725 697
        max_w=std::max(double(_arcWidths[e]),max_w);
726 698
      if(max_w>EPSILON) {
727 699
        _arcWidthScale/=max_w;
728 700
      }
729 701
    }
730 702

	
731 703
    if (_autoNodeScale) {
732 704
      double max_s=0;
733 705
      for(NodeIt n(g);n!=INVALID;++n)
734 706
        max_s=std::max(double(_nodeSizes[n]),max_s);
735 707
      if(max_s>EPSILON) {
736 708
        _nodeScale/=max_s;
737 709
      }
738 710
    }
739 711

	
740 712
    double diag_len = 1;
741 713
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
742 714
      dim2::Box<double> bb;
743 715
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
744 716
      if (bb.empty()) {
745 717
        bb = dim2::Box<double>(dim2::Point<double>(0,0));
746 718
      }
747 719
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
748 720
      if(diag_len<EPSILON) diag_len = 1;
749 721
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
750 722
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
751 723
    }
752 724

	
753 725
    dim2::Box<double> bb;
754 726
    for(NodeIt n(g);n!=INVALID;++n) {
755 727
      double ns=_nodeSizes[n]*_nodeScale;
756 728
      dim2::Point<double> p(ns,ns);
757 729
      switch(_nodeShapes[n]) {
758 730
      case CIRCLE:
759 731
      case SQUARE:
760 732
      case DIAMOND:
761 733
        bb.add(p+mycoords[n]);
762 734
        bb.add(-p+mycoords[n]);
763 735
        break;
764 736
      case MALE:
765 737
        bb.add(-p+mycoords[n]);
766 738
        bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
767 739
        break;
768 740
      case FEMALE:
769 741
        bb.add(p+mycoords[n]);
770 742
        bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
771 743
        break;
772 744
      }
773 745
    }
774 746
    if (bb.empty()) {
775 747
      bb = dim2::Box<double>(dim2::Point<double>(0,0));
776 748
    }
777 749

	
778 750
    if(_scaleToA4)
779 751
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
780 752
    else {
781 753
      if(_preScale) {
782 754
        //Rescale so that BoundingBox won't be neither to big nor too small.
783 755
        while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
784 756
        while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
785 757
      }
786 758

	
787 759
      os << "%%BoundingBox: "
788 760
         << int(floor(bb.left()   * _scale - _xBorder)) << ' '
789 761
         << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
790 762
         << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
791 763
         << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
792 764
    }
793 765

	
794 766
    os << "%%EndComments\n";
795 767

	
796 768
    //x1 y1 x2 y2 x3 y3 cr cg cb w
797 769
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
798 770
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
799 771
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }"
800 772
       << " bind def\n";
801 773
    //x y r
802 774
    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath }"
803 775
       << " bind def\n";
804 776
    //x y r
805 777
    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
806 778
       << "      2 index 1 index sub 2 index 2 index add lineto\n"
807 779
       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
808 780
       << "      2 index 1 index add 2 index 2 index sub lineto\n"
809 781
       << "      closepath pop pop pop} bind def\n";
810 782
    //x y r
811 783
    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
812 784
       << "      2 index             2 index 2 index add lineto\n"
813 785
       << "      2 index 1 index sub 2 index             lineto\n"
814 786
       << "      2 index             2 index 2 index sub lineto\n"
815 787
       << "      closepath pop pop pop} bind def\n";
816 788
    // x y r cr cg cb
Ignore white space 192 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
/*
20 20
 * This file contains the reimplemented version of the Mersenne Twister
21 21
 * Generator of Matsumoto and Nishimura.
22 22
 *
23 23
 * See the appropriate copyright notice below.
24 24
 *
25 25
 * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
26 26
 * All rights reserved.
27 27
 *
28 28
 * Redistribution and use in source and binary forms, with or without
29 29
 * modification, are permitted provided that the following conditions
30 30
 * are met:
31 31
 *
32 32
 * 1. Redistributions of source code must retain the above copyright
33 33
 *    notice, this list of conditions and the following disclaimer.
34 34
 *
35 35
 * 2. Redistributions in binary form must reproduce the above copyright
36 36
 *    notice, this list of conditions and the following disclaimer in the
37 37
 *    documentation and/or other materials provided with the distribution.
38 38
 *
39 39
 * 3. The names of its contributors may not be used to endorse or promote
40 40
 *    products derived from this software without specific prior written
41 41
 *    permission.
42 42
 *
43 43
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 44
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 45
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46 46
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
47 47
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48 48
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49 49
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 50
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 51
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 52
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 53
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 54
 * OF THE POSSIBILITY OF SUCH DAMAGE.
55 55
 *
56 56
 *
57 57
 * Any feedback is very welcome.
58 58
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
59 59
 * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
60 60
 */
61 61

	
62 62
#ifndef LEMON_RANDOM_H
63 63
#define LEMON_RANDOM_H
64 64

	
65 65
#include <algorithm>
66 66
#include <iterator>
67 67
#include <vector>
68 68
#include <limits>
69 69
#include <fstream>
70 70

	
71 71
#include <lemon/math.h>
72 72
#include <lemon/dim2.h>
73 73

	
74 74
#ifndef WIN32
75 75
#include <sys/time.h>
76 76
#include <ctime>
77 77
#include <sys/types.h>
78 78
#include <unistd.h>
79 79
#else
80
#include <windows.h>
80
#include <lemon/bits/windows.h>
81 81
#endif
82 82

	
83 83
///\ingroup misc
84 84
///\file
85 85
///\brief Mersenne Twister random number generator
86 86

	
87 87
namespace lemon {
88 88

	
89 89
  namespace _random_bits {
90 90

	
91 91
    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
92 92
    struct RandomTraits {};
93 93

	
94 94
    template <typename _Word>
95 95
    struct RandomTraits<_Word, 32> {
96 96

	
97 97
      typedef _Word Word;
98 98
      static const int bits = 32;
99 99

	
100 100
      static const int length = 624;
101 101
      static const int shift = 397;
102 102

	
103 103
      static const Word mul = 0x6c078965u;
104 104
      static const Word arrayInit = 0x012BD6AAu;
105 105
      static const Word arrayMul1 = 0x0019660Du;
106 106
      static const Word arrayMul2 = 0x5D588B65u;
107 107

	
108 108
      static const Word mask = 0x9908B0DFu;
109 109
      static const Word loMask = (1u << 31) - 1;
110 110
      static const Word hiMask = ~loMask;
111 111

	
112 112

	
113 113
      static Word tempering(Word rnd) {
114 114
        rnd ^= (rnd >> 11);
115 115
        rnd ^= (rnd << 7) & 0x9D2C5680u;
116 116
        rnd ^= (rnd << 15) & 0xEFC60000u;
117 117
        rnd ^= (rnd >> 18);
118 118
        return rnd;
119 119
      }
120 120

	
121 121
    };
122 122

	
123 123
    template <typename _Word>
124 124
    struct RandomTraits<_Word, 64> {
125 125

	
126 126
      typedef _Word Word;
127 127
      static const int bits = 64;
128 128

	
129 129
      static const int length = 312;
130 130
      static const int shift = 156;
131 131

	
132 132
      static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
133 133
      static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
134 134
      static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
135 135
      static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
136 136

	
137 137
      static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
138 138
      static const Word loMask = (Word(1u) << 31) - 1;
139 139
      static const Word hiMask = ~loMask;
140 140

	
141 141
      static Word tempering(Word rnd) {
142 142
        rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
143 143
        rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
144 144
        rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
145 145
        rnd ^= (rnd >> 43);
146 146
        return rnd;
147 147
      }
148 148

	
149 149
    };
150 150

	
151 151
    template <typename _Word>
152 152
    class RandomCore {
153 153
    public:
154 154

	
155 155
      typedef _Word Word;
156 156

	
157 157
    private:
158 158

	
159 159
      static const int bits = RandomTraits<Word>::bits;
160 160

	
161 161
      static const int length = RandomTraits<Word>::length;
162 162
      static const int shift = RandomTraits<Word>::shift;
163 163

	
164 164
    public:
165 165

	
166 166
      void initState() {
167 167
        static const Word seedArray[4] = {
168 168
          0x12345u, 0x23456u, 0x34567u, 0x45678u
169 169
        };
170 170

	
171 171
        initState(seedArray, seedArray + 4);
172 172
      }
173 173

	
174 174
      void initState(Word seed) {
175 175

	
176 176
        static const Word mul = RandomTraits<Word>::mul;
... ...
@@ -573,195 +573,193 @@
573 573
    ///
574 574
    /// Copy constructor. The generated sequence will be identical to
575 575
    /// the other sequence. It can be used to save the current state
576 576
    /// of the generator and later use it to generate the same
577 577
    /// sequence.
578 578
    Random(const Random& other) {
579 579
      core.copyState(other.core);
580 580
    }
581 581

	
582 582
    /// \brief Assign operator
583 583
    ///
584 584
    /// Assign operator. The generated sequence will be identical to
585 585
    /// the other sequence. It can be used to save the current state
586 586
    /// of the generator and later use it to generate the same
587 587
    /// sequence.
588 588
    Random& operator=(const Random& other) {
589 589
      if (&other != this) {
590 590
        core.copyState(other.core);
591 591
      }
592 592
      return *this;
593 593
    }
594 594

	
595 595
    /// \brief Seeding random sequence
596 596
    ///
597 597
    /// Seeding the random sequence. The current number type will be
598 598
    /// converted to the architecture word type.
599 599
    template <typename Number>
600 600
    void seed(Number seed) {
601 601
      _random_bits::Initializer<Number, Word>::init(core, seed);
602 602
    }
603 603

	
604 604
    /// \brief Seeding random sequence
605 605
    ///
606 606
    /// Seeding the random sequence. The given range should contain
607 607
    /// any number type and the numbers will be converted to the
608 608
    /// architecture word type.
609 609
    template <typename Iterator>
610 610
    void seed(Iterator begin, Iterator end) {
611 611
      typedef typename std::iterator_traits<Iterator>::value_type Number;
612 612
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
613 613
    }
614 614

	
615 615
    /// \brief Seeding from file or from process id and time
616 616
    ///
617 617
    /// By default, this function calls the \c seedFromFile() member
618 618
    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
619 619
    /// it uses the \c seedFromTime().
620 620
    /// \return Currently always true.
621 621
    bool seed() {
622 622
#ifndef WIN32
623 623
      if (seedFromFile("/dev/urandom", 0)) return true;
624 624
#endif
625 625
      if (seedFromTime()) return true;
626 626
      return false;
627 627
    }
628 628

	
629 629
    /// \brief Seeding from file
630 630
    ///
631 631
    /// Seeding the random sequence from file. The linux kernel has two
632 632
    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
633 633
    /// could give good seed values for pseudo random generators (The
634 634
    /// difference between two devices is that the <tt>random</tt> may
635 635
    /// block the reading operation while the kernel can give good
636 636
    /// source of randomness, while the <tt>urandom</tt> does not
637 637
    /// block the input, but it could give back bytes with worse
638 638
    /// entropy).
639 639
    /// \param file The source file
640 640
    /// \param offset The offset, from the file read.
641 641
    /// \return True when the seeding successes.
642 642
#ifndef WIN32
643 643
    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
644 644
#else
645 645
    bool seedFromFile(const std::string& file = "", int offset = 0)
646 646
#endif
647 647
    {
648 648
      std::ifstream rs(file.c_str());
649 649
      const int size = 4;
650 650
      Word buf[size];
651 651
      if (offset != 0 && !rs.seekg(offset)) return false;
652 652
      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
653 653
      seed(buf, buf + size);
654 654
      return true;
655 655
    }
656 656

	
657 657
    /// \brief Seding from process id and time
658 658
    ///
659 659
    /// Seding from process id and time. This function uses the
660 660
    /// current process id and the current time for initialize the
661 661
    /// random sequence.
662 662
    /// \return Currently always true.
663 663
    bool seedFromTime() {
664 664
#ifndef WIN32
665 665
      timeval tv;
666 666
      gettimeofday(&tv, 0);
667 667
      seed(getpid() + tv.tv_sec + tv.tv_usec);
668 668
#else
669
      FILETIME time;
670
      GetSystemTimeAsFileTime(&time);
671
      seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
669
      seed(bits::getWinRndSeed());
672 670
#endif
673 671
      return true;
674 672
    }
675 673

	
676 674
    /// @}
677 675

	
678 676
    ///\name Uniform distributions
679 677
    ///
680 678
    /// @{
681 679

	
682 680
    /// \brief Returns a random real number from the range [0, 1)
683 681
    ///
684 682
    /// It returns a random real number from the range [0, 1). The
685 683
    /// default Number type is \c double.
686 684
    template <typename Number>
687 685
    Number real() {
688 686
      return _random_bits::RealConversion<Number, Word>::convert(core);
689 687
    }
690 688

	
691 689
    double real() {
692 690
      return real<double>();
693 691
    }
694 692

	
695 693
    /// @}
696 694

	
697 695
    ///\name Uniform distributions
698 696
    ///
699 697
    /// @{
700 698

	
701 699
    /// \brief Returns a random real number from the range [0, 1)
702 700
    ///
703 701
    /// It returns a random double from the range [0, 1).
704 702
    double operator()() {
705 703
      return real<double>();
706 704
    }
707 705

	
708 706
    /// \brief Returns a random real number from the range [0, b)
709 707
    ///
710 708
    /// It returns a random real number from the range [0, b).
711 709
    double operator()(double b) {
712 710
      return real<double>() * b;
713 711
    }
714 712

	
715 713
    /// \brief Returns a random real number from the range [a, b)
716 714
    ///
717 715
    /// It returns a random real number from the range [a, b).
718 716
    double operator()(double a, double b) {
719 717
      return real<double>() * (b - a) + a;
720 718
    }
721 719

	
722 720
    /// \brief Returns a random integer from a range
723 721
    ///
724 722
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
725 723
    template <typename Number>
726 724
    Number integer(Number b) {
727 725
      return _random_bits::Mapping<Number, Word>::map(core, b);
728 726
    }
729 727

	
730 728
    /// \brief Returns a random integer from a range
731 729
    ///
732 730
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
733 731
    template <typename Number>
734 732
    Number integer(Number a, Number b) {
735 733
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
736 734
    }
737 735

	
738 736
    /// \brief Returns a random integer from a range
739 737
    ///
740 738
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
741 739
    template <typename Number>
742 740
    Number operator[](Number b) {
743 741
      return _random_bits::Mapping<Number, Word>::map(core, b);
744 742
    }
745 743

	
746 744
    /// \brief Returns a random non-negative integer
747 745
    ///
748 746
    /// It returns a random non-negative integer uniformly from the
749 747
    /// whole range of the current \c Number type. The default result
750 748
    /// type of this function is <tt>unsigned int</tt>.
751 749
    template <typename Number>
752 750
    Number uinteger() {
753 751
      return _random_bits::IntConversion<Number, Word>::convert(core);
754 752
    }
755 753

	
756 754
    /// @}
757 755

	
758 756
    unsigned int uinteger() {
759 757
      return uinteger<unsigned int>();
760 758
    }
761 759

	
762 760
    /// \brief Returns a random integer
763 761
    ///
764 762
    /// It returns a random integer uniformly from the whole range of
765 763
    /// the current \c Number type. The default result type of this
766 764
    /// function is \c int.
767 765
    template <typename Number>
Ignore white space 192 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
28
#define WIN32_LEAN_AND_MEAN
29
#endif
30
#ifndef NOMINMAX
31
#define NOMINMAX
32
#endif
33
#include <windows.h>
34
#include <cmath>
27
#include <lemon/bits/windows.h>
35 28
#else
36 29
#include <unistd.h>
37 30
#include <sys/times.h>
38 31
#include <sys/time.h>
39 32
#endif
40 33

	
41 34
#include <string>
42 35
#include <fstream>
43 36
#include <iostream>
44 37

	
45 38
namespace lemon {
46 39

	
47 40
  /// \addtogroup timecount
48 41
  /// @{
49 42

	
50 43
  /// A class to store (cpu)time instances.
51 44

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

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

	
73 66
    void _reset() {
74 67
      utime = stime = cutime = cstime = rtime = 0;
75 68
    }
76 69

	
77 70
  public:
78 71

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

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

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

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

	
118 92
    /// Constructor initializing with zero
119 93
    TimeStamp()
120 94
    { _reset(); }
121 95
    ///Constructor initializing with the current time values of the process
122 96
    TimeStamp(void *) { stamp();}
123 97

	
124 98
    ///Set every time value to zero
125 99
    TimeStamp &reset() {_reset();return *this;}
126 100

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

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

	
201 175
    ///Gives back the user time of the process
202 176
    double userTime() const
203 177
    {
204 178
      return utime;
205 179
    }
206 180
    ///Gives back the system time of the process
207 181
    double systemTime() const
208 182
    {
209 183
      return stime;
210 184
    }
0 comments (0 inline)