↑ Collapse diff ↑
Ignore white space 1099511627776 line context
1
project (LEMON)
2
enable_testing ()
3
add_subdirectory (lemon)
4
add_subdirectory (demo)
5
add_subdirectory (test)
Ignore white space 1099511627776 line context
1
include_directories (${LEMON_SOURCE_DIR})
2

	
3
link_directories (${LEMON_BINARY_DIR}/lemon)
4

	
5
set (DEMOS
6
  arg_parser_demo
7
  graph_to_eps_demo
8
  lgf_demo)
9

	
10
foreach (DEMO_NAME ${DEMOS})
11
  add_executable (${DEMO_NAME} ${DEMO_NAME}.cc)
12
  target_link_libraries (${DEMO_NAME} lemon)
13
  endforeach (DEMO_NAME)
Ignore white space 1099511627776 line context
1
include_directories (${LEMON_SOURCE_DIR})
2
add_library (lemon arg_parser.cc base.cc color.cc random.cc)
Ignore white space 1099511627776 line context
1
include_directories (${LEMON_SOURCE_DIR})
2

	
3
link_directories (${LEMON_BINARY_DIR}/lemon)
4

	
5
set (TESTS
6
  bfs_test
7
  counter_test
8
  dfs_test
9
  digraph_test
10
  dim_test
11
  error_test
12
  graph_test
13
  kruskal_test
14
  maps_test
15
  random_test
16
  path_test
17
  time_measure_test
18
  unionfind_test)
19

	
20
foreach (TEST_NAME ${TESTS})
21
  add_executable (${TEST_NAME} ${TEST_NAME}.cc)
22
  target_link_libraries (${TEST_NAME} lemon)
23
  add_test(${TEST_NAME} ${TEST_NAME})
24
endforeach (TEST_NAME)
Ignore white space 1099511627776 line context
1 1
syntax: glob
2 2
*.obj
3 3
*.orig
4 4
*.rej
5 5
*~
6 6
*.o
7 7
*.log
8 8
*.lo
9 9
*.tar.*
10 10
Makefile.in
11 11
aclocal.m4
12 12
config.h.in
13 13
configure
14 14
Makefile
15 15
config.h
16 16
config.log
17 17
config.status
18 18
libtool
19 19
stamp-h1
20 20
lemon/lemon.pc
21 21
lemon/libemon.la
22 22
lemon/stamp-h2
23 23
doc/Doxyfile
24 24
.dirstamp
25 25
.libs/*
26 26
.deps/*
27 27
demo/*.eps
28 28

	
29 29
syntax: regexp
30 30
(.*/)?\#[^/]*\#$
31 31
^doc/html/.*
32 32
^autom4te.cache/.*
33 33
^build-aux/.*
34 34
^objs.*/.*
35 35
^test/[a-z_]*$
36 36
^demo/.*_demo$
37
^build/.*
38
CMakeFiles
39
DartTestfile.txt
40
cmake_install.cmake
41
CMakeCache.txt
Ignore white space 1099511627776 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 1099511627776 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_ASSERT_H
20 20
#define LEMON_ASSERT_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Extended assertion handling
25 25

	
26 26
#include <lemon/error.h>
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  inline void assert_fail_log(const char *file, int line, const char *function,
31 31
			      const char *message, const char *assertion)
32 32
  {
33 33
    std::cerr << file << ":" << line << ": ";
34 34
    if (function)
35 35
      std::cerr << function << ": ";
36 36
    std::cerr << message;
37 37
    if (assertion)
38 38
      std::cerr << " (assertion '" << assertion << "' failed)";
39 39
    std::cerr << std::endl;
40 40
  }
41 41

	
42 42
  inline void assert_fail_abort(const char *file, int line,
43 43
				const char *function, const char* message,
44 44
				const char *assertion)
45 45
  {
46 46
    assert_fail_log(file, line, function, message, assertion);
47 47
    std::abort();
48 48
  }
49 49

	
50 50
  namespace _assert_bits {
51 51
    
52 52
    
53 53
    inline const char* cstringify(const std::string& str) {
54 54
      return str.c_str();
55 55
    }
56 56

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

	
63 63
#endif // LEMON_ASSERT_H
64 64

	
65 65
#undef LEMON_ASSERT
66 66
#undef LEMON_FIXME
67 67
#undef LEMON_DEBUG
68 68

	
69 69
#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
70 70
  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
71 71
  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
72 72
#error "LEMON assertion system is not set properly"
73 73
#endif
74 74

	
75 75
#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
76 76
     (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
77 77
     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||	\
78 78
     defined(LEMON_ENABLE_ASSERTS)) &&			\
79 79
  (defined(LEMON_DISABLE_ASSERTS) ||			\
80 80
   defined(NDEBUG))
81 81
#error "LEMON assertion system is not set properly"
82 82
#endif
83 83

	
84 84

	
85 85
#if defined LEMON_ASSERT_LOG
86 86
#  undef LEMON_ASSERT_HANDLER
87 87
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log
88 88
#elif defined LEMON_ASSERT_ABORT
89 89
#  undef LEMON_ASSERT_HANDLER
90 90
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
91 91
#elif defined LEMON_ASSERT_CUSTOM
92 92
#  undef LEMON_ASSERT_HANDLER
93 93
#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
94 94
#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
95 95
#  endif
96 96
#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
97 97
#elif defined LEMON_DISABLE_ASSERTS
98 98
#  undef LEMON_ASSERT_HANDLER
99 99
#elif defined NDEBUG
100 100
#  undef LEMON_ASSERT_HANDLER
101 101
#else
102 102
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
103 103
#endif
104 104

	
105 105
#ifndef LEMON_FUNCTION_NAME
106
#  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
106
#  if defined __GNUC__
107
#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
108
#  elif defined _MSC_VER
109
#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
110
#  else
111
#    define LEMON_FUNCTION_NAME (__func__)
112
#  endif
107 113
#endif
108 114

	
109 115
#ifdef DOXYGEN
110 116

	
111 117
/// \ingroup exceptions
112 118
///
113 119
/// \brief Macro for assertion with customizable message
114 120
///
115 121
/// Macro for assertion with customizable message.  \param exp An
116 122
/// expression that must be convertible to \c bool.  If it is \c
117 123
/// false, then an assertion is raised. The concrete behaviour depends
118 124
/// on the settings of the assertion system.  \param msg A <tt>const
119 125
/// char*</tt> parameter, which can be used to provide information
120 126
/// about the circumstances of the failed assertion.
121 127
///
122 128
/// The assertions are enabled in the default behaviour.
123 129
/// You can disable them with the following code:
124 130
/// \code
125 131
/// #define LEMON_DISABLE_ASSERTS
126 132
/// \endcode
127 133
/// or with compilation parameters:
128 134
/// \code
129 135
/// g++ -DLEMON_DISABLE_ASSERTS
130 136
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
131 137
/// \endcode
132 138
/// The checking is also disabled when the standard macro \c NDEBUG is defined.
133 139
/// 
134 140
/// The LEMON assertion system has a wide range of customization
135 141
/// properties. As a default behaviour the failed assertion prints a
136 142
/// short log message to the standard error and aborts the execution.
137 143
///
138 144
/// The following modes can be used in the assertion system: 
139 145
///
140 146
/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
141 147
///   message to the standard error and continues the execution.
142 148
/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
143 149
///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
144 150
///   behaviour.
145 151
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
146 152
///   function.
147 153
///   \code
148 154
///     void custom_assert_handler(const char* file, int line, const char* function,
149 155
///                                const char* message, const char* assertion);
150 156
///   \endcode
151 157
///   The name of the function should be defined as the \c
152 158
///   LEMON_CUSTOM_ASSERT_HANDLER macro name. 
153 159
///   \code
154 160
///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
155 161
///   \endcode
156 162
///   Whenever an assertion is occured, the custom assertion
157 163
///   handler is called with appropiate parameters.
158 164
///
159 165
/// The assertion mode can also be changed within one compilation unit.
160 166
/// If the macros are redefined with other settings and the
161 167
/// \ref lemon/assert.h "assert.h" file is reincluded, then the
162 168
/// behaviour is changed appropiately to the new settings.
163 169
#  define LEMON_ASSERT(exp, msg)					\
164 170
  (static_cast<void> (!!(exp) ? 0 : (					\
165 171
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,				\
166 172
			 LEMON_FUNCTION_NAME,				\
167 173
			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
168 174

	
169 175
/// \ingroup exceptions
170 176
///
171 177
/// \brief Macro for mark not yet implemented features.
172 178
///
173 179
/// Macro for mark not yet implemented features and outstanding bugs.
174 180
/// It is close to be the shortcut of the following code:
175 181
/// \code
176 182
///   LEMON_ASSERT(false, msg);
177 183
/// \endcode
178 184
///
179 185
/// \see LEMON_ASSERT 
180 186
#  define LEMON_FIXME(msg)						\
181 187
  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
182 188
			::lemon::_assert_bits::cstringify(msg),		\
183 189
			static_cast<const char*>(0)))
184 190

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

	
214 220
#else
215 221

	
216 222
#  ifndef LEMON_ASSERT_HANDLER
217 223
#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
218 224
#    define LEMON_FIXME(msg) (static_cast<void>(0))
219 225
#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
220 226
#  else
221 227
#    define LEMON_ASSERT(exp, msg)					\
222 228
       (static_cast<void> (!!(exp) ? 0 : (				\
223 229
        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
224 230
			     LEMON_FUNCTION_NAME,			\
225 231
			     ::lemon::_assert_bits::cstringify(msg),	\
226 232
			     #exp), 0)))
227 233
#    define LEMON_FIXME(msg)						\
228 234
       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
229 235
			     ::lemon::_assert_bits::cstringify(msg),	\
230 236
			     static_cast<const char*>(0)))
231 237

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

	
244 250
#endif
245 251

	
246 252
#ifdef DOXYGEN
247 253

	
248 254

	
249 255
#else
250 256

	
251 257

	
252 258
#endif
253 259

	
254 260

	
Ignore white space 1099511627776 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

	
416 418
  ///Sets the map of the arc widths
417 419
  ///\param x must be a arc map with \c double (or convertible) values. 
418 420
  template<class X> GraphToEps<ArcWidthsTraits<X> > arcWidths(const X &x)
419 421
  {
420 422
    dontPrint=true;
421 423
    return GraphToEps<ArcWidthsTraits<X> >(ArcWidthsTraits<X>(*this,x));
422 424
  }
423 425

	
424 426
  template<class X> struct NodeColorsTraits : public T {
425 427
    const X &_nodeColors;
426 428
    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
427 429
  };
428 430
  ///Sets the map of the node colors
429 431

	
430 432
  ///Sets the map of the node colors
431 433
  ///\param x must be a node map with \ref Color values.
432 434
  ///
433 435
  ///\sa Palette
434 436
  template<class X> GraphToEps<NodeColorsTraits<X> >
435 437
  nodeColors(const X &x)
436 438
  {
437 439
    dontPrint=true;
438 440
    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
439 441
  }
440 442
  template<class X> struct NodeTextColorsTraits : public T {
441 443
    const X &_nodeTextColors;
442 444
    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
443 445
  };
444 446
  ///Sets the map of the node text colors
445 447

	
446 448
  ///Sets the map of the node text colors
447 449
  ///\param x must be a node map with \ref Color values. 
448 450
  ///
449 451
  ///\sa Palette
450 452
  template<class X> GraphToEps<NodeTextColorsTraits<X> >
451 453
  nodeTextColors(const X &x)
452 454
  {
453 455
    dontPrint=true;
454 456
    _nodeTextColorType=CUST_COL;
455 457
    return GraphToEps<NodeTextColorsTraits<X> >
456 458
      (NodeTextColorsTraits<X>(*this,x));
457 459
  }
458 460
  template<class X> struct ArcColorsTraits : public T {
459 461
    const X &_arcColors;
460 462
    ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {}
461 463
  };
462 464
  ///Sets the map of the arc colors
463 465

	
464 466
  ///Sets the map of the arc colors
465 467
  ///\param x must be a arc map with \ref Color values. 
466 468
  ///
467 469
  ///\sa Palette
468 470
  template<class X> GraphToEps<ArcColorsTraits<X> >
469 471
  arcColors(const X &x)
470 472
  {
471 473
    dontPrint=true;
472 474
    return GraphToEps<ArcColorsTraits<X> >(ArcColorsTraits<X>(*this,x));
473 475
  }
474 476
  ///Sets a global scale factor for node sizes
475 477

	
476 478
  ///Sets a global scale factor for node sizes.
477 479
  /// 
478 480
  /// If nodeSizes() is not given, this function simply sets the node
479 481
  /// sizes to \c d.  If nodeSizes() is given, but
480 482
  /// autoNodeScale() is not, then the node size given by
481 483
  /// nodeSizes() will be multiplied by the value \c d.
482 484
  /// If both nodeSizes() and autoNodeScale() are used, then the
483 485
  /// node sizes will be scaled in such a way that the greatest size will be
484 486
  /// equal to \c d.
485 487
  /// \sa nodeSizes()
486 488
  /// \sa autoNodeScale()
487 489
  GraphToEps<T> &nodeScale(double d=.01) {_nodeScale=d;return *this;}
488 490
  ///Turns on/off the automatic node width scaling.
489 491

	
490 492
  ///Turns on/off the automatic node width scaling.
491 493
  ///
492 494
  ///\sa nodeScale()
493 495
  ///
494 496
  GraphToEps<T> &autoNodeScale(bool b=true) {
495 497
    _autoNodeScale=b;return *this;
496 498
  }
497 499

	
498 500
  ///Turns on/off the absolutematic node width scaling.
499 501

	
500 502
  ///Turns on/off the absolutematic node width scaling.
501 503
  ///
502 504
  ///\sa nodeScale()
503 505
  ///
504 506
  GraphToEps<T> &absoluteNodeSizes(bool b=true) {
505 507
    _absoluteNodeSizes=b;return *this;
506 508
  }
507 509

	
508 510
  ///Negates the Y coordinates.
509 511

	
510 512
  ///Negates the Y coordinates.
511 513
  ///
512 514
  GraphToEps<T> &negateY(bool b=true) {
513 515
    _negY=b;return *this;
514 516
  }
515 517

	
516 518
  ///Turn on/off pre-scaling
517 519

	
518 520
  ///By default graphToEps() rescales the whole image in order to avoid
519 521
  ///very big or very small bounding boxes.
520 522
  ///
521 523
  ///This (p)rescaling can be turned off with this function.
522 524
  ///
523 525
  GraphToEps<T> &preScale(bool b=true) {
524 526
    _preScale=b;return *this;
525 527
  }
526 528

	
527 529
  ///Sets a global scale factor for arc widths
528 530

	
529 531
  /// Sets a global scale factor for arc widths.
530 532
  ///
531 533
  /// If arcWidths() is not given, this function simply sets the arc
532 534
  /// widths to \c d.  If arcWidths() is given, but
533 535
  /// autoArcWidthScale() is not, then the arc withs given by
534 536
  /// arcWidths() will be multiplied by the value \c d.
535 537
  /// If both arcWidths() and autoArcWidthScale() are used, then the
536 538
  /// arc withs will be scaled in such a way that the greatest width will be
537 539
  /// equal to \c d.
538 540
  GraphToEps<T> &arcWidthScale(double d=.003) {_arcWidthScale=d;return *this;}
539 541
  ///Turns on/off the automatic arc width scaling.
540 542

	
541 543
  ///Turns on/off the automatic arc width scaling.
542 544
  ///
543 545
  ///\sa arcWidthScale()
544 546
  ///
545 547
  GraphToEps<T> &autoArcWidthScale(bool b=true) {
546 548
    _autoArcWidthScale=b;return *this;
547 549
  }
548 550
  ///Turns on/off the absolutematic arc width scaling.
549 551

	
550 552
  ///Turns on/off the absolutematic arc width scaling.
551 553
  ///
552 554
  ///\sa arcWidthScale()
553 555
  ///
554 556
  GraphToEps<T> &absoluteArcWidths(bool b=true) {
555 557
    _absoluteArcWidths=b;return *this;
556 558
  }
557 559
  ///Sets a global scale factor for the whole picture
558 560

	
559 561
  ///Sets a global scale factor for the whole picture
560 562
  ///
561 563

	
562 564
  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
563 565
  ///Sets the width of the border around the picture
564 566

	
565 567
  ///Sets the width of the border around the picture
566 568
  ///
567 569
  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
568 570
  ///Sets the width of the border around the picture
569 571

	
570 572
  ///Sets the width of the border around the picture
571 573
  ///
572 574
  GraphToEps<T> &border(double x, double y) {
573 575
    _xBorder=x;_yBorder=y;return *this;
574 576
  }
575 577
  ///Sets whether to draw arrows
576 578

	
577 579
  ///Sets whether to draw arrows
578 580
  ///
579 581
  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
580 582
  ///Sets the length of the arrowheads
581 583

	
582 584
  ///Sets the length of the arrowheads
583 585
  ///
584 586
  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
585 587
  ///Sets the width of the arrowheads
586 588

	
587 589
  ///Sets the width of the arrowheads
588 590
  ///
589 591
  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
590 592
  
591 593
  ///Scales the drawing to fit to A4 page
592 594

	
593 595
  ///Scales the drawing to fit to A4 page
594 596
  ///
595 597
  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
596 598
  
597 599
  ///Enables parallel arcs
598 600

	
599 601
  ///Enables parallel arcs
600 602
  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
601 603
  
602 604
  ///Sets the distance 
603 605
  
604 606
  ///Sets the distance 
605 607
  ///
606 608
  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
607 609
  
608 610
  ///Hides the arcs
609 611
  
610 612
  ///Hides the arcs
611 613
  ///
612 614
  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
613 615
  ///Hides the nodes
614 616
  
615 617
  ///Hides the nodes
616 618
  ///
617 619
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
618 620
  
619 621
  ///Sets the size of the node texts
620 622
  
621 623
  ///Sets the size of the node texts
622 624
  ///
623 625
  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
624 626

	
625 627
  ///Sets the color of the node texts to be different from the node color
626 628

	
627 629
  ///Sets the color of the node texts to be as different from the node color
628 630
  ///as it is possible
629 631
  ///
630 632
  GraphToEps<T> &distantColorNodeTexts()
631 633
  {_nodeTextColorType=DIST_COL;return *this;}
632 634
  ///Sets the color of the node texts to be black or white and always visible.
633 635

	
634 636
  ///Sets the color of the node texts to be black or white according to
635 637
  ///which is more 
636 638
  ///different from the node color
637 639
  ///
638 640
  GraphToEps<T> &distantBWNodeTexts()
639 641
  {_nodeTextColorType=DIST_BW;return *this;}
640 642

	
641 643
  ///Gives a preamble block for node Postscript block.
642 644
  
643 645
  ///Gives a preamble block for node Postscript block.
644 646
  ///
645 647
  ///\sa nodePsTexts()
646 648
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
647 649
    _nodePsTextsPreamble=str ;return *this;
648 650
  }
649 651
  ///Sets whether the the graph is undirected
650 652

	
651 653
  ///Sets whether the the graph is undirected.
652 654
  ///
653 655
  ///This setting is the default for undirected graphs.
654 656
  ///
655 657
  ///\sa directed()
656 658
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
657 659

	
658 660
  ///Sets whether the the graph is directed
659 661

	
660 662
  ///Sets whether the the graph is directed.
661 663
  ///Use it to show the edges as a pair of directed ones.
662 664
  ///
663 665
  ///This setting is the default for digraphs.
664 666
  ///
665 667
  ///\sa undirected()
666 668
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
667 669
  
668 670
  ///Sets the title.
669 671

	
670 672
  ///Sets the title of the generated image,
671 673
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
672 674
  ///the EPS file.
673 675
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
674 676
  ///Sets the copyright statement.
675 677

	
676 678
  ///Sets the copyright statement of the generated image,
677 679
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
678 680
  ///the EPS file.
679 681
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
680 682

	
681 683
protected:
682 684
  bool isInsideNode(dim2::Point<double> p, double r,int t) 
683 685
  {
684 686
    switch(t) {
685 687
    case CIRCLE:
686 688
    case MALE:
687 689
    case FEMALE:
688 690
      return p.normSquare()<=r*r;
689 691
    case SQUARE:
690 692
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
691 693
    case DIAMOND:
692 694
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
693 695
    }
694 696
    return false;
695 697
  }
696 698

	
697 699
public:
698 700
  ~GraphToEps() { }
699 701
  
700 702
  ///Draws the graph.
701 703

	
702 704
  ///Like other functions using
703 705
  ///\ref named-templ-func-param "named template parameters",
704 706
  ///this function calls the algorithm itself, i.e. in this case
705 707
  ///it draws the graph.
706 708
  void run() {
707 709
    //\todo better 'epsilon' would be nice here.
708 710
    const double EPSILON=1e-9;
709 711
    if(dontPrint) return;
710 712
    
711 713
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
712 714
      mycoords(_coords,_negY);
713 715

	
714 716
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
715 717
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
716 718
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
717 719
//        << "%%Copyright: XXXX\n"
718 720
    os << "%%Creator: LEMON, graphToEps()\n";
719 721

	
720 722
    {    
721 723
#ifndef WIN32 
722 724
      timeval tv;
723 725
      gettimeofday(&tv, 0);
724 726

	
725 727
      char cbuf[26];
726 728
      ctime_r(&tv.tv_sec,cbuf);
727 729
      os << "%%CreationDate: " << cbuf;
728 730
#else
729 731
      SYSTEMTIME time;
730 732
      char buf1[11], buf2[9], buf3[5];
731 733
      
732 734
      GetSystemTime(&time);
733 735
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
734 736
			"ddd MMM dd", buf1, 11) &&
735 737
	  GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time, 
736 738
			"HH':'mm':'ss", buf2, 9) &&
737 739
	  GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
738 740
				"yyyy", buf3, 5)) {
739 741
	os << "%%CreationDate: " << buf1 << ' ' 
740 742
	   << buf2 << ' ' << buf3 << std::endl;
741 743
      }	  
742 744
#endif
743 745
    }
744 746

	
745 747
    if (_autoArcWidthScale) {
746 748
      double max_w=0;
747 749
      for(ArcIt e(g);e!=INVALID;++e)
748 750
	max_w=std::max(double(_arcWidths[e]),max_w);
749 751
      ///\todo better 'epsilon' would be nice here.
750 752
      if(max_w>EPSILON) {
751 753
	_arcWidthScale/=max_w;
752 754
      }
753 755
    }
754 756

	
755 757
    if (_autoNodeScale) {
756 758
      double max_s=0;
757 759
      for(NodeIt n(g);n!=INVALID;++n)
758 760
	max_s=std::max(double(_nodeSizes[n]),max_s);
759 761
      ///\todo better 'epsilon' would be nice here.
760 762
      if(max_s>EPSILON) {
761 763
	_nodeScale/=max_s;
762 764
      }
763 765
    }
764 766

	
765 767
    double diag_len = 1;
766 768
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
767 769
      dim2::BoundingBox<double> bb;
768 770
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
769 771
      if (bb.empty()) {
770 772
	bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
771 773
      }
772 774
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
773 775
      if(diag_len<EPSILON) diag_len = 1;
774 776
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
775 777
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
776 778
    }
777 779
    
778 780
    dim2::BoundingBox<double> bb;
779 781
    for(NodeIt n(g);n!=INVALID;++n) {
780 782
      double ns=_nodeSizes[n]*_nodeScale;
781 783
      dim2::Point<double> p(ns,ns);
782 784
      switch(_nodeShapes[n]) {
783 785
      case CIRCLE:
784 786
      case SQUARE:
785 787
      case DIAMOND:
786 788
	bb.add(p+mycoords[n]);
787 789
	bb.add(-p+mycoords[n]);
788 790
	break;
789 791
      case MALE:
790 792
	bb.add(-p+mycoords[n]);
791 793
	bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
792 794
	break;
793 795
      case FEMALE:
794 796
	bb.add(p+mycoords[n]);
795 797
	bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
796 798
	break;
797 799
      }
798 800
    }
799 801
    if (bb.empty()) {
800 802
      bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
801 803
    }
802 804
    
803 805
    if(_scaleToA4)
804 806
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
805 807
    else {
806 808
      if(_preScale) {
807 809
	//Rescale so that BoundingBox won't be neither to big nor too small.
808 810
	while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
809 811
	while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
810 812
      }
811 813
      
812 814
      os << "%%BoundingBox: "
813 815
	 << int(floor(bb.left()   * _scale - _xBorder)) << ' '
814 816
	 << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
815 817
	 << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
816 818
	 << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
817 819
    }
818 820
    
819 821
    os << "%%EndComments\n";
820 822
    
821 823
    //x1 y1 x2 y2 x3 y3 cr cg cb w
822 824
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
823 825
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
824 826
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
825 827
    //x y r
826 828
    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
827 829
    //x y r
828 830
    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
829 831
       << "      2 index 1 index sub 2 index 2 index add lineto\n"
830 832
       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
831 833
       << "      2 index 1 index add 2 index 2 index sub lineto\n"
832 834
       << "      closepath pop pop pop} bind def\n";
833 835
    //x y r
834 836
    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
835 837
       << "      2 index             2 index 2 index add lineto\n"
836 838
       << "      2 index 1 index sub 2 index             lineto\n"
837 839
       << "      2 index             2 index 2 index sub lineto\n"
838 840
       << "      closepath pop pop pop} bind def\n";
839 841
    // x y r cr cg cb
840 842
    os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
841 843
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
842 844
       << "   } bind def\n";
843 845
    os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
844 846
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
845 847
       << "   } bind def\n";
846 848
    os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
847 849
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
848 850
       << "   } bind def\n";
849 851
    os << "/nfemale { 0 0 0 setrgbcolor 3 index "
850 852
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
851 853
       << " 1.5 mul mul setlinewidth\n"
852 854
       << "  newpath 5 index 5 index moveto "
853 855
       << "5 index 5 index 5 index 3.01 mul sub\n"
854 856
       << "  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto\n"
855 857
       << "  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke\n"
856 858
       << "  5 index 5 index 5 index c fill\n"
857 859
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
858 860
       << "  } bind def\n";
859 861
    os << "/nmale {\n"
860 862
       << "  0 0 0 setrgbcolor 3 index "
861 863
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
862 864
       <<" 1.5 mul mul setlinewidth\n"
863 865
       << "  newpath 5 index 5 index moveto\n"
864 866
       << "  5 index 4 index 1 mul 1.5 mul add\n"
865 867
       << "  5 index 5 index 3 sqrt 1.5 mul mul add\n"
866 868
       << "  1 index 1 index lineto\n"
867 869
       << "  1 index 1 index 7 index sub moveto\n"
868 870
       << "  1 index 1 index lineto\n"
869 871
       << "  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto\n"
870 872
       << "  stroke\n"
871 873
       << "  5 index 5 index 5 index c fill\n"
872 874
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
873 875
       << "  } bind def\n";
874 876
    
875 877

	
876 878
    os << "/arrl " << _arrowLength << " def\n";
877 879
    os << "/arrw " << _arrowWidth << " def\n";
878 880
    // l dx_norm dy_norm
879 881
    os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
880 882
    //len w dx_norm dy_norm x1 y1 cr cg cb
881 883
    os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
882 884
       << "       /w exch def /len exch def\n"
883 885
      //	 << "       0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
884 886
       << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
885 887
       << "       len w sub arrl sub dx dy lrl\n"
886 888
       << "       arrw dy dx neg lrl\n"
887 889
       << "       dx arrl w add mul dy w 2 div arrw add mul sub\n"
888 890
       << "       dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
889 891
       << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
890 892
       << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
891 893
       << "       arrw dy dx neg lrl\n"
892 894
       << "       len w sub arrl sub neg dx dy lrl\n"
893 895
       << "       closepath fill } bind def\n";
894 896
    os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
895 897
       << "         neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
896 898

	
897 899
    os << "\ngsave\n";
898 900
    if(_scaleToA4)
899 901
      if(bb.height()>bb.width()) {
900 902
	double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.height(),
901 903
		  (A4WIDTH-2*A4BORDER)/bb.width());
902 904
	os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
903 905
	   << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER
904 906
	   << " translate\n"
905 907
	   << sc << " dup scale\n"
906 908
	   << -bb.left() << ' ' << -bb.bottom() << " translate\n";
907 909
      }
908 910
      else {
909 911
	//\todo Verify centering
910 912
	double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.width(),
911 913
		  (A4WIDTH-2*A4BORDER)/bb.height());
912 914
	os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
913 915
	   << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER 
914 916
	   << " translate\n"
915 917
	   << sc << " dup scale\n90 rotate\n"
916 918
	   << -bb.left() << ' ' << -bb.top() << " translate\n";	
917 919
	}
918 920
    else if(_scale!=1.0) os << _scale << " dup scale\n";
919 921
    
920 922
    if(_showArcs) {
921 923
      os << "%Arcs:\ngsave\n";      
922 924
      if(_enableParallel) {
923 925
	std::vector<Arc> el;
924 926
	for(ArcIt e(g);e!=INVALID;++e)
925 927
	  if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
926 928
	     &&g.source(e)!=g.target(e))
927 929
	    el.push_back(e);
928 930
	std::sort(el.begin(),el.end(),arcLess(g));
929 931
	
930 932
	typename std::vector<Arc>::iterator j;
931 933
	for(typename std::vector<Arc>::iterator i=el.begin();i!=el.end();i=j) {
932 934
	  for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
933 935

	
934 936
	  double sw=0;
935 937
	  for(typename std::vector<Arc>::iterator e=i;e!=j;++e)
936 938
	    sw+=_arcWidths[*e]*_arcWidthScale+_parArcDist;
937 939
	  sw-=_parArcDist;
938 940
	  sw/=-2.0;
939 941
	  dim2::Point<double>
940 942
	    dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
941 943
	  double l=std::sqrt(dvec.normSquare()); 
942 944
	  //\todo better 'epsilon' would be nice here.
943 945
	  dim2::Point<double> d(dvec/std::max(l,EPSILON));
944 946
 	  dim2::Point<double> m;
945 947
// 	  m=dim2::Point<double>(mycoords[g.target(*i)]+mycoords[g.source(*i)])/2.0;
946 948

	
947 949
//  	  m=dim2::Point<double>(mycoords[g.source(*i)])+
948 950
// 	    dvec*(double(_nodeSizes[g.source(*i)])/
949 951
// 	       (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
950 952

	
951 953
 	  m=dim2::Point<double>(mycoords[g.source(*i)])+
952 954
	    d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
953 955

	
954 956
	  for(typename std::vector<Arc>::iterator e=i;e!=j;++e) {
955 957
	    sw+=_arcWidths[*e]*_arcWidthScale/2.0;
956 958
	    dim2::Point<double> mm=m+rot90(d)*sw/.75;
957 959
	    if(_drawArrows) {
958 960
	      int node_shape;
959 961
	      dim2::Point<double> s=mycoords[g.source(*e)];
960 962
	      dim2::Point<double> t=mycoords[g.target(*e)];
961 963
	      double rn=_nodeSizes[g.target(*e)]*_nodeScale;
962 964
	      node_shape=_nodeShapes[g.target(*e)];
963 965
	      dim2::Bezier3 bez(s,mm,mm,t);
964 966
	      double t1=0,t2=1;
965 967
	      for(int ii=0;ii<INTERPOL_PREC;++ii)
966 968
		if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
967 969
		else t1=(t1+t2)/2;
968 970
	      dim2::Point<double> apoint=bez((t1+t2)/2);
969 971
	      rn = _arrowLength+_arcWidths[*e]*_arcWidthScale;
970 972
	      rn*=rn;
971 973
	      t2=(t1+t2)/2;t1=0;
972 974
	      for(int ii=0;ii<INTERPOL_PREC;++ii)
973 975
		if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
974 976
		else t2=(t1+t2)/2;
975 977
	      dim2::Point<double> linend=bez((t1+t2)/2);	      
976 978
	      bez=bez.before((t1+t2)/2);
977 979
// 	      rn=_nodeSizes[g.source(*e)]*_nodeScale;
978 980
// 	      node_shape=_nodeShapes[g.source(*e)];
979 981
// 	      t1=0;t2=1;
980 982
// 	      for(int i=0;i<INTERPOL_PREC;++i)
981 983
// 		if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2;
982 984
// 		else t2=(t1+t2)/2;
983 985
// 	      bez=bez.after((t1+t2)/2);
984 986
	      os << _arcWidths[*e]*_arcWidthScale << " setlinewidth "
985 987
		 << _arcColors[*e].red() << ' '
986 988
		 << _arcColors[*e].green() << ' '
987 989
		 << _arcColors[*e].blue() << " setrgbcolor newpath\n"
988 990
		 << bez.p1.x << ' ' <<  bez.p1.y << " moveto\n"
989 991
		 << bez.p2.x << ' ' << bez.p2.y << ' '
990 992
		 << bez.p3.x << ' ' << bez.p3.y << ' '
991 993
		 << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
992 994
	      dim2::Point<double> dd(rot90(linend-apoint));
993 995
	      dd*=(.5*_arcWidths[*e]*_arcWidthScale+_arrowWidth)/
994 996
		std::sqrt(dd.normSquare());
995 997
	      os << "newpath " << psOut(apoint) << " moveto "
996 998
		 << psOut(linend+dd) << " lineto "
997 999
		 << psOut(linend-dd) << " lineto closepath fill\n";
998 1000
	    }
999 1001
	    else {
1000 1002
	      os << mycoords[g.source(*e)].x << ' '
1001 1003
		 << mycoords[g.source(*e)].y << ' '
1002 1004
		 << mm.x << ' ' << mm.y << ' '
1003 1005
		 << mycoords[g.target(*e)].x << ' '
1004 1006
		 << mycoords[g.target(*e)].y << ' '
1005 1007
		 << _arcColors[*e].red() << ' '
1006 1008
		 << _arcColors[*e].green() << ' '
1007 1009
		 << _arcColors[*e].blue() << ' '
1008 1010
		 << _arcWidths[*e]*_arcWidthScale << " lb\n";
1009 1011
	    }
1010 1012
	    sw+=_arcWidths[*e]*_arcWidthScale/2.0+_parArcDist;
1011 1013
	  }
1012 1014
	}
1013 1015
      }
1014 1016
      else for(ArcIt e(g);e!=INVALID;++e)
1015 1017
	if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
1016 1018
	   &&g.source(e)!=g.target(e))
1017 1019
	  if(_drawArrows) {
1018 1020
	    dim2::Point<double> d(mycoords[g.target(e)]-mycoords[g.source(e)]);
1019 1021
	    double rn=_nodeSizes[g.target(e)]*_nodeScale;
1020 1022
	    int node_shape=_nodeShapes[g.target(e)];
1021 1023
	    double t1=0,t2=1;
1022 1024
	    for(int i=0;i<INTERPOL_PREC;++i)
1023 1025
	      if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
1024 1026
	      else t2=(t1+t2)/2;
1025 1027
	    double l=std::sqrt(d.normSquare());
1026 1028
	    d/=l;
1027 1029
	    
1028 1030
	    os << l*(1-(t1+t2)/2) << ' '
1029 1031
	       << _arcWidths[e]*_arcWidthScale << ' '
1030 1032
	       << d.x << ' ' << d.y << ' '
1031 1033
	       << mycoords[g.source(e)].x << ' '
1032 1034
	       << mycoords[g.source(e)].y << ' '
1033 1035
	       << _arcColors[e].red() << ' '
1034 1036
	       << _arcColors[e].green() << ' '
1035 1037
	       << _arcColors[e].blue() << " arr\n";
1036 1038
	  }
1037 1039
	  else os << mycoords[g.source(e)].x << ' '
1038 1040
		  << mycoords[g.source(e)].y << ' '
1039 1041
		  << mycoords[g.target(e)].x << ' '
1040 1042
		  << mycoords[g.target(e)].y << ' '
1041 1043
		  << _arcColors[e].red() << ' '
1042 1044
		  << _arcColors[e].green() << ' '
1043 1045
		  << _arcColors[e].blue() << ' '
1044 1046
		  << _arcWidths[e]*_arcWidthScale << " l\n";
1045 1047
      os << "grestore\n";
1046 1048
    }
1047 1049
    if(_showNodes) {
1048 1050
      os << "%Nodes:\ngsave\n";
1049 1051
      for(NodeIt n(g);n!=INVALID;++n) {
1050 1052
	os << mycoords[n].x << ' ' << mycoords[n].y << ' '
1051 1053
	   << _nodeSizes[n]*_nodeScale << ' '
1052 1054
	   << _nodeColors[n].red() << ' '
1053 1055
	   << _nodeColors[n].green() << ' '
1054 1056
	   << _nodeColors[n].blue() << ' ';
1055 1057
	switch(_nodeShapes[n]) {
1056 1058
	case CIRCLE:
1057 1059
	  os<< "nc";break;
1058 1060
	case SQUARE:
1059 1061
	  os<< "nsq";break;
1060 1062
	case DIAMOND:
1061 1063
	  os<< "ndi";break;
1062 1064
	case MALE:
1063 1065
	  os<< "nmale";break;
1064 1066
	case FEMALE:
1065 1067
	  os<< "nfemale";break;
1066 1068
	}
1067 1069
	os<<'\n';
1068 1070
      }
1069 1071
      os << "grestore\n";
1070 1072
    }
1071 1073
    if(_showNodeText) {
1072 1074
      os << "%Node texts:\ngsave\n";
1073 1075
      os << "/fosi " << _nodeTextSize << " def\n";
1074 1076
      os << "(Helvetica) findfont fosi scalefont setfont\n";
1075 1077
      for(NodeIt n(g);n!=INVALID;++n) {
1076 1078
	switch(_nodeTextColorType) {
1077 1079
	case DIST_COL:
1078 1080
	  os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
1079 1081
	  break;
1080 1082
	case DIST_BW:
1081 1083
	  os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
1082 1084
	  break;
1083 1085
	case CUST_COL:
1084 1086
	  os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
1085 1087
	  break;
1086 1088
	default:
1087 1089
	  os << "0 0 0 setrgbcolor\n";
1088 1090
	}
1089 1091
	os << mycoords[n].x << ' ' << mycoords[n].y
1090 1092
	   << " (" << _nodeTexts[n] << ") cshow\n";
1091 1093
      }
1092 1094
      os << "grestore\n";
1093 1095
    }
1094 1096
    if(_showNodePsText) {
1095 1097
      os << "%Node PS blocks:\ngsave\n";
1096 1098
      for(NodeIt n(g);n!=INVALID;++n)
1097 1099
	os << mycoords[n].x << ' ' << mycoords[n].y
1098 1100
	   << " moveto\n" << _nodePsTexts[n] << "\n";
1099 1101
      os << "grestore\n";
1100 1102
    }
1101 1103
    
1102 1104
    os << "grestore\nshowpage\n";
1103 1105

	
1104 1106
    //CleanUp:
1105 1107
    if(_pleaseRemoveOsStream) {delete &os;}
1106 1108
  }
1107 1109

	
1108 1110
  ///\name Aliases
1109 1111
  ///These are just some aliases to other parameter setting functions.
1110 1112

	
1111 1113
  ///@{
1112 1114

	
1113 1115
  ///An alias for arcWidths()
1114 1116

	
1115 1117
  ///An alias for arcWidths()
1116 1118
  ///
1117 1119
  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
1118 1120
  {
1119 1121
    return arcWidths(x);
1120 1122
  }
1121 1123

	
1122 1124
  ///An alias for arcColors()
1123 1125

	
1124 1126
  ///An alias for arcColors()
1125 1127
  ///
1126 1128
  template<class X> GraphToEps<ArcColorsTraits<X> >
1127 1129
  edgeColors(const X &x)
1128 1130
  {
1129 1131
    return arcColors(x);
1130 1132
  }
1131 1133

	
1132 1134
  ///An alias for arcWidthScale()
1133 1135

	
1134 1136
  ///An alias for arcWidthScale()
1135 1137
  ///
1136 1138
  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
1137 1139

	
1138 1140
  ///An alias for autoArcWidthScale()
1139 1141

	
1140 1142
  ///An alias for autoArcWidthScale()
1141 1143
  ///
1142 1144
  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
1143 1145
  {
1144 1146
    return autoArcWidthScale(b);
1145 1147
  }
1146 1148
  
1147 1149
  ///An alias for absoluteArcWidths()
1148 1150

	
1149 1151
  ///An alias for absoluteArcWidths()
1150 1152
  ///
1151 1153
  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
1152 1154
  {
1153 1155
    return absoluteArcWidths(b);
1154 1156
  }
1155 1157
  
1156 1158
  ///An alias for parArcDist()
1157 1159

	
1158 1160
  ///An alias for parArcDist()
1159 1161
  ///
1160 1162
  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
1161 1163
  
1162 1164
  ///An alias for hideArcs()
1163 1165
  
1164 1166
  ///An alias for hideArcs()
1165 1167
  ///
1166 1168
  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
1167 1169

	
1168 1170
  ///@}
1169 1171
};
1170 1172

	
1171 1173
template<class T>
1172 1174
const int GraphToEps<T>::INTERPOL_PREC = 20;
1173 1175
template<class T>
1174 1176
const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
1175 1177
template<class T>
1176 1178
const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
1177 1179
template<class T>
1178 1180
const double GraphToEps<T>::A4BORDER = 15;
1179 1181

	
1180 1182

	
1181 1183
///Generates an EPS file from a graph
1182 1184

	
1183 1185
///\ingroup eps_io
1184 1186
///Generates an EPS file from a graph.
1185 1187
///\param g is a reference to the graph to be printed
1186 1188
///\param os is a reference to the output stream.
1187 1189
///By default it is <tt>std::cout</tt>
1188 1190
///
1189 1191
///This function also has a lot of
1190 1192
///\ref named-templ-func-param "named parameters",
1191 1193
///they are declared as the members of class \ref GraphToEps. The following
1192 1194
///example shows how to use these parameters.
1193 1195
///\code
1194 1196
/// graphToEps(g,os).scale(10).coords(coords)
1195 1197
///              .nodeScale(2).nodeSizes(sizes)
1196 1198
///              .arcWidthScale(.4).run();
1197 1199
///\endcode
1198 1200
///\warning Don't forget to put the \ref GraphToEps::run() "run()"
1199 1201
///to the end of the parameter list.
1200 1202
///\sa GraphToEps
1201 1203
///\sa graphToEps(G &g, const char *file_name)
1202 1204
template<class G>
1203 1205
GraphToEps<DefaultGraphToEpsTraits<G> > 
1204 1206
graphToEps(G &g, std::ostream& os=std::cout)
1205 1207
{
1206 1208
  return 
1207 1209
    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
1208 1210
}
1209 1211
 
1210 1212
///Generates an EPS file from a graph
1211 1213

	
1212 1214
///\ingroup eps_io
1213 1215
///This function does the same as
1214 1216
///\ref graphToEps(G &g,std::ostream& os)
1215 1217
///but it writes its output into the file \c file_name
1216 1218
///instead of a stream.
1217 1219
///\sa graphToEps(G &g, std::ostream& os)
1218 1220
template<class G>
1219 1221
GraphToEps<DefaultGraphToEpsTraits<G> > 
1220 1222
graphToEps(G &g,const char *file_name)
1221 1223
{
1222 1224
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1223 1225
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
1224 1226
}
1225 1227

	
1226 1228
///Generates an EPS file from a graph
1227 1229

	
1228 1230
///\ingroup eps_io
1229 1231
///This function does the same as
1230 1232
///\ref graphToEps(G &g,std::ostream& os)
1231 1233
///but it writes its output into the file \c file_name
1232 1234
///instead of a stream.
1233 1235
///\sa graphToEps(G &g, std::ostream& os)
1234 1236
template<class G>
1235 1237
GraphToEps<DefaultGraphToEpsTraits<G> > 
1236 1238
graphToEps(G &g,const std::string& file_name)
1237 1239
{
1238 1240
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1239 1241
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name.c_str()),true));
1240 1242
}
1241 1243

	
1242 1244
} //END OF NAMESPACE LEMON
1243 1245

	
1244 1246
#endif // LEMON_GRAPH_TO_EPS_H
Ignore white space 1099511627776 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 paths
20 20
///\file
21 21
///\brief Classes for representing paths in digraphs.
22 22
///
23 23

	
24 24
#ifndef LEMON_PATH_H
25 25
#define LEMON_PATH_H
26 26

	
27 27
#include <vector>
28 28
#include <algorithm>
29 29

	
30 30
#include <lemon/error.h>
31 31
#include <lemon/bits/invalid.h>
32 32
#include <lemon/concepts/path.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \addtogroup paths
37 37
  /// @{
38 38

	
39 39

	
40 40
  /// \brief A structure for representing directed paths in a digraph.
41 41
  ///
42 42
  /// A structure for representing directed path in a digraph.
43 43
  /// \param Digraph The digraph type in which the path is.
44 44
  ///
45 45
  /// In a sense, the path can be treated as a list of arcs. The
46 46
  /// lemon path type stores just this list. As a consequence, it
47 47
  /// cannot enumerate the nodes of the path and the source node of
48 48
  /// a zero length path is undefined.
49 49
  ///
50 50
  /// This implementation is a back and front insertable and erasable
51 51
  /// path type. It can be indexed in O(1) time. The front and back
52 52
  /// insertion and erase is done in O(1) (amortized) time. The
53 53
  /// implementation uses two vectors for storing the front and back
54 54
  /// insertions.
55 55
  template <typename _Digraph>
56 56
  class Path {
57 57
  public:
58 58

	
59 59
    typedef _Digraph Digraph;
60 60
    typedef typename Digraph::Arc Arc;
61 61

	
62 62
    /// \brief Default constructor
63 63
    ///
64 64
    /// Default constructor
65 65
    Path() {}
66 66

	
67 67
    /// \brief Template copy constructor
68 68
    ///
69 69
    /// This constuctor initializes the path from any other path type.
70 70
    /// It simply makes a copy of the given path.
71 71
    template <typename CPath>
72 72
    Path(const CPath& cpath) {
73 73
      copyPath(*this, cpath);
74 74
    }
75 75

	
76 76
    /// \brief Template copy assignment
77 77
    ///
78 78
    /// This operator makes a copy of a path of any other type.
79 79
    template <typename CPath>
80 80
    Path& operator=(const CPath& cpath) {
81 81
      copyPath(*this, cpath);
82 82
      return *this;
83 83
    }
84 84

	
85 85
    /// \brief Lemon style iterator for path arcs
86 86
    ///
87 87
    /// This class is used to iterate on the arcs of the paths.
88 88
    class ArcIt {
89 89
      friend class Path;
90 90
    public:
91 91
      /// \brief Default constructor
92 92
      ArcIt() {}
93 93
      /// \brief Invalid constructor
94 94
      ArcIt(Invalid) : path(0), idx(-1) {}
95 95
      /// \brief Initializate the iterator to the first arc of path
96 96
      ArcIt(const Path &_path) 
97 97
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
98 98

	
99 99
    private:
100 100

	
101 101
      ArcIt(const Path &_path, int _idx) 
102 102
        : path(&_path), idx(_idx) {}
103 103

	
104 104
    public:
105 105

	
106 106
      /// \brief Conversion to Arc
107 107
      operator const Arc&() const {
108 108
        return path->nth(idx);
109 109
      }
110 110

	
111 111
      /// \brief Next arc
112 112
      ArcIt& operator++() { 
113 113
        ++idx;
114 114
        if (idx >= path->length()) idx = -1; 
115 115
        return *this; 
116 116
      }
117 117

	
118 118
      /// \brief Comparison operator
119 119
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
120 120
      /// \brief Comparison operator
121 121
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
122 122
      /// \brief Comparison operator
123 123
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
124 124

	
125 125
    private:
126 126
      const Path *path;
127 127
      int idx;
128 128
    };
129 129

	
130 130
    /// \brief Length of the path.
131 131
    int length() const { return head.size() + tail.size(); }
132 132
    /// \brief Return whether the path is empty.
133 133
    bool empty() const { return head.empty() && tail.empty(); }
134 134

	
135 135
    /// \brief Reset the path to an empty one.
136 136
    void clear() { head.clear(); tail.clear(); }
137 137

	
138 138
    /// \brief The nth arc.
139 139
    ///
140 140
    /// \pre n is in the [0..length() - 1] range
141 141
    const Arc& nth(int n) const {
142 142
      return n < int(head.size()) ? *(head.rbegin() + n) :
143 143
        *(tail.begin() + (n - head.size()));
144 144
    }
145 145

	
146 146
    /// \brief Initialize arc iterator to point to the nth arc
147 147
    ///
148 148
    /// \pre n is in the [0..length() - 1] range
149 149
    ArcIt nthIt(int n) const {
150 150
      return ArcIt(*this, n);
151 151
    }
152 152

	
153 153
    /// \brief The first arc of the path
154 154
    const Arc& front() const {
155 155
      return head.empty() ? tail.front() : head.back();
156 156
    }
157 157

	
158 158
    /// \brief Add a new arc before the current path
159 159
    void addFront(const Arc& arc) {
160 160
      head.push_back(arc);
161 161
    }
162 162

	
163 163
    /// \brief Erase the first arc of the path
164 164
    void eraseFront() {
165 165
      if (!head.empty()) {
166 166
        head.pop_back();
167 167
      } else {
168 168
        head.clear();
169 169
        int halfsize = tail.size() / 2;
170 170
        head.resize(halfsize);
171 171
        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
172 172
                  head.rbegin());
173 173
        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
174 174
        tail.resize(tail.size() - halfsize - 1);
175 175
      }
176 176
    }
177 177

	
178 178
    /// \brief The last arc of the path
179 179
    const Arc& back() const {
180 180
      return tail.empty() ? head.front() : tail.back();
181 181
    }
182 182

	
183 183
    /// \brief Add a new arc behind the current path
184 184
    void addBack(const Arc& arc) {
185 185
      tail.push_back(arc);
186 186
    }
187 187

	
188 188
    /// \brief Erase the last arc of the path
189 189
    void eraseBack() {
190 190
      if (!tail.empty()) {
191 191
        tail.pop_back();
192 192
      } else {
193 193
        int halfsize = head.size() / 2;
194 194
        tail.resize(halfsize);
195 195
        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
196 196
                  tail.rbegin());
197 197
        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
198 198
        head.resize(head.size() - halfsize - 1);
199 199
      }
200 200
    }
201 201

	
202 202
    typedef True BuildTag;
203 203

	
204 204
    template <typename CPath>
205 205
    void build(const CPath& path) {
206 206
      int len = path.length();
207 207
      tail.reserve(len);
208 208
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
209 209
        tail.push_back(it);
210 210
      }
211 211
    }
212 212

	
213 213
    template <typename CPath>
214 214
    void buildRev(const CPath& path) {
215 215
      int len = path.length();
216 216
      head.reserve(len);
217 217
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
218 218
        head.push_back(it);
219 219
      }
220 220
    }
221 221

	
222 222
  protected:
223 223
    typedef std::vector<Arc> Container;
224 224
    Container head, tail;
225 225

	
226 226
  };
227 227

	
228 228
  /// \brief A structure for representing directed paths in a digraph.
229 229
  ///
230 230
  /// A structure for representing directed path in a digraph.
231 231
  /// \param Digraph The digraph type in which the path is.
232 232
  ///
233 233
  /// In a sense, the path can be treated as a list of arcs. The
234 234
  /// lemon path type stores just this list. As a consequence it
235 235
  /// cannot enumerate the nodes in the path and the zero length paths
236 236
  /// cannot store the source.
237 237
  ///
238 238
  /// This implementation is a just back insertable and erasable path
239 239
  /// type. It can be indexed in O(1) time. The back insertion and
240 240
  /// erasure is amortized O(1) time. This implementation is faster
241 241
  /// then the \c Path type because it use just one vector for the
242 242
  /// arcs.
243 243
  template <typename _Digraph>
244 244
  class SimplePath {
245 245
  public:
246 246

	
247 247
    typedef _Digraph Digraph;
248 248
    typedef typename Digraph::Arc Arc;
249 249

	
250 250
    /// \brief Default constructor
251 251
    ///
252 252
    /// Default constructor
253 253
    SimplePath() {}
254 254

	
255 255
    /// \brief Template copy constructor
256 256
    ///
257 257
    /// This path can be initialized with any other path type. It just
258 258
    /// makes a copy of the given path.
259 259
    template <typename CPath>
260 260
    SimplePath(const CPath& cpath) {
261 261
      copyPath(*this, cpath);
262 262
    }
263 263

	
264 264
    /// \brief Template copy assignment
265 265
    ///
266 266
    /// This path can be initialized with any other path type. It just
267 267
    /// makes a copy of the given path.
268 268
    template <typename CPath>
269 269
    SimplePath& operator=(const CPath& cpath) {
270 270
      copyPath(*this, cpath);
271 271
      return *this;
272 272
    }
273 273

	
274 274
    /// \brief Iterator class to iterate on the arcs of the paths
275 275
    ///
276 276
    /// This class is used to iterate on the arcs of the paths
277 277
    ///
278 278
    /// Of course it converts to Digraph::Arc
279 279
    class ArcIt {
280 280
      friend class SimplePath;
281 281
    public:
282 282
      /// Default constructor
283 283
      ArcIt() {}
284 284
      /// Invalid constructor
285 285
      ArcIt(Invalid) : path(0), idx(-1) {}
286 286
      /// \brief Initializate the constructor to the first arc of path
287 287
      ArcIt(const SimplePath &_path) 
288 288
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
289 289

	
290 290
    private:
291 291

	
292 292
      /// Constructor with starting point
293 293
      ArcIt(const SimplePath &_path, int _idx) 
294 294
        : idx(_idx), path(&_path) {}
295 295

	
296 296
    public:
297 297

	
298 298
      ///Conversion to Digraph::Arc
299 299
      operator const Arc&() const {
300 300
        return path->nth(idx);
301 301
      }
302 302

	
303 303
      /// Next arc
304 304
      ArcIt& operator++() { 
305 305
        ++idx;
306 306
        if (idx >= path->length()) idx = -1; 
307 307
        return *this; 
308 308
      }
309 309

	
310 310
      /// Comparison operator
311 311
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
312 312
      /// Comparison operator
313 313
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
314 314
      /// Comparison operator
315 315
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
316 316

	
317 317
    private:
318 318
      const SimplePath *path;
319 319
      int idx;
320 320
    };
321 321

	
322 322
    /// \brief Length of the path.
323 323
    int length() const { return data.size(); }
324 324
    /// \brief Return true if the path is empty.
325 325
    bool empty() const { return data.empty(); }
326 326

	
327 327
    /// \brief Reset the path to an empty one.
328 328
    void clear() { data.clear(); }
329 329

	
330 330
    /// \brief The nth arc.
331 331
    ///
332 332
    /// \pre n is in the [0..length() - 1] range
333 333
    const Arc& nth(int n) const {
334 334
      return data[n];
335 335
    }
336 336

	
337 337
    /// \brief  Initializes arc iterator to point to the nth arc.
338 338
    ArcIt nthIt(int n) const {
339 339
      return ArcIt(*this, n);
340 340
    }
341 341

	
342 342
    /// \brief The first arc of the path.
343 343
    const Arc& front() const {
344 344
      return data.front();
345 345
    }
346 346

	
347 347
    /// \brief The last arc of the path.
348 348
    const Arc& back() const {
349 349
      return data.back();
350 350
    }
351 351

	
352 352
    /// \brief Add a new arc behind the current path.
353 353
    void addBack(const Arc& arc) {
354 354
      data.push_back(arc);
355 355
    }
356 356

	
357 357
    /// \brief Erase the last arc of the path
358 358
    void eraseBack() {
359 359
      data.pop_back();
360 360
    }
361 361

	
362 362
    typedef True BuildTag;
363 363

	
364 364
    template <typename CPath>
365 365
    void build(const CPath& path) {
366 366
      int len = path.length();
367 367
      data.resize(len);
368 368
      int index = 0;
369 369
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
370 370
        data[index] = it;;
371 371
        ++index;
372 372
      }
373 373
    }
374 374

	
375 375
    template <typename CPath>
376 376
    void buildRev(const CPath& path) {
377 377
      int len = path.length();
378 378
      data.resize(len);
379 379
      int index = len;
380 380
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
381 381
        --index;
382 382
        data[index] = it;;
383 383
      }
384 384
    }
385 385

	
386 386
  protected:
387 387
    typedef std::vector<Arc> Container;
388 388
    Container data;
389 389

	
390 390
  };
391 391

	
392 392
  /// \brief A structure for representing directed paths in a digraph.
393 393
  ///
394 394
  /// A structure for representing directed path in a digraph.
395 395
  /// \param Digraph The digraph type in which the path is.
396 396
  ///
397 397
  /// In a sense, the path can be treated as a list of arcs. The
398 398
  /// lemon path type stores just this list. As a consequence it
399 399
  /// cannot enumerate the nodes in the path and the zero length paths
400 400
  /// cannot store the source.
401 401
  ///
402 402
  /// This implementation is a back and front insertable and erasable
403 403
  /// path type. It can be indexed in O(k) time, where k is the rank
404 404
  /// of the arc in the path. The length can be computed in O(n)
405 405
  /// time. The front and back insertion and erasure is O(1) time
406 406
  /// and it can be splited and spliced in O(1) time.
407 407
  template <typename _Digraph>
408 408
  class ListPath {
409 409
  public:
410 410

	
411 411
    typedef _Digraph Digraph;
412 412
    typedef typename Digraph::Arc Arc;
413 413

	
414 414
  protected:
415 415

	
416 416
    // the std::list<> is incompatible 
417 417
    // hard to create invalid iterator
418 418
    struct Node {
419 419
      Arc arc;
420 420
      Node *next, *prev;
421 421
    };
422 422

	
423 423
    Node *first, *last;
424 424

	
425 425
    std::allocator<Node> alloc;
426 426

	
427 427
  public:
428 428
 
429 429
    /// \brief Default constructor
430 430
    ///
431 431
    /// Default constructor
432 432
    ListPath() : first(0), last(0) {}
433 433

	
434 434
    /// \brief Template copy constructor
435 435
    ///
436 436
    /// This path can be initialized with any other path type. It just
437 437
    /// makes a copy of the given path.
438 438
    template <typename CPath>
439 439
    ListPath(const CPath& cpath) : first(0), last(0) {
440 440
      copyPath(*this, cpath);
441 441
    }
442 442

	
443 443
    /// \brief Destructor of the path
444 444
    ///
445 445
    /// Destructor of the path
446 446
    ~ListPath() {
447 447
      clear();
448 448
    }
449 449

	
450 450
    /// \brief Template copy assignment
451 451
    ///
452 452
    /// This path can be initialized with any other path type. It just
453 453
    /// makes a copy of the given path.
454 454
    template <typename CPath>
455 455
    ListPath& operator=(const CPath& cpath) {
456 456
      copyPath(*this, cpath);
457 457
      return *this;
458 458
    }
459 459

	
460 460
    /// \brief Iterator class to iterate on the arcs of the paths
461 461
    ///
462 462
    /// This class is used to iterate on the arcs of the paths
463 463
    ///
464 464
    /// Of course it converts to Digraph::Arc
465 465
    class ArcIt {
466 466
      friend class ListPath;
467 467
    public:
468 468
      /// Default constructor
469 469
      ArcIt() {}
470 470
      /// Invalid constructor
471 471
      ArcIt(Invalid) : path(0), node(0) {}
472 472
      /// \brief Initializate the constructor to the first arc of path
473 473
      ArcIt(const ListPath &_path) 
474 474
        : path(&_path), node(_path.first) {}
475 475

	
476 476
    protected:
477 477

	
478 478
      ArcIt(const ListPath &_path, Node *_node) 
479 479
        : path(&_path), node(_node) {}
480 480

	
481 481

	
482 482
    public:
483 483

	
484 484
      ///Conversion to Digraph::Arc
485 485
      operator const Arc&() const {
486 486
        return node->arc;
487 487
      }
488 488

	
489 489
      /// Next arc
490 490
      ArcIt& operator++() { 
491 491
        node = node->next;
492 492
        return *this; 
493 493
      }
494 494

	
495 495
      /// Comparison operator
496 496
      bool operator==(const ArcIt& e) const { return node==e.node; }
497 497
      /// Comparison operator
498 498
      bool operator!=(const ArcIt& e) const { return node!=e.node; }
499 499
      /// Comparison operator
500 500
      bool operator<(const ArcIt& e) const { return node<e.node; }
501 501

	
502 502
    private:
503 503
      const ListPath *path;
504 504
      Node *node;
505 505
    };
506 506

	
507 507
    /// \brief The nth arc.
508 508
    ///
509 509
    /// This function looks for the nth arc in O(n) time.
510 510
    /// \pre n is in the [0..length() - 1] range
511 511
    const Arc& nth(int n) const {
512 512
      Node *node = first;
513 513
      for (int i = 0; i < n; ++i) {
514 514
        node = node->next;
515 515
      }
516 516
      return node->arc;
517 517
    }
518 518

	
519 519
    /// \brief Initializes arc iterator to point to the nth arc.
520 520
    ArcIt nthIt(int n) const {
521 521
      Node *node = first;
522 522
      for (int i = 0; i < n; ++i) {
523 523
        node = node->next;
524 524
      }
525 525
      return ArcIt(*this, node);
526 526
    }
527 527

	
528 528
    /// \brief Length of the path.
529 529
    int length() const {
530 530
      int len = 0;
531 531
      Node *node = first;
532 532
      while (node != 0) {
533 533
        node = node->next;
534 534
        ++len;
535 535
      }
536 536
      return len;
537 537
    }
538 538

	
539 539
    /// \brief Return true if the path is empty.
540 540
    bool empty() const { return first == 0; }
541 541

	
542 542
    /// \brief Reset the path to an empty one.
543 543
    void clear() {
544 544
      while (first != 0) {
545 545
        last = first->next;
546 546
        alloc.destroy(first);
547 547
        alloc.deallocate(first, 1);
548 548
        first = last;
549 549
      }
550 550
    }
551 551

	
552 552
    /// \brief The first arc of the path
553 553
    const Arc& front() const {
554 554
      return first->arc;
555 555
    }
556 556

	
557 557
    /// \brief Add a new arc before the current path
558 558
    void addFront(const Arc& arc) {
559 559
      Node *node = alloc.allocate(1);
560 560
      alloc.construct(node, Node());
561 561
      node->prev = 0;
562 562
      node->next = first;
563 563
      node->arc = arc;
564 564
      if (first) {
565 565
        first->prev = node;
566 566
        first = node;
567 567
      } else {
568 568
        first = last = node;
569 569
      }
570 570
    }
571 571

	
572 572
    /// \brief Erase the first arc of the path
573 573
    void eraseFront() {
574 574
      Node *node = first;
575 575
      first = first->next;
576 576
      if (first) {
577 577
        first->prev = 0;
578 578
      } else {
579 579
        last = 0;
580 580
      }
581 581
      alloc.destroy(node);
582 582
      alloc.deallocate(node, 1);
583 583
    }
584 584

	
585 585
    /// \brief The last arc of the path.
586 586
    const Arc& back() const {
587 587
      return last->arc;
588 588
    }
589 589

	
590 590
    /// \brief Add a new arc behind the current path.
591 591
    void addBack(const Arc& arc) {
592 592
      Node *node = alloc.allocate(1);
593 593
      alloc.construct(node, Node());
594 594
      node->next = 0;
595 595
      node->prev = last;
596 596
      node->arc = arc;
597 597
      if (last) {
598 598
        last->next = node;
599 599
        last = node;
600 600
      } else {
601 601
        last = first = node;
602 602
      }
603 603
    }
604 604

	
605 605
    /// \brief Erase the last arc of the path
606 606
    void eraseBack() {
607 607
      Node *node = last;
608 608
      last = last->prev;
609 609
      if (last) {
610 610
        last->next = 0;
611 611
      } else {
612 612
        first = 0;
613 613
      }
614 614
      alloc.destroy(node);
615 615
      alloc.deallocate(node, 1);
616 616
    }
617 617

	
618 618
    /// \brief Splice a path to the back of the current path.
619 619
    ///
620 620
    /// It splices \c tpath to the back of the current path and \c
621 621
    /// tpath becomes empty. The time complexity of this function is
622 622
    /// O(1).
623 623
    void spliceBack(ListPath& tpath) {
624 624
      if (first) {
625 625
        if (tpath.first) {
626 626
          last->next = tpath.first;
627 627
          tpath.first->prev = last;
628 628
          last = tpath.last;
629 629
        }
630 630
      } else {
631 631
        first = tpath.first;
632 632
        last = tpath.last;
633 633
      }
634 634
      tpath.first = tpath.last = 0;
635 635
    }
636 636

	
637 637
    /// \brief Splice a path to the front of the current path.
638 638
    ///
639 639
    /// It splices \c tpath before the current path and \c tpath
640 640
    /// becomes empty. The time complexity of this function
641 641
    /// is O(1).
642 642
    void spliceFront(ListPath& tpath) {
643 643
      if (first) {
644 644
        if (tpath.first) {
645 645
          first->prev = tpath.last;
646 646
          tpath.last->next = first;
647 647
          first = tpath.first;
648 648
        }
649 649
      } else {
650 650
        first = tpath.first;
651 651
        last = tpath.last;
652 652
      }
653 653
      tpath.first = tpath.last = 0;
654 654
    }
655 655

	
656 656
    /// \brief Splice a path into the current path.
657 657
    ///
658 658
    /// It splices the \c tpath into the current path before the
659 659
    /// position of \c it iterator and \c tpath becomes empty. The
660 660
    /// time complexity of this function is O(1). If the \c it is
661 661
    /// \c INVALID then it will splice behind the current path.
662 662
    void splice(ArcIt it, ListPath& tpath) {
663 663
      if (it.node) {
664 664
        if (tpath.first) {
665 665
          tpath.first->prev = it.node->prev;
666 666
          if (it.node->prev) {
667 667
            it.node->prev->next = tpath.first;
668 668
          } else {
669 669
            first = tpath.first;
670 670
          }
671 671
          it.node->prev = tpath.last;
672 672
          tpath.last->next = it.node;
673 673
        }
674 674
      } else {
675 675
        if (first) {
676 676
          if (tpath.first) {
677 677
            last->next = tpath.first;
678 678
            tpath.first->prev = last;
679 679
            last = tpath.last;
680 680
          }
681 681
        } else {
682 682
          first = tpath.first;
683 683
          last = tpath.last;
684 684
        }
685 685
      }
686 686
      tpath.first = tpath.last = 0;
687 687
    }
688 688

	
689 689
    /// \brief Split the current path.
690 690
    ///
691 691
    /// It splits the current path into two parts. The part before
692 692
    /// the iterator \c it will remain in the current path and the part
693 693
    /// starting with
694 694
    /// \c it will put into \c tpath. If \c tpath have arcs
695 695
    /// before the operation they are removed first.  The time
696 696
    /// complexity of this function is O(1) plus the the time of emtying
697 697
    /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
698 698
    void split(ArcIt it, ListPath& tpath) {
699 699
      tpath.clear();
700 700
      if (it.node) {
701 701
        tpath.first = it.node;
702 702
        tpath.last = last;
703 703
        if (it.node->prev) {
704 704
          last = it.node->prev;
705 705
          last->next = 0;
706 706
        } else {
707 707
          first = last = 0;
708 708
        }
709 709
        it.node->prev = 0;
710 710
      }
711 711
    }
712 712

	
713 713

	
714 714
    typedef True BuildTag;
715 715

	
716 716
    template <typename CPath>
717 717
    void build(const CPath& path) {
718 718
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
719 719
        addBack(it);
720 720
      }
721 721
    }
722 722

	
723 723
    template <typename CPath>
724 724
    void buildRev(const CPath& path) {
725 725
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
726 726
        addFront(it);
727 727
      }
728 728
    }
729 729

	
730 730
  };
731 731

	
732 732
  /// \brief A structure for representing directed paths in a digraph.
733 733
  ///
734 734
  /// A structure for representing directed path in a digraph.
735 735
  /// \param Digraph The digraph type in which the path is.
736 736
  ///
737 737
  /// In a sense, the path can be treated as a list of arcs. The
738 738
  /// lemon path type stores just this list. As a consequence it
739 739
  /// cannot enumerate the nodes in the path and the source node of
740 740
  /// a zero length path is undefined.
741 741
  ///
742 742
  /// This implementation is completly static, i.e. it can be copy constucted
743 743
  /// or copy assigned from another path, but otherwise it cannot be
744 744
  /// modified.
745 745
  ///
746 746
  /// Being the the most memory efficient path type in LEMON,
747 747
  /// it is intented to be
748 748
  /// used when you want to store a large number of paths.
749 749
  template <typename _Digraph>
750 750
  class StaticPath {
751 751
  public:
752 752

	
753 753
    typedef _Digraph Digraph;
754 754
    typedef typename Digraph::Arc Arc;
755 755

	
756 756
    /// \brief Default constructor
757 757
    ///
758 758
    /// Default constructor
759 759
    StaticPath() : len(0), arcs(0) {}
760 760
    
761 761
    /// \brief Template copy constructor
762 762
    ///
763 763
    /// This path can be initialized from any other path type.
764 764
    template <typename CPath>
765 765
    StaticPath(const CPath& cpath) : arcs(0) {
766 766
      copyPath(*this, cpath);
767 767
    }
768 768

	
769 769
    /// \brief Destructor of the path
770 770
    ///
771 771
    /// Destructor of the path
772 772
    ~StaticPath() {
773 773
      if (arcs) delete[] arcs;
774 774
    }
775 775

	
776 776
    /// \brief Template copy assignment
777 777
    ///
778 778
    /// This path can be made equal to any other path type. It simply
779 779
    /// makes a copy of the given path.
780 780
    template <typename CPath>
781 781
    StaticPath& operator=(const CPath& cpath) {
782 782
      copyPath(*this, cpath);
783 783
      return *this;
784 784
    }
785 785

	
786 786
    /// \brief Iterator class to iterate on the arcs of the paths
787 787
    ///
788 788
    /// This class is used to iterate on the arcs of the paths
789 789
    ///
790 790
    /// Of course it converts to Digraph::Arc
791 791
    class ArcIt {
792 792
      friend class StaticPath;
793 793
    public:
794 794
      /// Default constructor
795 795
      ArcIt() {}
796 796
      /// Invalid constructor
797 797
      ArcIt(Invalid) : path(0), idx(-1) {}
798 798
      /// Initializate the constructor to the first arc of path
799 799
      ArcIt(const StaticPath &_path) 
800 800
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
801 801

	
802 802
    private:
803 803

	
804 804
      /// Constructor with starting point
805 805
      ArcIt(const StaticPath &_path, int _idx) 
806 806
        : idx(_idx), path(&_path) {}
807 807

	
808 808
    public:
809 809

	
810 810
      ///Conversion to Digraph::Arc
811 811
      operator const Arc&() const {
812 812
        return path->nth(idx);
813 813
      }
814 814

	
815 815
      /// Next arc
816 816
      ArcIt& operator++() { 
817 817
        ++idx;
818 818
        if (idx >= path->length()) idx = -1; 
819 819
        return *this; 
820 820
      }
821 821

	
822 822
      /// Comparison operator
823 823
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
824 824
      /// Comparison operator
825 825
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
826 826
      /// Comparison operator
827 827
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
828 828

	
829 829
    private:
830 830
      const StaticPath *path;
831 831
      int idx;
832 832
    };
833 833

	
834 834
    /// \brief The nth arc.
835 835
    ///
836 836
    /// \pre n is in the [0..length() - 1] range
837 837
    const Arc& nth(int n) const {
838 838
      return arcs[n];
839 839
    }
840 840

	
841 841
    /// \brief The arc iterator pointing to the nth arc.
842 842
    ArcIt nthIt(int n) const {
843 843
      return ArcIt(*this, n);
844 844
    }
845 845

	
846 846
    /// \brief The length of the path.
847 847
    int length() const { return len; }
848 848

	
849 849
    /// \brief Return true when the path is empty.
850 850
    int empty() const { return len == 0; }
851 851

	
852 852
    /// \break Erase all arcs in the digraph.
853 853
    void clear() {
854 854
      len = 0;
855 855
      if (arcs) delete[] arcs;
856 856
      arcs = 0;
857 857
    }
858 858

	
859 859
    /// \brief The first arc of the path.
860 860
    const Arc& front() const {
861 861
      return arcs[0];
862 862
    }
863 863

	
864 864
    /// \brief The last arc of the path.
865 865
    const Arc& back() const {
866 866
      return arcs[len - 1];
867 867
    }
868 868

	
869 869

	
870 870
    typedef True BuildTag;
871 871

	
872 872
    template <typename CPath>
873 873
    void build(const CPath& path) {
874 874
      len = path.length();
875 875
      arcs = new Arc[len];
876 876
      int index = 0;
877 877
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
878 878
        arcs[index] = it;
879 879
        ++index;
880 880
      }
881 881
    }
882 882

	
883 883
    template <typename CPath>
884 884
    void buildRev(const CPath& path) {
885 885
      len = path.length();
886 886
      arcs = new Arc[len];
887 887
      int index = len;
888 888
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
889 889
        --index;
890 890
        arcs[index] = it;
891 891
      }
892 892
    }
893 893

	
894 894
  private:
895 895
    int len;
896 896
    Arc* arcs;
897 897
  };
898 898

	
899 899
  ///////////////////////////////////////////////////////////////////////
900 900
  // Additional utilities
901 901
  ///////////////////////////////////////////////////////////////////////
902 902

	
903 903
  namespace _path_bits {
904 904

	
905 905
    template <typename Path, typename Enable = void>
906
    struct RevTagIndicator {
906
    struct RevPathTagIndicator {
907 907
      static const bool value = false;
908 908
    };
909 909

	
910
    template <typename Digraph>
911
    struct RevTagIndicator<
912
      Digraph, 
913
      typename enable_if<typename Digraph::RevTag, void>::type
910
    template <typename Path>
911
    struct RevPathTagIndicator<
912
      Path, 
913
      typename enable_if<typename Path::RevPathTag, void>::type
914
      > {
915
      static const bool value = true;
916
    };
917

	
918
    template <typename Path, typename Enable = void>
919
    struct BuildTagIndicator {
920
      static const bool value = false;
921
    };
922

	
923
    template <typename Path>
924
    struct BuildTagIndicator<
925
      Path, 
926
      typename enable_if<typename Path::BuildTag, void>::type
914 927
    > {
915 928
      static const bool value = true;
916 929
    };
917 930

	
918 931
    template <typename Target, typename Source,
919
              typename BuildEnable = void, typename RevEnable = void>
932
	      bool buildEnable = BuildTagIndicator<Target>::value, 
933
	      bool revEnable = RevPathTagIndicator<Source>::value>
920 934
    struct PathCopySelector {
921 935
      static void copy(Target& target, const Source& source) {
922 936
        target.clear();
923 937
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
924 938
          target.addBack(it);
925 939
        }
926 940
      }
927 941
    };
928 942

	
929
    template <typename Target, typename Source, typename BuildEnable>
930
    struct PathCopySelector<
931
      Target, Source, BuildEnable, 
932
      typename enable_if<typename Source::RevPathTag, void>::type> {
943
    template <typename Target, typename Source>
944
    struct PathCopySelector<Target, Source, false, true> {
933 945
      static void copy(Target& target, const Source& source) {
934 946
        target.clear();
935 947
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
936 948
          target.addFront(it);
937 949
        }
938 950
      }
939 951
    };
940 952

	
941
    template <typename Target, typename Source, typename RevEnable>
942
    struct PathCopySelector<
943
      Target, Source, 
944
      typename enable_if<typename Target::BuildTag, void>::type, RevEnable> {
953
    template <typename Target, typename Source>
954
    struct PathCopySelector<Target, Source, true, false> {
945 955
      static void copy(Target& target, const Source& source) {
946 956
        target.clear();
947 957
        target.build(source);
948 958
      }
949 959
    };
950 960

	
951 961
    template <typename Target, typename Source>
952
    struct PathCopySelector<
953
      Target, Source, 
954
      typename enable_if<typename Target::BuildTag, void>::type,
955
      typename enable_if<typename Source::RevPathTag, void>::type> {
962
    struct PathCopySelector<Target, Source, true, true> {
956 963
      static void copy(Target& target, const Source& source) {
957 964
        target.clear();
958 965
        target.buildRev(source);
959 966
      }
960 967
    };
961 968

	
962 969
  }
963 970

	
964 971

	
965 972
  /// \brief Make a copy of a path.
966 973
  ///
967 974
  ///  This function makes a copy of a path.
968 975
  template <typename Target, typename Source>
969 976
  void copyPath(Target& target, const Source& source) {
970 977
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
971 978
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
972 979
  }
973 980

	
974 981
  /// \brief Check the consistency of a path.
975 982
  ///
976 983
  /// This function checks that the target of each arc is the same
977 984
  /// as the source of the next one. 
978 985
  /// 
979 986
  template <typename Digraph, typename Path>
980 987
  bool checkPath(const Digraph& digraph, const Path& path) {
981 988
    typename Path::ArcIt it(path);
982 989
    if (it == INVALID) return true;
983 990
    typename Digraph::Node node = digraph.target(it);
984 991
    ++it;
985 992
    while (it != INVALID) {
986 993
      if (digraph.source(it) != node) return false;
987 994
      node = digraph.target(it);
988 995
      ++it;
989 996
    }
990 997
    return true;
991 998
  }
992 999

	
993 1000
  /// \brief The source of a path
994 1001
  ///
995 1002
  /// This function returns the source of the given path.
996 1003
  template <typename Digraph, typename Path>
997 1004
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
998 1005
    return digraph.source(path.front());
999 1006
  }
1000 1007

	
1001 1008
  /// \brief The target of a path
1002 1009
  ///
1003 1010
  /// This function returns the target of the given path.
1004 1011
  template <typename Digraph, typename Path>
1005 1012
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1006 1013
    return digraph.target(path.back());
1007 1014
  }
1008 1015

	
1009 1016
  /// \brief Class which helps to iterate through the nodes of a path
1010 1017
  ///
1011 1018
  /// In a sense, the path can be treated as a list of arcs. The
1012 1019
  /// lemon path type stores only this list. As a consequence, it
1013 1020
  /// cannot enumerate the nodes in the path and the zero length paths
1014 1021
  /// cannot have a source node.
1015 1022
  ///
1016 1023
  /// This class implements the node iterator of a path structure. To
1017 1024
  /// provide this feature, the underlying digraph should be passed to
1018 1025
  /// the constructor of the iterator.
1019 1026
  template <typename Path>
1020 1027
  class PathNodeIt {
1021 1028
  private:
1022 1029
    const typename Path::Digraph *_digraph;
1023 1030
    typename Path::ArcIt _it;
1024 1031
    typename Path::Digraph::Node _nd;
1025 1032

	
1026 1033
  public:
1027 1034

	
1028 1035
    typedef typename Path::Digraph Digraph;
1029 1036
    typedef typename Digraph::Node Node;
1030 1037
    
1031 1038
    /// Default constructor
1032 1039
    PathNodeIt() {}
1033 1040
    /// Invalid constructor
1034 1041
    PathNodeIt(Invalid) 
1035 1042
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1036 1043
    /// Constructor
1037 1044
    PathNodeIt(const Digraph& digraph, const Path& path) 
1038 1045
      : _digraph(&digraph), _it(path) {
1039 1046
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1040 1047
    }
1041 1048
    /// Constructor
1042 1049
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src) 
1043 1050
      : _digraph(&digraph), _it(path), _nd(src) {}
1044 1051

	
1045 1052
    ///Conversion to Digraph::Node
1046 1053
    operator Node() const {
1047 1054
      return _nd;
1048 1055
    }
1049 1056

	
1050 1057
    /// Next node
1051 1058
    PathNodeIt& operator++() {
1052 1059
      if (_it == INVALID) _nd = INVALID;
1053 1060
      else {
1054 1061
	_nd = _digraph->target(_it);
1055 1062
	++_it;
1056 1063
      }
1057 1064
      return *this;
1058 1065
    }
1059 1066

	
1060 1067
    /// Comparison operator
1061 1068
    bool operator==(const PathNodeIt& n) const { 
1062 1069
      return _it == n._it && _nd == n._nd; 
1063 1070
    }
1064 1071
    /// Comparison operator
1065 1072
    bool operator!=(const PathNodeIt& n) const { 
1066 1073
      return _it != n._it || _nd != n._nd; 
1067 1074
    }
1068 1075
    /// Comparison operator
1069 1076
    bool operator<(const PathNodeIt& n) const { 
1070 1077
      return (_it < n._it && _nd != INVALID);
1071 1078
    }
1072 1079
    
1073 1080
  };
1074 1081
  
1075 1082
  ///@}
1076 1083

	
1077 1084
} // namespace lemon
1078 1085

	
1079 1086
#endif // LEMON_PATH_H
Ignore white space 1099511627776 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
    }
418 421
    
419 422
    ///@}
420 423

	
421 424
    ///\name Query Functions for the ellapsed time
422 425

	
423 426
    ///@{
424 427

	
425 428
    ///Gives back the ellapsed user time of the process
426 429
    double userTime() const
427 430
    {
428 431
      return operator TimeStamp().userTime();
429 432
    }
430 433
    ///Gives back the ellapsed system time of the process
431 434
    double systemTime() const
432 435
    {
433 436
      return operator TimeStamp().systemTime();
434 437
    }
435 438
    ///Gives back the ellapsed user time of the process' children
436 439

	
437 440
    ///\note On <tt>WIN32</tt> platform this value is not calculated. 
438 441
    ///
439 442
    double cUserTime() const
440 443
    {
441 444
      return operator TimeStamp().cUserTime();
442 445
    }
443 446
    ///Gives back the ellapsed user time of the process' children
444 447

	
445 448
    ///\note On <tt>WIN32</tt> platform this value is not calculated. 
446 449
    ///
447 450
    double cSystemTime() const
448 451
    {
449 452
      return operator TimeStamp().cSystemTime();
450 453
    }
451 454
    ///Gives back the ellapsed real time
452 455
    double realTime() const
453 456
    {
454 457
      return operator TimeStamp().realTime();
455 458
    }
456 459
    ///Computes the ellapsed time
457 460

	
458 461
    ///This conversion computes the ellapsed time, therefore you can print
459 462
    ///the ellapsed time like this.
460 463
    ///\code
461 464
    ///  Timer t;
462 465
    ///  doSomething();
463 466
    ///  std::cout << t << '\n';
464 467
    ///\endcode
465 468
    operator TimeStamp () const
466 469
    {
467 470
      TimeStamp t;
468 471
      t.stamp();
469 472
      return _running?t-start_time:start_time;
470 473
    }
471 474

	
472 475

	
473 476
    ///@}
474 477
  };
475 478

	
476 479
  ///Same as \ref Timer but prints a report on destruction.
477 480

	
478 481
  ///Same as \ref Timer but prints a report on destruction.
479 482
  ///This example shows its usage.
480 483
  ///\code
481 484
  ///  void myAlg(ListGraph &g,int n)
482 485
  ///  {
483 486
  ///    TimeReport tr("Running time of myAlg: ");
484 487
  ///    ... //Here comes the algorithm
485 488
  ///  }
486 489
  ///\endcode
487 490
  ///
488 491
  ///\sa Timer
489 492
  ///\sa NoTimeReport
490 493
  ///\todo There is no test case for this
491 494
  class TimeReport : public Timer 
492 495
  {
493 496
    std::string _title;
494 497
    std::ostream &_os;
495 498
  public:
496 499
    ///\e
497 500

	
498 501
    ///\param title This text will be printed before the ellapsed time.
499 502
    ///\param os The stream to print the report to.
500 503
    ///\param run Sets whether the timer should start immediately.
501 504

	
502 505
    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 
503 506
      : Timer(run), _title(title), _os(os){}
504 507
    ///\e Prints the ellapsed time on destruction.
505 508
    ~TimeReport() 
506 509
    {
507 510
      _os << _title << *this << std::endl;
508 511
    }
509 512
  };
510 513
      
511 514
  ///'Do nothing' version of \ref TimeReport
512 515

	
513 516
  ///\sa TimeReport
514 517
  ///
515 518
  class NoTimeReport
516 519
  {
517 520
  public:
518 521
    ///\e
519 522
    NoTimeReport(std::string,std::ostream &,bool) {}
520 523
    ///\e
521 524
    NoTimeReport(std::string,std::ostream &) {}
522 525
    ///\e
523 526
    NoTimeReport(std::string) {}
524 527
    ///\e Do nothing.
525 528
    ~NoTimeReport() {}
526 529

	
527 530
    operator TimeStamp () const { return TimeStamp(); }
528 531
    void reset() {}
529 532
    void start() {}
530 533
    void stop() {}
531 534
    void halt() {} 
532 535
    int running() { return 0; }
533 536
    void restart() {}
534 537
    double userTime() const { return 0; }
535 538
    double systemTime() const { return 0; }
536 539
    double cUserTime() const { return 0; }
537 540
    double cSystemTime() const { return 0; }
538 541
    double realTime() const { return 0; }
539 542
  };
540 543
      
541 544
  ///Tool to measure the running time more exactly.
542 545
  
543 546
  ///This function calls \c f several times and returns the average
544 547
  ///running time. The number of the executions will be choosen in such a way
545 548
  ///that the full real running time will be roughly between \c min_time
546 549
  ///and <tt>2*min_time</tt>.
547 550
  ///\param f the function object to be measured.
548 551
  ///\param min_time the minimum total running time.
549 552
  ///\retval num if it is not \c NULL, then the actual
550 553
  ///        number of execution of \c f will be written into <tt>*num</tt>.
551 554
  ///\retval full_time if it is not \c NULL, then the actual
552 555
  ///        total running time will be written into <tt>*full_time</tt>.
553 556
  ///\return The average running time of \c f.
554 557
  
555 558
  template<class F>
556 559
  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
557 560
                            TimeStamp *full_time=NULL)
558 561
  {
559 562
    TimeStamp full;
560 563
    unsigned int total=0;
561 564
    Timer t;
562 565
    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
563 566
      for(;total<tn;total++) f();
564 567
      full=t;
565 568
    }
566 569
    if(num) *num=total;
567 570
    if(full_time) *full_time=full;
568 571
    return full/total;
569 572
  }
570 573
  
571 574
  /// @}  
572 575

	
573 576

	
574 577
} //namespace lemon
575 578

	
576 579
#endif //LEMON_TIME_MEASURE_H
Ignore white space 1099511627776 line context
1
all:
2
	$(MAKE) -C ..
Ignore white space 1099511627776 line context
1
all:
2
	$(MAKE) -C ..
Ignore white space 1099511627776 line context
1
all:
2
	$(MAKE) -C ..
Ignore white space 1099511627776 line context
1
all:
2
	$(MAKE) -C ..
Ignore white space 1099511627776 line context
1
all:
2
	$(MAKE) -C ..
Ignore white space 1099511627776 line context
1
all:
2
	$(MAKE) -C ..
0 comments (0 inline)