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

	
19 19
/**
20 20
\dir demo
21 21
\brief A collection of demo applications.
22 22

	
23 23
This directory contains several simple demo applications, mainly
24 24
for educational purposes.
25 25
*/
26 26

	
27 27
/**
28 28
\dir doc
29 29
\brief Auxiliary (and the whole generated) documentation.
30 30

	
31 31
This directory contains some auxiliary pages and the whole generated
32 32
documentation.
33 33
*/
34 34

	
35 35
/**
36 36
\dir test
37 37
\brief Test programs.
38 38

	
39 39
This directory contains several test programs that check the consistency
40 40
of the code.
41 41
*/
42 42

	
43 43
/**
44 44
\dir tools
45 45
\brief Some useful executables.
46 46

	
47 47
This directory contains the sources of some useful complete executables.
48 48
*/
49 49

	
50 50
/**
51 51
\dir lemon
52 52
\brief Base include directory of LEMON.
53 53

	
54 54
This is the base directory of LEMON includes, so each include file must be
55 55
prefixed with this, e.g.
56 56
\code
57 57
#include<lemon/list_graph.h>
58 58
#include<lemon/dijkstra.h>
59 59
\endcode
60 60
*/
61 61

	
62 62
/**
63 63
\dir concepts
64 64
\brief Concept descriptors and checking classes.
65 65

	
66 66
This directory contains the concept descriptors and concept checking tools.
67 67
For more information see the \ref concept "Concepts" module.
68 68
*/
69 69

	
70 70
/**
71 71
\dir bits
72 72
\brief Auxiliary tools for implementation.
73 73

	
74
This directory contains some auxiliary classes for implementing graphs, 
74
This directory contains some auxiliary classes for implementing graphs,
75 75
maps and some other classes.
76 76
As a user you typically don't have to deal with these files.
77 77
*/
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
/**
20 20
@defgroup datas Data Structures
21 21
This group describes the several data structures implemented in LEMON.
22 22
*/
23 23

	
24 24
/**
25 25
@defgroup graphs Graph Structures
26 26
@ingroup datas
27 27
\brief Graph structures implemented in LEMON.
28 28

	
29 29
The implementation of combinatorial algorithms heavily relies on
30 30
efficient graph implementations. LEMON offers data structures which are
31 31
planned to be easily used in an experimental phase of implementation studies,
32 32
and thereafter the program code can be made efficient by small modifications.
33 33

	
34 34
The most efficient implementation of diverse applications require the
35 35
usage of different physical graph implementations. These differences
36 36
appear in the size of graph we require to handle, memory or time usage
37 37
limitations or in the set of operations through which the graph can be
38 38
accessed.  LEMON provides several physical graph structures to meet
39 39
the diverging requirements of the possible users.  In order to save on
40 40
running time or on memory usage, some structures may fail to provide
41 41
some graph features like arc/edge or node deletion.
42 42

	
43 43
You are free to use the graph structure that fit your requirements
44 44
the best, most graph algorithms and auxiliary data structures can be used
45 45
with any graph structure.
46 46

	
47 47
<b>See also:</b> \ref graph_concepts "Graph Structure Concepts".
48 48
*/
49 49

	
50 50
/**
51 51
@defgroup maps Maps
52 52
@ingroup datas
53 53
\brief Map structures implemented in LEMON.
54 54

	
55 55
This group describes the map structures implemented in LEMON.
56 56

	
57 57
LEMON provides several special purpose maps and map adaptors that e.g. combine
58 58
new maps from existing ones.
59 59

	
60 60
<b>See also:</b> \ref map_concepts "Map Concepts".
61 61
*/
62 62

	
63 63
/**
64 64
@defgroup graph_maps Graph Maps
65 65
@ingroup maps
66 66
\brief Special graph-related maps.
67 67

	
68 68
This group describes maps that are specifically designed to assign
69 69
values to the nodes and arcs of graphs.
70 70
*/
71 71

	
72 72
/**
73 73
\defgroup map_adaptors Map Adaptors
74 74
\ingroup maps
75 75
\brief Tools to create new maps from existing ones
76 76

	
77 77
This group describes map adaptors that are used to create "implicit"
78 78
maps from other maps.
79 79

	
80 80
Most of them are \ref lemon::concepts::ReadMap "read-only maps".
81 81
They can make arithmetic and logical operations between one or two maps
82 82
(negation, shifting, addition, multiplication, logical 'and', 'or',
83 83
'not' etc.) or e.g. convert a map to another one of different Value type.
84 84

	
85 85
The typical usage of this classes is passing implicit maps to
86 86
algorithms.  If a function type algorithm is called then the function
87 87
type map adaptors can be used comfortable. For example let's see the
88 88
usage of map adaptors with the \c graphToEps() function.
89 89
\code
90 90
  Color nodeColor(int deg) {
91 91
    if (deg >= 2) {
92 92
      return Color(0.5, 0.0, 0.5);
93 93
    } else if (deg == 1) {
94 94
      return Color(1.0, 0.5, 1.0);
95 95
    } else {
96 96
      return Color(0.0, 0.0, 0.0);
97 97
    }
98 98
  }
99 99

	
100 100
  Digraph::NodeMap<int> degree_map(graph);
101 101

	
102 102
  graphToEps(graph, "graph.eps")
103 103
    .coords(coords).scaleToA4().undirected()
104 104
    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
105 105
    .run();
106 106
\endcode
107 107
The \c functorToMap() function makes an \c int to \c Color map from the
108 108
\c nodeColor() function. The \c composeMap() compose the \c degree_map
109 109
and the previously created map. The composed map is a proper function to
110 110
get the color of each node.
111 111

	
112 112
The usage with class type algorithms is little bit harder. In this
113 113
case the function type map adaptors can not be used, because the
114 114
function map adaptors give back temporary objects.
115 115
\code
116 116
  Digraph graph;
117 117

	
118 118
  typedef Digraph::ArcMap<double> DoubleArcMap;
119 119
  DoubleArcMap length(graph);
120 120
  DoubleArcMap speed(graph);
121 121

	
122 122
  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
123 123
  TimeMap time(length, speed);
124 124

	
125 125
  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
126 126
  dijkstra.run(source, target);
127 127
\endcode
128 128
We have a length map and a maximum speed map on the arcs of a digraph.
129 129
The minimum time to pass the arc can be calculated as the division of
130 130
the two maps which can be done implicitly with the \c DivMap template
131 131
class. We use the implicit minimum time map as the length map of the
132 132
\c Dijkstra algorithm.
133 133
*/
134 134

	
135 135
/**
136 136
@defgroup paths Path Structures
137 137
@ingroup datas
138 138
\brief %Path structures implemented in LEMON.
139 139

	
140 140
This group describes the path structures implemented in LEMON.
141 141

	
142 142
LEMON provides flexible data structures to work with paths.
143 143
All of them have similar interfaces and they can be copied easily with
144 144
assignment operators and copy constructors. This makes it easy and
145 145
efficient to have e.g. the Dijkstra algorithm to store its result in
146 146
any kind of path structure.
147 147

	
148 148
\sa lemon::concepts::Path
149 149
*/
150 150

	
151 151
/**
152 152
@defgroup auxdat Auxiliary Data Structures
153 153
@ingroup datas
154 154
\brief Auxiliary data structures implemented in LEMON.
155 155

	
156 156
This group describes some data structures implemented in LEMON in
157 157
order to make it easier to implement combinatorial algorithms.
158 158
*/
159 159

	
160 160
/**
161 161
@defgroup algs Algorithms
162 162
\brief This group describes the several algorithms
163 163
implemented in LEMON.
164 164

	
165 165
This group describes the several algorithms
166 166
implemented in LEMON.
167 167
*/
168 168

	
169 169
/**
170 170
@defgroup search Graph Search
171 171
@ingroup algs
172 172
\brief Common graph search algorithms.
173 173

	
174 174
This group describes the common graph search algorithms like
175 175
Breadth-First Search (BFS) and Depth-First Search (DFS).
176 176
*/
177 177

	
178 178
/**
179 179
@defgroup shortest_path Shortest Path Algorithms
180 180
@ingroup algs
181 181
\brief Algorithms for finding shortest paths.
182 182

	
183 183
This group describes the algorithms for finding shortest paths in graphs.
184 184
*/
185 185

	
186 186
/**
187 187
@defgroup spantree Minimum Spanning Tree Algorithms
188 188
@ingroup algs
189 189
\brief Algorithms for finding a minimum cost spanning tree in a graph.
190 190

	
191 191
This group describes the algorithms for finding a minimum cost spanning
192 192
tree in a graph
193 193
*/
194 194

	
195 195
/**
196 196
@defgroup utils Tools and Utilities
197 197
\brief Tools and utilities for programming in LEMON
198 198

	
199 199
Tools and utilities for programming in LEMON.
200 200
*/
201 201

	
202 202
/**
203 203
@defgroup gutils Basic Graph Utilities
204 204
@ingroup utils
205 205
\brief Simple basic graph utilities.
206 206

	
207 207
This group describes some simple basic graph utilities.
208 208
*/
209 209

	
210 210
/**
211 211
@defgroup misc Miscellaneous Tools
212 212
@ingroup utils
213 213
\brief Tools for development, debugging and testing.
214 214

	
215 215
This group describes several useful tools for development,
216 216
debugging and testing.
217 217
*/
218 218

	
219 219
/**
220 220
@defgroup timecount Time Measuring and Counting
221 221
@ingroup misc
222 222
\brief Simple tools for measuring the performance of algorithms.
223 223

	
224 224
This group describes simple tools for measuring the performance
225 225
of algorithms.
226 226
*/
227 227

	
228 228
/**
229 229
@defgroup exceptions Exceptions
230 230
@ingroup utils
231 231
\brief Exceptions defined in LEMON.
232 232

	
233 233
This group describes the exceptions defined in LEMON.
234 234
*/
235 235

	
236 236
/**
237 237
@defgroup io_group Input-Output
238 238
\brief Graph Input-Output methods
239 239

	
240 240
This group describes the tools for importing and exporting graphs
241 241
and graph related data. Now it supports the LEMON format
242 242
and the encapsulated postscript (EPS) format.
243 243
postscript (EPS) format.
244 244
*/
245 245

	
246 246
/**
247 247
@defgroup lemon_io LEMON Input-Output
248 248
@ingroup io_group
249 249
\brief Reading and writing LEMON Graph Format.
250 250

	
251 251
This group describes methods for reading and writing
252 252
\ref lgf-format "LEMON Graph Format".
253 253
*/
254 254

	
255 255
/**
256 256
@defgroup eps_io Postscript Exporting
257 257
@ingroup io_group
258 258
\brief General \c EPS drawer and graph exporter
259 259

	
260 260
This group describes general \c EPS drawing methods and special
261 261
graph exporting tools.
262 262
*/
263 263

	
264 264
/**
265 265
@defgroup concept Concepts
266 266
\brief Skeleton classes and concept checking classes
267 267

	
268 268
This group describes the data/algorithm skeletons and concept checking
269 269
classes implemented in LEMON.
270 270

	
271 271
The purpose of the classes in this group is fourfold.
272 272

	
273 273
- These classes contain the documentations of the %concepts. In order
274 274
  to avoid document multiplications, an implementation of a concept
275 275
  simply refers to the corresponding concept class.
276 276

	
277 277
- These classes declare every functions, <tt>typedef</tt>s etc. an
278 278
  implementation of the %concepts should provide, however completely
279 279
  without implementations and real data structures behind the
280 280
  interface. On the other hand they should provide nothing else. All
281 281
  the algorithms working on a data structure meeting a certain concept
282 282
  should compile with these classes. (Though it will not run properly,
283 283
  of course.) In this way it is easily to check if an algorithm
284 284
  doesn't use any extra feature of a certain implementation.
285 285

	
286 286
- The concept descriptor classes also provide a <em>checker class</em>
287 287
  that makes it possible to check whether a certain implementation of a
288 288
  concept indeed provides all the required features.
289 289

	
290 290
- Finally, They can serve as a skeleton of a new implementation of a concept.
291 291
*/
292 292

	
293 293
/**
294 294
@defgroup graph_concepts Graph Structure Concepts
295 295
@ingroup concept
296 296
\brief Skeleton and concept checking classes for graph structures
297 297

	
298 298
This group describes the skeletons and concept checking classes of LEMON's
299 299
graph structures and helper classes used to implement these.
300 300
*/
301 301

	
302 302
/**
303 303
@defgroup map_concepts Map Concepts
304 304
@ingroup concept
305 305
\brief Skeleton and concept checking classes for maps
306
 
306

	
307 307
This group describes the skeletons and concept checking classes of maps.
308 308
*/
309 309

	
310 310
/**
311 311
\anchor demoprograms
312 312

	
313 313
@defgroup demos Demo programs
314 314

	
315 315
Some demo programs are listed here. Their full source codes can be found in
316 316
the \c demo subdirectory of the source tree.
317 317

	
318 318
It order to compile them, use <tt>--enable-demo</tt> configure option when
319 319
build the library.
320 320
*/
Ignore white space 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24 24
\page lgf-format LEMON Graph Format (LGF)
25 25

	
26 26
The \e LGF is a <em>column oriented</em>
27 27
file format for storing graphs and associated data like
28 28
node and edge maps.
29 29

	
30 30
Each line with \c '#' first non-whitespace
31 31
character is considered as a comment line.
32 32

	
33 33
Otherwise the file consists of sections starting with
34 34
a header line. The header lines starts with an \c '@' character followed by the
35 35
type of section. The standard section types are \c \@nodes, \c
36 36
\@arcs and \c \@edges
37 37
and \@attributes. Each header line may also have an optional
38 38
\e name, which can be use to distinguish the sections of the same
39 39
type.
40 40

	
41 41
The standard sections are column oriented, each line consists of
42 42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43 43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44 44
while a quoted token is a
45 45
character sequence surrounded by double quotes, and it can also
46 46
contain whitespaces and escape sequences.
47 47

	
48 48
The \c \@nodes section describes a set of nodes and associated
49 49
maps. The first is a header line, its columns are the names of the
50 50
maps appearing in the following lines.
51 51
One of the maps must be called \c
52 52
"label", which plays special role in the file.
53 53
The following
54 54
non-empty lines until the next section describes nodes of the
55 55
graph. Each line contains the values of the node maps
56 56
associated to the current node.
57 57

	
58 58
\code
59 59
 @nodes
60 60
 label  coordinates  size    title
61 61
 1      (10,20)      10      "First node"
62 62
 2      (80,80)      8       "Second node"
63 63
 3      (40,10)      10      "Third node"
64 64
\endcode
65 65

	
66 66
The \c \@arcs section is very similar to the \c \@nodes section, it
67 67
again starts with a header line describing the names of the maps, but
68 68
the \c "label" map is not obligatory here. The following lines
69 69
describe the arcs. The first two tokens of each line are the source
70 70
and the target node of the arc, respectively, then come the map
71 71
values. The source and target tokens must be node labels.
72 72

	
73 73
\code
74 74
 @arcs
75 75
         capacity
76 76
 1   2   16
77 77
 1   3   12
78 78
 2   3   18
79 79
\endcode
80 80

	
81 81
If there is no map in the \c \@arcs section at all, then it must be
82 82
indicated by a sole '-' sign in the first line.
83 83

	
84 84
\code
85 85
 @arcs
86 86
         -
87 87
 1   2
88 88
 1   3
89 89
 2   3
90 90
\endcode
91 91

	
92 92
The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
93 93
also store the edge set of an undirected graph. In such case there is
94 94
a conventional method for store arc maps in the file, if two columns
95 95
have the same caption with \c '+' and \c '-' prefix, then these columns
96 96
can be regarded as the values of an arc map.
97 97

	
98 98
The \c \@attributes section contains key-value pairs, each line
99 99
consists of two tokens, an attribute name, and then an attribute
100 100
value. The value of the attribute could be also a label value of a
101 101
node or an edge, or even an edge label prefixed with \c '+' or \c '-',
102 102
which regards to the forward or backward directed arc of the
103 103
corresponding edge.
104 104

	
105 105
\code
106 106
 @attributes
107 107
 source 1
108 108
 target 3
109 109
 caption "LEMON test digraph"
110 110
\endcode
111 111

	
112 112
The \e LGF can contain extra sections, but there is no restriction on
113 113
the format of such sections.
114 114

	
115 115
*/
116 116
}
117 117

	
118 118
//  LocalWords:  whitespace whitespaces
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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
///\file
20 20
///\brief Some basic non-inline functions and static global data.
21 21

	
22 22
#include<lemon/tolerance.h>
23 23
#include<lemon/core.h>
24 24
namespace lemon {
25 25

	
26 26
  float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
27 27
  double Tolerance<double>::def_epsilon = 1e-10;
28 28
  long double Tolerance<long double>::def_epsilon = 1e-14;
29 29

	
30 30
#ifndef LEMON_ONLY_TEMPLATES
31 31
  const Invalid INVALID = Invalid();
32 32
#endif
33 33

	
34 34
} //namespace lemon
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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_BITS_DEFAULT_MAP_H
20 20
#define LEMON_BITS_DEFAULT_MAP_H
21 21

	
22 22
#include <lemon/config.h>
23 23
#include <lemon/bits/array_map.h>
24 24
#include <lemon/bits/vector_map.h>
25 25
//#include <lemon/bits/debug_map.h>
26 26

	
27 27
//\ingroup graphbits
28 28
//\file
29 29
//\brief Graph maps that construct and destruct their elements dynamically.
30 30

	
31 31
namespace lemon {
32 32

	
33 33

	
34 34
  //#ifndef LEMON_USE_DEBUG_MAP
35 35

	
36 36
  template <typename _Graph, typename _Item, typename _Value>
37 37
  struct DefaultMapSelector {
38 38
    typedef ArrayMap<_Graph, _Item, _Value> Map;
39 39
  };
40 40

	
41 41
  // bool
42 42
  template <typename _Graph, typename _Item>
43 43
  struct DefaultMapSelector<_Graph, _Item, bool> {
44 44
    typedef VectorMap<_Graph, _Item, bool> Map;
45 45
  };
46 46

	
47 47
  // char
48 48
  template <typename _Graph, typename _Item>
49 49
  struct DefaultMapSelector<_Graph, _Item, char> {
50 50
    typedef VectorMap<_Graph, _Item, char> Map;
51 51
  };
52 52

	
53 53
  template <typename _Graph, typename _Item>
54 54
  struct DefaultMapSelector<_Graph, _Item, signed char> {
55 55
    typedef VectorMap<_Graph, _Item, signed char> Map;
56 56
  };
57 57

	
58 58
  template <typename _Graph, typename _Item>
59 59
  struct DefaultMapSelector<_Graph, _Item, unsigned char> {
60 60
    typedef VectorMap<_Graph, _Item, unsigned char> Map;
61 61
  };
62 62

	
63 63

	
64 64
  // int
65 65
  template <typename _Graph, typename _Item>
66 66
  struct DefaultMapSelector<_Graph, _Item, signed int> {
67 67
    typedef VectorMap<_Graph, _Item, signed int> Map;
68 68
  };
69 69

	
70 70
  template <typename _Graph, typename _Item>
71 71
  struct DefaultMapSelector<_Graph, _Item, unsigned int> {
72 72
    typedef VectorMap<_Graph, _Item, unsigned int> Map;
73 73
  };
74 74

	
75 75

	
76 76
  // short
77 77
  template <typename _Graph, typename _Item>
78 78
  struct DefaultMapSelector<_Graph, _Item, signed short> {
79 79
    typedef VectorMap<_Graph, _Item, signed short> Map;
80 80
  };
81 81

	
82 82
  template <typename _Graph, typename _Item>
83 83
  struct DefaultMapSelector<_Graph, _Item, unsigned short> {
84 84
    typedef VectorMap<_Graph, _Item, unsigned short> Map;
85 85
  };
86 86

	
87 87

	
88 88
  // long
89 89
  template <typename _Graph, typename _Item>
90 90
  struct DefaultMapSelector<_Graph, _Item, signed long> {
91 91
    typedef VectorMap<_Graph, _Item, signed long> Map;
92 92
  };
93 93

	
94 94
  template <typename _Graph, typename _Item>
95 95
  struct DefaultMapSelector<_Graph, _Item, unsigned long> {
96 96
    typedef VectorMap<_Graph, _Item, unsigned long> Map;
97 97
  };
98 98

	
99 99

	
100 100
#if defined LEMON_HAVE_LONG_LONG
101 101

	
102 102
  // long long
103 103
  template <typename _Graph, typename _Item>
104 104
  struct DefaultMapSelector<_Graph, _Item, signed long long> {
105 105
    typedef VectorMap<_Graph, _Item, signed long long> Map;
106 106
  };
107 107

	
108 108
  template <typename _Graph, typename _Item>
109 109
  struct DefaultMapSelector<_Graph, _Item, unsigned long long> {
110 110
    typedef VectorMap<_Graph, _Item, unsigned long long> Map;
111 111
  };
112 112

	
113 113
#endif
114 114

	
115 115

	
116 116
  // float
117 117
  template <typename _Graph, typename _Item>
118 118
  struct DefaultMapSelector<_Graph, _Item, float> {
119 119
    typedef VectorMap<_Graph, _Item, float> Map;
120 120
  };
121 121

	
122 122

	
123 123
  // double
124 124
  template <typename _Graph, typename _Item>
125 125
  struct DefaultMapSelector<_Graph, _Item, double> {
126 126
    typedef VectorMap<_Graph, _Item,  double> Map;
127 127
  };
128 128

	
129 129

	
130 130
  // long double
131 131
  template <typename _Graph, typename _Item>
132 132
  struct DefaultMapSelector<_Graph, _Item, long double> {
133 133
    typedef VectorMap<_Graph, _Item, long double> Map;
134 134
  };
135 135

	
136 136

	
137 137
  // pointer
138 138
  template <typename _Graph, typename _Item, typename _Ptr>
139 139
  struct DefaultMapSelector<_Graph, _Item, _Ptr*> {
140 140
    typedef VectorMap<_Graph, _Item, _Ptr*> Map;
141 141
  };
142 142

	
143 143
// #else
144 144

	
145 145
//   template <typename _Graph, typename _Item, typename _Value>
146 146
//   struct DefaultMapSelector {
147 147
//     typedef DebugMap<_Graph, _Item, _Value> Map;
148 148
//   };
149 149

	
150 150
// #endif
151 151

	
152 152
  // DefaultMap class
153 153
  template <typename _Graph, typename _Item, typename _Value>
154 154
  class DefaultMap
155 155
    : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
156 156
  public:
157 157
    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
158 158
    typedef DefaultMap<_Graph, _Item, _Value> Map;
159 159

	
160 160
    typedef typename Parent::Graph Graph;
161 161
    typedef typename Parent::Value Value;
162 162

	
163 163
    explicit DefaultMap(const Graph& graph) : Parent(graph) {}
164 164
    DefaultMap(const Graph& graph, const Value& value)
165 165
      : Parent(graph, value) {}
166 166

	
167 167
    DefaultMap& operator=(const DefaultMap& cmap) {
168 168
      return operator=<DefaultMap>(cmap);
169 169
    }
170 170

	
171 171
    template <typename CMap>
172 172
    DefaultMap& operator=(const CMap& cmap) {
173 173
      Parent::operator=(cmap);
174 174
      return *this;
175 175
    }
176 176

	
177 177
  };
178 178

	
179 179
}
180 180

	
181 181
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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_BITS_MAP_EXTENDER_H
20 20
#define LEMON_BITS_MAP_EXTENDER_H
21 21

	
22 22
#include <iterator>
23 23

	
24 24
#include <lemon/bits/traits.h>
25 25

	
26 26
#include <lemon/concept_check.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
//\file
30 30
//\brief Extenders for iterable maps.
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  // \ingroup graphbits
35 35
  //
36 36
  // \brief Extender for maps
37 37
  template <typename _Map>
38 38
  class MapExtender : public _Map {
39 39
  public:
40 40

	
41 41
    typedef _Map Parent;
42 42
    typedef MapExtender Map;
43 43

	
44 44

	
45 45
    typedef typename Parent::Graph Graph;
46 46
    typedef typename Parent::Key Item;
47 47

	
48 48
    typedef typename Parent::Key Key;
49 49
    typedef typename Parent::Value Value;
50 50

	
51 51
    class MapIt;
52 52
    class ConstMapIt;
53 53

	
54 54
    friend class MapIt;
55 55
    friend class ConstMapIt;
56 56

	
57 57
  public:
58 58

	
59 59
    MapExtender(const Graph& graph)
60 60
      : Parent(graph) {}
61 61

	
62 62
    MapExtender(const Graph& graph, const Value& value)
63 63
      : Parent(graph, value) {}
64 64

	
65 65
  private:
66 66
    MapExtender& operator=(const MapExtender& cmap) {
67 67
      return operator=<MapExtender>(cmap);
68 68
    }
69 69

	
70 70
    template <typename CMap>
71 71
    MapExtender& operator=(const CMap& cmap) {
72 72
      Parent::operator=(cmap);
73 73
      return *this;
74 74
    }
75 75

	
76 76
  public:
77 77
    class MapIt : public Item {
78 78
    public:
79 79

	
80 80
      typedef Item Parent;
81 81
      typedef typename Map::Value Value;
82 82

	
83 83
      MapIt() : map(NULL) {}
84 84

	
85 85
      MapIt(Invalid i) : Parent(i), map(NULL) {}
86 86

	
87 87
      explicit MapIt(Map& _map) : map(&_map) {
88 88
        map->notifier()->first(*this);
89 89
      }
90 90

	
91 91
      MapIt(const Map& _map, const Item& item)
92 92
        : Parent(item), map(&_map) {}
93 93

	
94 94
      MapIt& operator++() {
95 95
        map->notifier()->next(*this);
96 96
        return *this;
97 97
      }
98 98

	
99 99
      typename MapTraits<Map>::ConstReturnValue operator*() const {
100 100
        return (*map)[*this];
101 101
      }
102 102

	
103 103
      typename MapTraits<Map>::ReturnValue operator*() {
104 104
        return (*map)[*this];
105 105
      }
106 106

	
107 107
      void set(const Value& value) {
108 108
        map->set(*this, value);
109 109
      }
110 110

	
111 111
    protected:
112 112
      Map* map;
113 113

	
114 114
    };
115 115

	
116 116
    class ConstMapIt : public Item {
117 117
    public:
118 118

	
119 119
      typedef Item Parent;
120 120

	
121 121
      typedef typename Map::Value Value;
122 122

	
123 123
      ConstMapIt() : map(NULL) {}
124 124

	
125 125
      ConstMapIt(Invalid i) : Parent(i), map(NULL) {}
126 126

	
127 127
      explicit ConstMapIt(Map& _map) : map(&_map) {
128 128
        map->notifier()->first(*this);
129 129
      }
130 130

	
131 131
      ConstMapIt(const Map& _map, const Item& item)
132 132
        : Parent(item), map(_map) {}
133 133

	
134 134
      ConstMapIt& operator++() {
135 135
        map->notifier()->next(*this);
136 136
        return *this;
137 137
      }
138 138

	
139 139
      typename MapTraits<Map>::ConstReturnValue operator*() const {
140 140
        return map[*this];
141 141
      }
142 142

	
143 143
    protected:
144 144
      const Map* map;
145 145
    };
146 146

	
147 147
    class ItemIt : public Item {
148 148
    public:
149 149

	
150 150
      typedef Item Parent;
151 151

	
152 152
      ItemIt() : map(NULL) {}
153 153

	
154 154
      ItemIt(Invalid i) : Parent(i), map(NULL) {}
155 155

	
156 156
      explicit ItemIt(Map& _map) : map(&_map) {
157 157
        map->notifier()->first(*this);
158 158
      }
159 159

	
160 160
      ItemIt(const Map& _map, const Item& item)
161 161
        : Parent(item), map(&_map) {}
162 162

	
163 163
      ItemIt& operator++() {
164 164
        map->notifier()->next(*this);
165 165
        return *this;
166 166
      }
167 167

	
168 168
    protected:
169 169
      const Map* map;
170 170

	
171 171
    };
172 172
  };
173 173

	
174 174
  // \ingroup graphbits
175 175
  //
176 176
  // \brief Extender for maps which use a subset of the items.
177 177
  template <typename _Graph, typename _Map>
178 178
  class SubMapExtender : public _Map {
179 179
  public:
180 180

	
181 181
    typedef _Map Parent;
182 182
    typedef SubMapExtender Map;
183 183

	
184 184
    typedef _Graph Graph;
185 185

	
186 186
    typedef typename Parent::Key Item;
187 187

	
188 188
    typedef typename Parent::Key Key;
189 189
    typedef typename Parent::Value Value;
190 190

	
191 191
    class MapIt;
192 192
    class ConstMapIt;
193 193

	
194 194
    friend class MapIt;
195 195
    friend class ConstMapIt;
196 196

	
197 197
  public:
198 198

	
199 199
    SubMapExtender(const Graph& _graph)
200 200
      : Parent(_graph), graph(_graph) {}
201 201

	
202 202
    SubMapExtender(const Graph& _graph, const Value& _value)
203 203
      : Parent(_graph, _value), graph(_graph) {}
204 204

	
205 205
  private:
206 206
    SubMapExtender& operator=(const SubMapExtender& cmap) {
207 207
      return operator=<MapExtender>(cmap);
208 208
    }
209 209

	
210 210
    template <typename CMap>
211 211
    SubMapExtender& operator=(const CMap& cmap) {
212 212
      checkConcept<concepts::ReadMap<Key, Value>, CMap>();
213 213
      Item it;
214 214
      for (graph.first(it); it != INVALID; graph.next(it)) {
215 215
        Parent::set(it, cmap[it]);
216 216
      }
217 217
      return *this;
218 218
    }
219 219

	
220 220
  public:
221 221
    class MapIt : public Item {
222 222
    public:
223 223

	
224 224
      typedef Item Parent;
225 225
      typedef typename Map::Value Value;
226 226

	
227 227
      MapIt() : map(NULL) {}
228 228

	
229 229
      MapIt(Invalid i) : Parent(i), map(NULL) { }
230 230

	
231 231
      explicit MapIt(Map& _map) : map(&_map) {
232 232
        map->graph.first(*this);
233 233
      }
234 234

	
235 235
      MapIt(const Map& _map, const Item& item)
236 236
        : Parent(item), map(&_map) {}
237 237

	
238 238
      MapIt& operator++() {
239 239
        map->graph.next(*this);
240 240
        return *this;
241 241
      }
242 242

	
243 243
      typename MapTraits<Map>::ConstReturnValue operator*() const {
244 244
        return (*map)[*this];
245 245
      }
246 246

	
247 247
      typename MapTraits<Map>::ReturnValue operator*() {
248 248
        return (*map)[*this];
249 249
      }
250 250

	
251 251
      void set(const Value& value) {
252 252
        map->set(*this, value);
253 253
      }
254 254

	
255 255
    protected:
256 256
      Map* map;
257 257

	
258 258
    };
259 259

	
260 260
    class ConstMapIt : public Item {
261 261
    public:
262 262

	
263 263
      typedef Item Parent;
264 264

	
265 265
      typedef typename Map::Value Value;
266 266

	
267 267
      ConstMapIt() : map(NULL) {}
268 268

	
269 269
      ConstMapIt(Invalid i) : Parent(i), map(NULL) { }
270 270

	
271 271
      explicit ConstMapIt(Map& _map) : map(&_map) {
272 272
        map->graph.first(*this);
273 273
      }
274 274

	
275 275
      ConstMapIt(const Map& _map, const Item& item)
276 276
        : Parent(item), map(&_map) {}
277 277

	
278 278
      ConstMapIt& operator++() {
279 279
        map->graph.next(*this);
280 280
        return *this;
281 281
      }
282 282

	
283 283
      typename MapTraits<Map>::ConstReturnValue operator*() const {
284 284
        return (*map)[*this];
285 285
      }
286 286

	
287 287
    protected:
288 288
      const Map* map;
289 289
    };
290 290

	
291 291
    class ItemIt : public Item {
292 292
    public:
293 293

	
294 294
      typedef Item Parent;
295 295

	
296 296
      ItemIt() : map(NULL) {}
297 297

	
298 298
      ItemIt(Invalid i) : Parent(i), map(NULL) { }
299 299

	
300 300
      explicit ItemIt(Map& _map) : map(&_map) {
301 301
        map->graph.first(*this);
302 302
      }
303 303

	
304 304
      ItemIt(const Map& _map, const Item& item)
305 305
        : Parent(item), map(&_map) {}
306 306

	
307 307
      ItemIt& operator++() {
308 308
        map->graph.next(*this);
309 309
        return *this;
310 310
      }
311 311

	
312 312
    protected:
313 313
      const Map* map;
314 314

	
315 315
    };
316 316

	
317 317
  private:
318 318

	
319 319
    const Graph& graph;
320 320

	
321 321
  };
322 322

	
323 323
}
324 324

	
325 325
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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_BITS_PRED_MAP_PATH_H
20 20
#define LEMON_BITS_PRED_MAP_PATH_H
21 21

	
22 22
namespace lemon {
23 23

	
24 24
  template <typename _Digraph, typename _PredMap>
25 25
  class PredMapPath {
26 26
  public:
27 27
    typedef True RevPathTag;
28 28

	
29 29
    typedef _Digraph Digraph;
30 30
    typedef typename Digraph::Arc Arc;
31 31
    typedef _PredMap PredMap;
32 32

	
33 33
    PredMapPath(const Digraph& _digraph, const PredMap& _predMap,
34 34
                typename Digraph::Node _target)
35 35
      : digraph(_digraph), predMap(_predMap), target(_target) {}
36 36

	
37 37
    int length() const {
38 38
      int len = 0;
39 39
      typename Digraph::Node node = target;
40 40
      typename Digraph::Arc arc;
41 41
      while ((arc = predMap[node]) != INVALID) {
42 42
        node = digraph.source(arc);
43 43
        ++len;
44 44
      }
45 45
      return len;
46 46
    }
47 47

	
48 48
    bool empty() const {
49 49
      return predMap[target] == INVALID;
50 50
    }
51 51

	
52 52
    class RevArcIt {
53 53
    public:
54 54
      RevArcIt() {}
55 55
      RevArcIt(Invalid) : path(0), current(INVALID) {}
56 56
      RevArcIt(const PredMapPath& _path)
57 57
        : path(&_path), current(_path.target) {
58 58
        if (path->predMap[current] == INVALID) current = INVALID;
59 59
      }
60 60

	
61 61
      operator const typename Digraph::Arc() const {
62 62
        return path->predMap[current];
63 63
      }
64 64

	
65 65
      RevArcIt& operator++() {
66 66
        current = path->digraph.source(path->predMap[current]);
67 67
        if (path->predMap[current] == INVALID) current = INVALID;
68 68
        return *this;
69 69
      }
70 70

	
71 71
      bool operator==(const RevArcIt& e) const {
72 72
        return current == e.current;
73 73
      }
74 74

	
75 75
      bool operator!=(const RevArcIt& e) const {
76 76
        return current != e.current;
77 77
      }
78 78

	
79 79
      bool operator<(const RevArcIt& e) const {
80 80
        return current < e.current;
81 81
      }
82 82

	
83 83
    private:
84 84
      const PredMapPath* path;
85 85
      typename Digraph::Node current;
86 86
    };
87 87

	
88 88
  private:
89 89
    const Digraph& digraph;
90 90
    const PredMap& predMap;
91 91
    typename Digraph::Node target;
92 92
  };
93 93

	
94 94

	
95 95
  template <typename _Digraph, typename _PredMatrixMap>
96 96
  class PredMatrixMapPath {
97 97
  public:
98 98
    typedef True RevPathTag;
99 99

	
100 100
    typedef _Digraph Digraph;
101 101
    typedef typename Digraph::Arc Arc;
102 102
    typedef _PredMatrixMap PredMatrixMap;
103 103

	
104 104
    PredMatrixMapPath(const Digraph& _digraph,
105 105
                      const PredMatrixMap& _predMatrixMap,
106 106
                      typename Digraph::Node _source,
107 107
                      typename Digraph::Node _target)
108 108
      : digraph(_digraph), predMatrixMap(_predMatrixMap),
109 109
        source(_source), target(_target) {}
110 110

	
111 111
    int length() const {
112 112
      int len = 0;
113 113
      typename Digraph::Node node = target;
114 114
      typename Digraph::Arc arc;
115 115
      while ((arc = predMatrixMap(source, node)) != INVALID) {
116 116
        node = digraph.source(arc);
117 117
        ++len;
118 118
      }
119 119
      return len;
120 120
    }
121 121

	
122 122
    bool empty() const {
123 123
      return predMatrixMap(source, target) == INVALID;
124 124
    }
125 125

	
126 126
    class RevArcIt {
127 127
    public:
128 128
      RevArcIt() {}
129 129
      RevArcIt(Invalid) : path(0), current(INVALID) {}
130 130
      RevArcIt(const PredMatrixMapPath& _path)
131 131
        : path(&_path), current(_path.target) {
132 132
        if (path->predMatrixMap(path->source, current) == INVALID)
133 133
          current = INVALID;
134 134
      }
135 135

	
136 136
      operator const typename Digraph::Arc() const {
137 137
        return path->predMatrixMap(path->source, current);
138 138
      }
139 139

	
140 140
      RevArcIt& operator++() {
141 141
        current =
142 142
          path->digraph.source(path->predMatrixMap(path->source, current));
143 143
        if (path->predMatrixMap(path->source, current) == INVALID)
144 144
          current = INVALID;
145 145
        return *this;
146 146
      }
147 147

	
148 148
      bool operator==(const RevArcIt& e) const {
149 149
        return current == e.current;
150 150
      }
151 151

	
152 152
      bool operator!=(const RevArcIt& e) const {
153 153
        return current != e.current;
154 154
      }
155 155

	
156 156
      bool operator<(const RevArcIt& e) const {
157 157
        return current < e.current;
158 158
      }
159 159

	
160 160
    private:
161 161
      const PredMatrixMapPath* path;
162 162
      typename Digraph::Node current;
163 163
    };
164 164

	
165 165
  private:
166 166
    const Digraph& digraph;
167 167
    const PredMatrixMap& predMatrixMap;
168 168
    typename Digraph::Node source;
169 169
    typename Digraph::Node target;
170 170
  };
171 171

	
172 172
}
173 173

	
174 174
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
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
///\file
20 20
///\brief Some basic non-inline functions and static global data.
21 21

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

	
24 24
#ifdef WIN32
25 25
#ifndef WIN32_LEAN_AND_MEAN
26 26
#define WIN32_LEAN_AND_MEAN
27 27
#endif
28 28
#ifndef NOMINMAX
29 29
#define NOMINMAX
30 30
#endif
31 31
#ifdef UNICODE
32 32
#undef UNICODE
33 33
#endif
34 34
#include <windows.h>
35 35
#ifdef LOCALE_INVARIANT
36 36
#define MY_LOCALE LOCALE_INVARIANT
37 37
#else
38 38
#define MY_LOCALE LOCALE_NEUTRAL
39 39
#endif
40 40
#else
41 41
#include <unistd.h>
42 42
#include <ctime>
43 43
#include <sys/times.h>
44 44
#include <sys/time.h>
45 45
#endif
46 46

	
47 47
#include <cmath>
48 48
#include <sstream>
49 49

	
50 50
namespace lemon {
51 51
  namespace bits {
52 52
    void getWinProcTimes(double &rtime,
53 53
                         double &utime, double &stime,
54 54
                         double &cutime, double &cstime)
55 55
    {
56 56
#ifdef WIN32
57 57
      static const double ch = 4294967296.0e-7;
58 58
      static const double cl = 1.0e-7;
59 59

	
60 60
      FILETIME system;
61 61
      GetSystemTimeAsFileTime(&system);
62 62
      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
63 63

	
64 64
      FILETIME create, exit, kernel, user;
65 65
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
66 66
        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
67 67
        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
68 68
        cutime = 0;
69 69
        cstime = 0;
70 70
      } else {
71 71
        rtime = 0;
72 72
        utime = 0;
73 73
        stime = 0;
74 74
        cutime = 0;
75 75
        cstime = 0;
76 76
      }
77 77
#else
78 78
      timeval tv;
79 79
      gettimeofday(&tv, 0);
80 80
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
81 81

	
82 82
      tms ts;
83 83
      double tck=sysconf(_SC_CLK_TCK);
84 84
      times(&ts);
85 85
      utime=ts.tms_utime/tck;
86 86
      stime=ts.tms_stime/tck;
87 87
      cutime=ts.tms_cutime/tck;
88 88
      cstime=ts.tms_cstime/tck;
89 89
#endif
90 90
    }
91 91

	
92 92
    std::string getWinFormattedDate()
93 93
    {
94 94
      std::ostringstream os;
95 95
#ifdef WIN32
96 96
      SYSTEMTIME time;
97 97
      GetSystemTime(&time);
98 98
      char buf1[11], buf2[9], buf3[5];
99
	  if (GetDateFormat(MY_LOCALE, 0, &time,
99
          if (GetDateFormat(MY_LOCALE, 0, &time,
100 100
                        ("ddd MMM dd"), buf1, 11) &&
101 101
          GetTimeFormat(MY_LOCALE, 0, &time,
102 102
                        ("HH':'mm':'ss"), buf2, 9) &&
103 103
          GetDateFormat(MY_LOCALE, 0, &time,
104 104
                        ("yyyy"), buf3, 5)) {
105 105
        os << buf1 << ' ' << buf2 << ' ' << buf3;
106 106
      }
107 107
      else os << "unknown";
108 108
#else
109 109
      timeval tv;
110 110
      gettimeofday(&tv, 0);
111 111

	
112 112
      char cbuf[26];
113 113
      ctime_r(&tv.tv_sec,cbuf);
114 114
      os << cbuf;
115 115
#endif
116 116
      return os.str();
117 117
    }
118 118

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

	
22 22
#include <vector>
23 23
#include <algorithm>
24 24

	
25 25
#include <lemon/config.h>
26 26
#include <lemon/bits/enable_if.h>
27 27
#include <lemon/bits/traits.h>
28 28
#include <lemon/assert.h>
29 29

	
30 30
///\file
31 31
///\brief LEMON core utilities.
32 32
///
33 33
///This header file contains core utilities for LEMON.
34 34
///It is automatically included by all graph types, therefore it usually
35 35
///do not have to be included directly.
36 36

	
37 37
namespace lemon {
38 38

	
39 39
  /// \brief Dummy type to make it easier to create invalid iterators.
40 40
  ///
41 41
  /// Dummy type to make it easier to create invalid iterators.
42 42
  /// See \ref INVALID for the usage.
43 43
  struct Invalid {
44 44
  public:
45 45
    bool operator==(Invalid) { return true;  }
46 46
    bool operator!=(Invalid) { return false; }
47 47
    bool operator< (Invalid) { return false; }
48 48
  };
49 49

	
50 50
  /// \brief Invalid iterators.
51 51
  ///
52 52
  /// \ref Invalid is a global type that converts to each iterator
53 53
  /// in such a way that the value of the target iterator will be invalid.
54 54
#ifdef LEMON_ONLY_TEMPLATES
55 55
  const Invalid INVALID = Invalid();
56 56
#else
57 57
  extern const Invalid INVALID;
58 58
#endif
59 59

	
60 60
  /// \addtogroup gutils
61 61
  /// @{
62 62

	
63 63
  ///Create convenience typedefs for the digraph types and iterators
64 64

	
65 65
  ///This \c \#define creates convenient type definitions for the following
66 66
  ///types of \c Digraph: \c Node,  \c NodeIt, \c Arc, \c ArcIt, \c InArcIt,
67 67
  ///\c OutArcIt, \c BoolNodeMap, \c IntNodeMap, \c DoubleNodeMap,
68 68
  ///\c BoolArcMap, \c IntArcMap, \c DoubleArcMap.
69 69
  ///
70 70
  ///\note If the graph type is a dependent type, ie. the graph type depend
71 71
  ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS()
72 72
  ///macro.
73 73
#define DIGRAPH_TYPEDEFS(Digraph)                                       \
74 74
  typedef Digraph::Node Node;                                           \
75 75
  typedef Digraph::NodeIt NodeIt;                                       \
76 76
  typedef Digraph::Arc Arc;                                             \
77 77
  typedef Digraph::ArcIt ArcIt;                                         \
78 78
  typedef Digraph::InArcIt InArcIt;                                     \
79 79
  typedef Digraph::OutArcIt OutArcIt;                                   \
80 80
  typedef Digraph::NodeMap<bool> BoolNodeMap;                           \
81 81
  typedef Digraph::NodeMap<int> IntNodeMap;                             \
82 82
  typedef Digraph::NodeMap<double> DoubleNodeMap;                       \
83 83
  typedef Digraph::ArcMap<bool> BoolArcMap;                             \
84 84
  typedef Digraph::ArcMap<int> IntArcMap;                               \
85 85
  typedef Digraph::ArcMap<double> DoubleArcMap
86 86

	
87 87
  ///Create convenience typedefs for the digraph types and iterators
88 88

	
89 89
  ///\see DIGRAPH_TYPEDEFS
90 90
  ///
91 91
  ///\note Use this macro, if the graph type is a dependent type,
92 92
  ///ie. the graph type depend on a template parameter.
93 93
#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph)                              \
94 94
  typedef typename Digraph::Node Node;                                  \
95 95
  typedef typename Digraph::NodeIt NodeIt;                              \
96 96
  typedef typename Digraph::Arc Arc;                                    \
97 97
  typedef typename Digraph::ArcIt ArcIt;                                \
98 98
  typedef typename Digraph::InArcIt InArcIt;                            \
99 99
  typedef typename Digraph::OutArcIt OutArcIt;                          \
100 100
  typedef typename Digraph::template NodeMap<bool> BoolNodeMap;         \
101 101
  typedef typename Digraph::template NodeMap<int> IntNodeMap;           \
102 102
  typedef typename Digraph::template NodeMap<double> DoubleNodeMap;     \
103 103
  typedef typename Digraph::template ArcMap<bool> BoolArcMap;           \
104 104
  typedef typename Digraph::template ArcMap<int> IntArcMap;             \
105 105
  typedef typename Digraph::template ArcMap<double> DoubleArcMap
106 106

	
107 107
  ///Create convenience typedefs for the graph types and iterators
108 108

	
109 109
  ///This \c \#define creates the same convenient type definitions as defined
110 110
  ///by \ref DIGRAPH_TYPEDEFS(Graph) and six more, namely it creates
111 111
  ///\c Edge, \c EdgeIt, \c IncEdgeIt, \c BoolEdgeMap, \c IntEdgeMap,
112 112
  ///\c DoubleEdgeMap.
113 113
  ///
114 114
  ///\note If the graph type is a dependent type, ie. the graph type depend
115 115
  ///on a template parameter, then use \c TEMPLATE_GRAPH_TYPEDEFS()
116 116
  ///macro.
117 117
#define GRAPH_TYPEDEFS(Graph)                                           \
118 118
  DIGRAPH_TYPEDEFS(Graph);                                              \
119 119
  typedef Graph::Edge Edge;                                             \
120 120
  typedef Graph::EdgeIt EdgeIt;                                         \
121 121
  typedef Graph::IncEdgeIt IncEdgeIt;                                   \
122 122
  typedef Graph::EdgeMap<bool> BoolEdgeMap;                             \
123 123
  typedef Graph::EdgeMap<int> IntEdgeMap;                               \
124 124
  typedef Graph::EdgeMap<double> DoubleEdgeMap
125 125

	
126 126
  ///Create convenience typedefs for the graph types and iterators
127 127

	
128 128
  ///\see GRAPH_TYPEDEFS
129 129
  ///
130 130
  ///\note Use this macro, if the graph type is a dependent type,
131 131
  ///ie. the graph type depend on a template parameter.
132 132
#define TEMPLATE_GRAPH_TYPEDEFS(Graph)                                  \
133 133
  TEMPLATE_DIGRAPH_TYPEDEFS(Graph);                                     \
134 134
  typedef typename Graph::Edge Edge;                                    \
135 135
  typedef typename Graph::EdgeIt EdgeIt;                                \
136 136
  typedef typename Graph::IncEdgeIt IncEdgeIt;                          \
137 137
  typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;           \
138 138
  typedef typename Graph::template EdgeMap<int> IntEdgeMap;             \
139 139
  typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
140 140

	
141 141
  /// \brief Function to count the items in a graph.
142 142
  ///
143 143
  /// This function counts the items (nodes, arcs etc.) in a graph.
144 144
  /// The complexity of the function is linear because
145 145
  /// it iterates on all of the items.
146 146
  template <typename Graph, typename Item>
147 147
  inline int countItems(const Graph& g) {
148 148
    typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
149 149
    int num = 0;
150 150
    for (ItemIt it(g); it != INVALID; ++it) {
151 151
      ++num;
152 152
    }
153 153
    return num;
154 154
  }
155 155

	
156 156
  // Node counting:
157 157

	
158 158
  namespace _core_bits {
159 159

	
160 160
    template <typename Graph, typename Enable = void>
161 161
    struct CountNodesSelector {
162 162
      static int count(const Graph &g) {
163 163
        return countItems<Graph, typename Graph::Node>(g);
164 164
      }
165 165
    };
166 166

	
167 167
    template <typename Graph>
168 168
    struct CountNodesSelector<
169 169
      Graph, typename
170 170
      enable_if<typename Graph::NodeNumTag, void>::type>
171 171
    {
172 172
      static int count(const Graph &g) {
173 173
        return g.nodeNum();
174 174
      }
175 175
    };
176 176
  }
177 177

	
178 178
  /// \brief Function to count the nodes in the graph.
179 179
  ///
180 180
  /// This function counts the nodes in the graph.
181 181
  /// The complexity of the function is <em>O</em>(<em>n</em>), but for some
182 182
  /// graph structures it is specialized to run in <em>O</em>(1).
183 183
  ///
184 184
  /// \note If the graph contains a \c nodeNum() member function and a
185 185
  /// \c NodeNumTag tag then this function calls directly the member
186 186
  /// function to query the cardinality of the node set.
187 187
  template <typename Graph>
188 188
  inline int countNodes(const Graph& g) {
189 189
    return _core_bits::CountNodesSelector<Graph>::count(g);
190 190
  }
191 191

	
192 192
  // Arc counting:
193 193

	
194 194
  namespace _core_bits {
195 195

	
196 196
    template <typename Graph, typename Enable = void>
197 197
    struct CountArcsSelector {
198 198
      static int count(const Graph &g) {
199 199
        return countItems<Graph, typename Graph::Arc>(g);
200 200
      }
201 201
    };
202 202

	
203 203
    template <typename Graph>
204 204
    struct CountArcsSelector<
205 205
      Graph,
206 206
      typename enable_if<typename Graph::ArcNumTag, void>::type>
207 207
    {
208 208
      static int count(const Graph &g) {
209 209
        return g.arcNum();
210 210
      }
211 211
    };
212 212
  }
213 213

	
214 214
  /// \brief Function to count the arcs in the graph.
215 215
  ///
216 216
  /// This function counts the arcs in the graph.
217 217
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
218 218
  /// graph structures it is specialized to run in <em>O</em>(1).
219 219
  ///
220 220
  /// \note If the graph contains a \c arcNum() member function and a
221 221
  /// \c ArcNumTag tag then this function calls directly the member
222 222
  /// function to query the cardinality of the arc set.
223 223
  template <typename Graph>
224 224
  inline int countArcs(const Graph& g) {
225 225
    return _core_bits::CountArcsSelector<Graph>::count(g);
226 226
  }
227 227

	
228 228
  // Edge counting:
229 229

	
230 230
  namespace _core_bits {
231 231

	
232 232
    template <typename Graph, typename Enable = void>
233 233
    struct CountEdgesSelector {
234 234
      static int count(const Graph &g) {
235 235
        return countItems<Graph, typename Graph::Edge>(g);
236 236
      }
237 237
    };
238 238

	
239 239
    template <typename Graph>
240 240
    struct CountEdgesSelector<
241 241
      Graph,
242 242
      typename enable_if<typename Graph::EdgeNumTag, void>::type>
243 243
    {
244 244
      static int count(const Graph &g) {
245 245
        return g.edgeNum();
246 246
      }
247 247
    };
248 248
  }
249 249

	
250 250
  /// \brief Function to count the edges in the graph.
251 251
  ///
252 252
  /// This function counts the edges in the graph.
253 253
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
254 254
  /// graph structures it is specialized to run in <em>O</em>(1).
255 255
  ///
256 256
  /// \note If the graph contains a \c edgeNum() member function and a
257 257
  /// \c EdgeNumTag tag then this function calls directly the member
258 258
  /// function to query the cardinality of the edge set.
259 259
  template <typename Graph>
260 260
  inline int countEdges(const Graph& g) {
261 261
    return _core_bits::CountEdgesSelector<Graph>::count(g);
262 262

	
263 263
  }
264 264

	
265 265

	
266 266
  template <typename Graph, typename DegIt>
267 267
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
268 268
    int num = 0;
269 269
    for (DegIt it(_g, _n); it != INVALID; ++it) {
270 270
      ++num;
271 271
    }
272 272
    return num;
273 273
  }
274 274

	
275 275
  /// \brief Function to count the number of the out-arcs from node \c n.
276 276
  ///
277 277
  /// This function counts the number of the out-arcs from node \c n
278 278
  /// in the graph \c g.
279 279
  template <typename Graph>
280 280
  inline int countOutArcs(const Graph& g,  const typename Graph::Node& n) {
281 281
    return countNodeDegree<Graph, typename Graph::OutArcIt>(g, n);
282 282
  }
283 283

	
284 284
  /// \brief Function to count the number of the in-arcs to node \c n.
285 285
  ///
286 286
  /// This function counts the number of the in-arcs to node \c n
287 287
  /// in the graph \c g.
288 288
  template <typename Graph>
289 289
  inline int countInArcs(const Graph& g,  const typename Graph::Node& n) {
290 290
    return countNodeDegree<Graph, typename Graph::InArcIt>(g, n);
291 291
  }
292 292

	
293 293
  /// \brief Function to count the number of the inc-edges to node \c n.
294 294
  ///
295 295
  /// This function counts the number of the inc-edges to node \c n
296 296
  /// in the undirected graph \c g.
297 297
  template <typename Graph>
298 298
  inline int countIncEdges(const Graph& g,  const typename Graph::Node& n) {
299 299
    return countNodeDegree<Graph, typename Graph::IncEdgeIt>(g, n);
300 300
  }
301 301

	
302 302
  namespace _core_bits {
303 303

	
304 304
    template <typename Digraph, typename Item, typename RefMap>
305 305
    class MapCopyBase {
306 306
    public:
307 307
      virtual void copy(const Digraph& from, const RefMap& refMap) = 0;
308 308

	
309 309
      virtual ~MapCopyBase() {}
310 310
    };
311 311

	
312 312
    template <typename Digraph, typename Item, typename RefMap,
313 313
              typename FromMap, typename ToMap>
314 314
    class MapCopy : public MapCopyBase<Digraph, Item, RefMap> {
315 315
    public:
316 316

	
317 317
      MapCopy(const FromMap& map, ToMap& tmap)
318 318
        : _map(map), _tmap(tmap) {}
319 319

	
320 320
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
321 321
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
322 322
        for (ItemIt it(digraph); it != INVALID; ++it) {
323 323
          _tmap.set(refMap[it], _map[it]);
324 324
        }
325 325
      }
326 326

	
327 327
    private:
328 328
      const FromMap& _map;
329 329
      ToMap& _tmap;
330 330
    };
331 331

	
332 332
    template <typename Digraph, typename Item, typename RefMap, typename It>
333 333
    class ItemCopy : public MapCopyBase<Digraph, Item, RefMap> {
334 334
    public:
335 335

	
336 336
      ItemCopy(const Item& item, It& it) : _item(item), _it(it) {}
337 337

	
338 338
      virtual void copy(const Digraph&, const RefMap& refMap) {
339 339
        _it = refMap[_item];
340 340
      }
341 341

	
342 342
    private:
343 343
      Item _item;
344 344
      It& _it;
345 345
    };
346 346

	
347 347
    template <typename Digraph, typename Item, typename RefMap, typename Ref>
348 348
    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
349 349
    public:
350 350

	
351 351
      RefCopy(Ref& map) : _map(map) {}
352 352

	
353 353
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
354 354
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
355 355
        for (ItemIt it(digraph); it != INVALID; ++it) {
356 356
          _map.set(it, refMap[it]);
357 357
        }
358 358
      }
359 359

	
360 360
    private:
361 361
      Ref& _map;
362 362
    };
363 363

	
364 364
    template <typename Digraph, typename Item, typename RefMap,
365 365
              typename CrossRef>
366 366
    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
367 367
    public:
368 368

	
369 369
      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
370 370

	
371 371
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
372 372
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
373 373
        for (ItemIt it(digraph); it != INVALID; ++it) {
374 374
          _cmap.set(refMap[it], it);
375 375
        }
376 376
      }
377 377

	
378 378
    private:
379 379
      CrossRef& _cmap;
380 380
    };
381 381

	
382 382
    template <typename Digraph, typename Enable = void>
383 383
    struct DigraphCopySelector {
384 384
      template <typename From, typename NodeRefMap, typename ArcRefMap>
385 385
      static void copy(const From& from, Digraph &to,
386 386
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
387 387
        to.clear();
388 388
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
389 389
          nodeRefMap[it] = to.addNode();
390 390
        }
391 391
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
392 392
          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
393 393
                                    nodeRefMap[from.target(it)]);
394 394
        }
395 395
      }
396 396
    };
397 397

	
398 398
    template <typename Digraph>
399 399
    struct DigraphCopySelector<
400 400
      Digraph,
401 401
      typename enable_if<typename Digraph::BuildTag, void>::type>
402 402
    {
403 403
      template <typename From, typename NodeRefMap, typename ArcRefMap>
404 404
      static void copy(const From& from, Digraph &to,
405 405
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
406 406
        to.build(from, nodeRefMap, arcRefMap);
407 407
      }
408 408
    };
409 409

	
410 410
    template <typename Graph, typename Enable = void>
411 411
    struct GraphCopySelector {
412 412
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
413 413
      static void copy(const From& from, Graph &to,
414 414
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
415 415
        to.clear();
416 416
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
417 417
          nodeRefMap[it] = to.addNode();
418 418
        }
419 419
        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
420 420
          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
421 421
                                      nodeRefMap[from.v(it)]);
422 422
        }
423 423
      }
424 424
    };
425 425

	
426 426
    template <typename Graph>
427 427
    struct GraphCopySelector<
428 428
      Graph,
429 429
      typename enable_if<typename Graph::BuildTag, void>::type>
430 430
    {
431 431
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
432 432
      static void copy(const From& from, Graph &to,
433 433
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
434 434
        to.build(from, nodeRefMap, edgeRefMap);
435 435
      }
436 436
    };
437 437

	
438 438
  }
439 439

	
440 440
  /// \brief Class to copy a digraph.
441 441
  ///
442 442
  /// Class to copy a digraph to another digraph (duplicate a digraph). The
443 443
  /// simplest way of using it is through the \c digraphCopy() function.
444 444
  ///
445 445
  /// This class not only make a copy of a digraph, but it can create
446 446
  /// references and cross references between the nodes and arcs of
447 447
  /// the two digraphs, and it can copy maps to use with the newly created
448 448
  /// digraph.
449 449
  ///
450 450
  /// To make a copy from a digraph, first an instance of DigraphCopy
451 451
  /// should be created, then the data belongs to the digraph should
452 452
  /// assigned to copy. In the end, the \c run() member should be
453 453
  /// called.
454 454
  ///
455 455
  /// The next code copies a digraph with several data:
456 456
  ///\code
457 457
  ///  DigraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
458 458
  ///  // Create references for the nodes
459 459
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
460 460
  ///  cg.nodeRef(nr);
461 461
  ///  // Create cross references (inverse) for the arcs
462 462
  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
463 463
  ///  cg.arcCrossRef(acr);
464 464
  ///  // Copy an arc map
465 465
  ///  OrigGraph::ArcMap<double> oamap(orig_graph);
466 466
  ///  NewGraph::ArcMap<double> namap(new_graph);
467 467
  ///  cg.arcMap(oamap, namap);
468 468
  ///  // Copy a node
469 469
  ///  OrigGraph::Node on;
470 470
  ///  NewGraph::Node nn;
471 471
  ///  cg.node(on, nn);
472 472
  ///  // Execute copying
473 473
  ///  cg.run();
474 474
  ///\endcode
475 475
  template <typename From, typename To>
476 476
  class DigraphCopy {
477 477
  private:
478 478

	
479 479
    typedef typename From::Node Node;
480 480
    typedef typename From::NodeIt NodeIt;
481 481
    typedef typename From::Arc Arc;
482 482
    typedef typename From::ArcIt ArcIt;
483 483

	
484 484
    typedef typename To::Node TNode;
485 485
    typedef typename To::Arc TArc;
486 486

	
487 487
    typedef typename From::template NodeMap<TNode> NodeRefMap;
488 488
    typedef typename From::template ArcMap<TArc> ArcRefMap;
489 489

	
490 490
  public:
491 491

	
492 492
    /// \brief Constructor of DigraphCopy.
493 493
    ///
494 494
    /// Constructor of DigraphCopy for copying the content of the
495 495
    /// \c from digraph into the \c to digraph.
496 496
    DigraphCopy(const From& from, To& to)
497 497
      : _from(from), _to(to) {}
498 498

	
499 499
    /// \brief Destructor of DigraphCopy
500 500
    ///
501 501
    /// Destructor of DigraphCopy.
502 502
    ~DigraphCopy() {
503 503
      for (int i = 0; i < int(_node_maps.size()); ++i) {
504 504
        delete _node_maps[i];
505 505
      }
506 506
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
507 507
        delete _arc_maps[i];
508 508
      }
509 509

	
510 510
    }
511 511

	
512 512
    /// \brief Copy the node references into the given map.
513 513
    ///
514 514
    /// This function copies the node references into the given map.
515 515
    /// The parameter should be a map, whose key type is the Node type of
516 516
    /// the source digraph, while the value type is the Node type of the
517 517
    /// destination digraph.
518 518
    template <typename NodeRef>
519 519
    DigraphCopy& nodeRef(NodeRef& map) {
520 520
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
521 521
                           NodeRefMap, NodeRef>(map));
522 522
      return *this;
523 523
    }
524 524

	
525 525
    /// \brief Copy the node cross references into the given map.
526 526
    ///
527 527
    /// This function copies the node cross references (reverse references)
528 528
    /// into the given map. The parameter should be a map, whose key type
529 529
    /// is the Node type of the destination digraph, while the value type is
530 530
    /// the Node type of the source digraph.
531 531
    template <typename NodeCrossRef>
532 532
    DigraphCopy& nodeCrossRef(NodeCrossRef& map) {
533 533
      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
534 534
                           NodeRefMap, NodeCrossRef>(map));
535 535
      return *this;
536 536
    }
537 537

	
538 538
    /// \brief Make a copy of the given node map.
539 539
    ///
540 540
    /// This function makes a copy of the given node map for the newly
541 541
    /// created digraph.
542 542
    /// The key type of the new map \c tmap should be the Node type of the
543 543
    /// destination digraph, and the key type of the original map \c map
544 544
    /// should be the Node type of the source digraph.
545 545
    template <typename FromMap, typename ToMap>
546 546
    DigraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
547 547
      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
548 548
                           NodeRefMap, FromMap, ToMap>(map, tmap));
549 549
      return *this;
550 550
    }
551 551

	
552 552
    /// \brief Make a copy of the given node.
553 553
    ///
554 554
    /// This function makes a copy of the given node.
555 555
    DigraphCopy& node(const Node& node, TNode& tnode) {
556 556
      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
557 557
                           NodeRefMap, TNode>(node, tnode));
558 558
      return *this;
559 559
    }
560 560

	
561 561
    /// \brief Copy the arc references into the given map.
562 562
    ///
563 563
    /// This function copies the arc references into the given map.
564 564
    /// The parameter should be a map, whose key type is the Arc type of
565 565
    /// the source digraph, while the value type is the Arc type of the
566 566
    /// destination digraph.
567 567
    template <typename ArcRef>
568 568
    DigraphCopy& arcRef(ArcRef& map) {
569 569
      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
570 570
                          ArcRefMap, ArcRef>(map));
571 571
      return *this;
572 572
    }
573 573

	
574 574
    /// \brief Copy the arc cross references into the given map.
575 575
    ///
576 576
    /// This function copies the arc cross references (reverse references)
577 577
    /// into the given map. The parameter should be a map, whose key type
578 578
    /// is the Arc type of the destination digraph, while the value type is
579 579
    /// the Arc type of the source digraph.
580 580
    template <typename ArcCrossRef>
581 581
    DigraphCopy& arcCrossRef(ArcCrossRef& map) {
582 582
      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
583 583
                          ArcRefMap, ArcCrossRef>(map));
584 584
      return *this;
585 585
    }
586 586

	
587 587
    /// \brief Make a copy of the given arc map.
588 588
    ///
589 589
    /// This function makes a copy of the given arc map for the newly
590 590
    /// created digraph.
591 591
    /// The key type of the new map \c tmap should be the Arc type of the
592 592
    /// destination digraph, and the key type of the original map \c map
593 593
    /// should be the Arc type of the source digraph.
594 594
    template <typename FromMap, typename ToMap>
595 595
    DigraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
596 596
      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
597 597
                          ArcRefMap, FromMap, ToMap>(map, tmap));
598 598
      return *this;
599 599
    }
600 600

	
601 601
    /// \brief Make a copy of the given arc.
602 602
    ///
603 603
    /// This function makes a copy of the given arc.
604 604
    DigraphCopy& arc(const Arc& arc, TArc& tarc) {
605 605
      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
606 606
                          ArcRefMap, TArc>(arc, tarc));
607 607
      return *this;
608 608
    }
609 609

	
610 610
    /// \brief Execute copying.
611 611
    ///
612 612
    /// This function executes the copying of the digraph along with the
613 613
    /// copying of the assigned data.
614 614
    void run() {
615 615
      NodeRefMap nodeRefMap(_from);
616 616
      ArcRefMap arcRefMap(_from);
617 617
      _core_bits::DigraphCopySelector<To>::
618 618
        copy(_from, _to, nodeRefMap, arcRefMap);
619 619
      for (int i = 0; i < int(_node_maps.size()); ++i) {
620 620
        _node_maps[i]->copy(_from, nodeRefMap);
621 621
      }
622 622
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
623 623
        _arc_maps[i]->copy(_from, arcRefMap);
624 624
      }
625 625
    }
626 626

	
627 627
  protected:
628 628

	
629 629
    const From& _from;
630 630
    To& _to;
631 631

	
632 632
    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
633 633
      _node_maps;
634 634

	
635 635
    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
636 636
      _arc_maps;
637 637

	
638 638
  };
639 639

	
640 640
  /// \brief Copy a digraph to another digraph.
641 641
  ///
642 642
  /// This function copies a digraph to another digraph.
643 643
  /// The complete usage of it is detailed in the DigraphCopy class, but
644 644
  /// a short example shows a basic work:
645 645
  ///\code
646 646
  /// digraphCopy(src, trg).nodeRef(nr).arcCrossRef(acr).run();
647 647
  ///\endcode
648 648
  ///
649 649
  /// After the copy the \c nr map will contain the mapping from the
650 650
  /// nodes of the \c from digraph to the nodes of the \c to digraph and
651 651
  /// \c acr will contain the mapping from the arcs of the \c to digraph
652 652
  /// to the arcs of the \c from digraph.
653 653
  ///
654 654
  /// \see DigraphCopy
655 655
  template <typename From, typename To>
656 656
  DigraphCopy<From, To> digraphCopy(const From& from, To& to) {
657 657
    return DigraphCopy<From, To>(from, to);
658 658
  }
659 659

	
660 660
  /// \brief Class to copy a graph.
661 661
  ///
662 662
  /// Class to copy a graph to another graph (duplicate a graph). The
663 663
  /// simplest way of using it is through the \c graphCopy() function.
664 664
  ///
665 665
  /// This class not only make a copy of a graph, but it can create
666 666
  /// references and cross references between the nodes, edges and arcs of
667 667
  /// the two graphs, and it can copy maps for using with the newly created
668 668
  /// graph.
669 669
  ///
670 670
  /// To make a copy from a graph, first an instance of GraphCopy
671 671
  /// should be created, then the data belongs to the graph should
672 672
  /// assigned to copy. In the end, the \c run() member should be
673 673
  /// called.
674 674
  ///
675 675
  /// The next code copies a graph with several data:
676 676
  ///\code
677 677
  ///  GraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
678 678
  ///  // Create references for the nodes
679 679
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
680 680
  ///  cg.nodeRef(nr);
681 681
  ///  // Create cross references (inverse) for the edges
682 682
  ///  NewGraph::EdgeMap<OrigGraph::Edge> ecr(new_graph);
683 683
  ///  cg.edgeCrossRef(ecr);
684 684
  ///  // Copy an edge map
685 685
  ///  OrigGraph::EdgeMap<double> oemap(orig_graph);
686 686
  ///  NewGraph::EdgeMap<double> nemap(new_graph);
687 687
  ///  cg.edgeMap(oemap, nemap);
688 688
  ///  // Copy a node
689 689
  ///  OrigGraph::Node on;
690 690
  ///  NewGraph::Node nn;
691 691
  ///  cg.node(on, nn);
692 692
  ///  // Execute copying
693 693
  ///  cg.run();
694 694
  ///\endcode
695 695
  template <typename From, typename To>
696 696
  class GraphCopy {
697 697
  private:
698 698

	
699 699
    typedef typename From::Node Node;
700 700
    typedef typename From::NodeIt NodeIt;
701 701
    typedef typename From::Arc Arc;
702 702
    typedef typename From::ArcIt ArcIt;
703 703
    typedef typename From::Edge Edge;
704 704
    typedef typename From::EdgeIt EdgeIt;
705 705

	
706 706
    typedef typename To::Node TNode;
707 707
    typedef typename To::Arc TArc;
708 708
    typedef typename To::Edge TEdge;
709 709

	
710 710
    typedef typename From::template NodeMap<TNode> NodeRefMap;
711 711
    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
712 712

	
713 713
    struct ArcRefMap {
714 714
      ArcRefMap(const From& from, const To& to,
715 715
                const EdgeRefMap& edge_ref, const NodeRefMap& node_ref)
716 716
        : _from(from), _to(to),
717 717
          _edge_ref(edge_ref), _node_ref(node_ref) {}
718 718

	
719 719
      typedef typename From::Arc Key;
720 720
      typedef typename To::Arc Value;
721 721

	
722 722
      Value operator[](const Key& key) const {
723 723
        bool forward = _from.u(key) != _from.v(key) ?
724 724
          _node_ref[_from.source(key)] ==
725 725
          _to.source(_to.direct(_edge_ref[key], true)) :
726 726
          _from.direction(key);
727 727
        return _to.direct(_edge_ref[key], forward);
728 728
      }
729 729

	
730 730
      const From& _from;
731 731
      const To& _to;
732 732
      const EdgeRefMap& _edge_ref;
733 733
      const NodeRefMap& _node_ref;
734 734
    };
735 735

	
736 736
  public:
737 737

	
738 738
    /// \brief Constructor of GraphCopy.
739 739
    ///
740 740
    /// Constructor of GraphCopy for copying the content of the
741 741
    /// \c from graph into the \c to graph.
742 742
    GraphCopy(const From& from, To& to)
743 743
      : _from(from), _to(to) {}
744 744

	
745 745
    /// \brief Destructor of GraphCopy
746 746
    ///
747 747
    /// Destructor of GraphCopy.
748 748
    ~GraphCopy() {
749 749
      for (int i = 0; i < int(_node_maps.size()); ++i) {
750 750
        delete _node_maps[i];
751 751
      }
752 752
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
753 753
        delete _arc_maps[i];
754 754
      }
755 755
      for (int i = 0; i < int(_edge_maps.size()); ++i) {
756 756
        delete _edge_maps[i];
757 757
      }
758 758
    }
759 759

	
760 760
    /// \brief Copy the node references into the given map.
761 761
    ///
762 762
    /// This function copies the node references into the given map.
763 763
    /// The parameter should be a map, whose key type is the Node type of
764 764
    /// the source graph, while the value type is the Node type of the
765 765
    /// destination graph.
766 766
    template <typename NodeRef>
767 767
    GraphCopy& nodeRef(NodeRef& map) {
768 768
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
769 769
                           NodeRefMap, NodeRef>(map));
770 770
      return *this;
771 771
    }
772 772

	
773 773
    /// \brief Copy the node cross references into the given map.
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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_DFS_H
20 20
#define LEMON_DFS_H
21 21

	
22 22
///\ingroup search
23 23
///\file
24 24
///\brief DFS algorithm.
25 25

	
26 26
#include <lemon/list_graph.h>
27 27
#include <lemon/bits/path_dump.h>
28 28
#include <lemon/core.h>
29 29
#include <lemon/error.h>
30 30
#include <lemon/maps.h>
31 31
#include <lemon/path.h>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  ///Default traits class of Dfs class.
36 36

	
37 37
  ///Default traits class of Dfs class.
38 38
  ///\tparam GR Digraph type.
39 39
  template<class GR>
40 40
  struct DfsDefaultTraits
41 41
  {
42 42
    ///The type of the digraph the algorithm runs on.
43 43
    typedef GR Digraph;
44 44

	
45 45
    ///\brief The type of the map that stores the predecessor
46 46
    ///arcs of the %DFS paths.
47 47
    ///
48 48
    ///The type of the map that stores the predecessor
49 49
    ///arcs of the %DFS paths.
50 50
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
51 51
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
52 52
    ///Instantiates a PredMap.
53 53

	
54 54
    ///This function instantiates a PredMap.
55 55
    ///\param g is the digraph, to which we would like to define the
56 56
    ///PredMap.
57 57
    static PredMap *createPredMap(const Digraph &g)
58 58
    {
59 59
      return new PredMap(g);
60 60
    }
61 61

	
62 62
    ///The type of the map that indicates which nodes are processed.
63 63

	
64 64
    ///The type of the map that indicates which nodes are processed.
65 65
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
66 66
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
67 67
    ///Instantiates a ProcessedMap.
68 68

	
69 69
    ///This function instantiates a ProcessedMap.
70 70
    ///\param g is the digraph, to which
71 71
    ///we would like to define the ProcessedMap
72 72
#ifdef DOXYGEN
73 73
    static ProcessedMap *createProcessedMap(const Digraph &g)
74 74
#else
75 75
    static ProcessedMap *createProcessedMap(const Digraph &)
76 76
#endif
77 77
    {
78 78
      return new ProcessedMap();
79 79
    }
80 80

	
81 81
    ///The type of the map that indicates which nodes are reached.
82 82

	
83 83
    ///The type of the map that indicates which nodes are reached.
84 84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 85
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86 86
    ///Instantiates a ReachedMap.
87 87

	
88 88
    ///This function instantiates a ReachedMap.
89 89
    ///\param g is the digraph, to which
90 90
    ///we would like to define the ReachedMap.
91 91
    static ReachedMap *createReachedMap(const Digraph &g)
92 92
    {
93 93
      return new ReachedMap(g);
94 94
    }
95 95

	
96 96
    ///The type of the map that stores the distances of the nodes.
97 97

	
98 98
    ///The type of the map that stores the distances of the nodes.
99 99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
100 100
    typedef typename Digraph::template NodeMap<int> DistMap;
101 101
    ///Instantiates a DistMap.
102 102

	
103 103
    ///This function instantiates a DistMap.
104 104
    ///\param g is the digraph, to which we would like to define the
105 105
    ///DistMap.
106 106
    static DistMap *createDistMap(const Digraph &g)
107 107
    {
108 108
      return new DistMap(g);
109 109
    }
110 110
  };
111 111

	
112 112
  ///%DFS algorithm class.
113 113

	
114 114
  ///\ingroup search
115 115
  ///This class provides an efficient implementation of the %DFS algorithm.
116 116
  ///
117 117
  ///There is also a \ref dfs() "function-type interface" for the DFS
118 118
  ///algorithm, which is convenient in the simplier cases and it can be
119 119
  ///used easier.
120 120
  ///
121 121
  ///\tparam GR The type of the digraph the algorithm runs on.
122 122
  ///The default value is \ref ListDigraph. The value of GR is not used
123 123
  ///directly by \ref Dfs, it is only passed to \ref DfsDefaultTraits.
124 124
  ///\tparam TR Traits class to set various data types used by the algorithm.
125 125
  ///The default traits class is
126 126
  ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
127 127
  ///See \ref DfsDefaultTraits for the documentation of
128 128
  ///a Dfs traits class.
129 129
#ifdef DOXYGEN
130 130
  template <typename GR,
131 131
            typename TR>
132 132
#else
133 133
  template <typename GR=ListDigraph,
134 134
            typename TR=DfsDefaultTraits<GR> >
135 135
#endif
136 136
  class Dfs {
137 137
  public:
138 138

	
139 139
    ///The type of the digraph the algorithm runs on.
140 140
    typedef typename TR::Digraph Digraph;
141 141

	
142 142
    ///\brief The type of the map that stores the predecessor arcs of the
143 143
    ///DFS paths.
144 144
    typedef typename TR::PredMap PredMap;
145 145
    ///The type of the map that stores the distances of the nodes.
146 146
    typedef typename TR::DistMap DistMap;
147 147
    ///The type of the map that indicates which nodes are reached.
148 148
    typedef typename TR::ReachedMap ReachedMap;
149 149
    ///The type of the map that indicates which nodes are processed.
150 150
    typedef typename TR::ProcessedMap ProcessedMap;
151 151
    ///The type of the paths.
152 152
    typedef PredMapPath<Digraph, PredMap> Path;
153 153

	
154 154
    ///The traits class.
155 155
    typedef TR Traits;
156 156

	
157 157
  private:
158 158

	
159 159
    typedef typename Digraph::Node Node;
160 160
    typedef typename Digraph::NodeIt NodeIt;
161 161
    typedef typename Digraph::Arc Arc;
162 162
    typedef typename Digraph::OutArcIt OutArcIt;
163 163

	
164 164
    //Pointer to the underlying digraph.
165 165
    const Digraph *G;
166 166
    //Pointer to the map of predecessor arcs.
167 167
    PredMap *_pred;
168 168
    //Indicates if _pred is locally allocated (true) or not.
169 169
    bool local_pred;
170 170
    //Pointer to the map of distances.
171 171
    DistMap *_dist;
172 172
    //Indicates if _dist is locally allocated (true) or not.
173 173
    bool local_dist;
174 174
    //Pointer to the map of reached status of the nodes.
175 175
    ReachedMap *_reached;
176 176
    //Indicates if _reached is locally allocated (true) or not.
177 177
    bool local_reached;
178 178
    //Pointer to the map of processed status of the nodes.
179 179
    ProcessedMap *_processed;
180 180
    //Indicates if _processed is locally allocated (true) or not.
181 181
    bool local_processed;
182 182

	
183 183
    std::vector<typename Digraph::OutArcIt> _stack;
184 184
    int _stack_head;
185 185

	
186 186
    //Creates the maps if necessary.
187 187
    void create_maps()
188 188
    {
189 189
      if(!_pred) {
190 190
        local_pred = true;
191 191
        _pred = Traits::createPredMap(*G);
192 192
      }
193 193
      if(!_dist) {
194 194
        local_dist = true;
195 195
        _dist = Traits::createDistMap(*G);
196 196
      }
197 197
      if(!_reached) {
198 198
        local_reached = true;
199 199
        _reached = Traits::createReachedMap(*G);
200 200
      }
201 201
      if(!_processed) {
202 202
        local_processed = true;
203 203
        _processed = Traits::createProcessedMap(*G);
204 204
      }
205 205
    }
206 206

	
207 207
  protected:
208 208

	
209 209
    Dfs() {}
210 210

	
211 211
  public:
212 212

	
213 213
    typedef Dfs Create;
214 214

	
215 215
    ///\name Named template parameters
216 216

	
217 217
    ///@{
218 218

	
219 219
    template <class T>
220 220
    struct SetPredMapTraits : public Traits {
221 221
      typedef T PredMap;
222 222
      static PredMap *createPredMap(const Digraph &)
223 223
      {
224 224
        LEMON_ASSERT(false, "PredMap is not initialized");
225 225
        return 0; // ignore warnings
226 226
      }
227 227
    };
228 228
    ///\brief \ref named-templ-param "Named parameter" for setting
229 229
    ///PredMap type.
230 230
    ///
231 231
    ///\ref named-templ-param "Named parameter" for setting
232 232
    ///PredMap type.
233 233
    template <class T>
234 234
    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
235 235
      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
236 236
    };
237 237

	
238 238
    template <class T>
239 239
    struct SetDistMapTraits : public Traits {
240 240
      typedef T DistMap;
241 241
      static DistMap *createDistMap(const Digraph &)
242 242
      {
243 243
        LEMON_ASSERT(false, "DistMap is not initialized");
244 244
        return 0; // ignore warnings
245 245
      }
246 246
    };
247 247
    ///\brief \ref named-templ-param "Named parameter" for setting
248 248
    ///DistMap type.
249 249
    ///
250 250
    ///\ref named-templ-param "Named parameter" for setting
251 251
    ///DistMap type.
252 252
    template <class T>
253 253
    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
254 254
      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
255 255
    };
256 256

	
257 257
    template <class T>
258 258
    struct SetReachedMapTraits : public Traits {
259 259
      typedef T ReachedMap;
260 260
      static ReachedMap *createReachedMap(const Digraph &)
261 261
      {
262 262
        LEMON_ASSERT(false, "ReachedMap is not initialized");
263 263
        return 0; // ignore warnings
264 264
      }
265 265
    };
266 266
    ///\brief \ref named-templ-param "Named parameter" for setting
267 267
    ///ReachedMap type.
268 268
    ///
269 269
    ///\ref named-templ-param "Named parameter" for setting
270 270
    ///ReachedMap type.
271 271
    template <class T>
272 272
    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
273 273
      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
274 274
    };
275 275

	
276 276
    template <class T>
277 277
    struct SetProcessedMapTraits : public Traits {
278 278
      typedef T ProcessedMap;
279 279
      static ProcessedMap *createProcessedMap(const Digraph &)
280 280
      {
281 281
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
282 282
        return 0; // ignore warnings
283 283
      }
284 284
    };
285 285
    ///\brief \ref named-templ-param "Named parameter" for setting
286 286
    ///ProcessedMap type.
287 287
    ///
288 288
    ///\ref named-templ-param "Named parameter" for setting
289 289
    ///ProcessedMap type.
290 290
    template <class T>
291 291
    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
292 292
      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
293 293
    };
294 294

	
295 295
    struct SetStandardProcessedMapTraits : public Traits {
296 296
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
297 297
      static ProcessedMap *createProcessedMap(const Digraph &g)
298 298
      {
299 299
        return new ProcessedMap(g);
300 300
      }
301 301
    };
302 302
    ///\brief \ref named-templ-param "Named parameter" for setting
303 303
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
304 304
    ///
305 305
    ///\ref named-templ-param "Named parameter" for setting
306 306
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
307 307
    ///If you don't set it explicitly, it will be automatically allocated.
308 308
    struct SetStandardProcessedMap :
309 309
      public Dfs< Digraph, SetStandardProcessedMapTraits > {
310 310
      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
311 311
    };
312 312

	
313 313
    ///@}
314 314

	
315 315
  public:
316 316

	
317 317
    ///Constructor.
318 318

	
319 319
    ///Constructor.
320 320
    ///\param g The digraph the algorithm runs on.
321 321
    Dfs(const Digraph &g) :
322 322
      G(&g),
323 323
      _pred(NULL), local_pred(false),
324 324
      _dist(NULL), local_dist(false),
325 325
      _reached(NULL), local_reached(false),
326 326
      _processed(NULL), local_processed(false)
327 327
    { }
328 328

	
329 329
    ///Destructor.
330 330
    ~Dfs()
331 331
    {
332 332
      if(local_pred) delete _pred;
333 333
      if(local_dist) delete _dist;
334 334
      if(local_reached) delete _reached;
335 335
      if(local_processed) delete _processed;
336 336
    }
337 337

	
338 338
    ///Sets the map that stores the predecessor arcs.
339 339

	
340 340
    ///Sets the map that stores the predecessor arcs.
341 341
    ///If you don't use this function before calling \ref run(),
342 342
    ///it will allocate one. The destructor deallocates this
343 343
    ///automatically allocated map, of course.
344 344
    ///\return <tt> (*this) </tt>
345 345
    Dfs &predMap(PredMap &m)
346 346
    {
347 347
      if(local_pred) {
348 348
        delete _pred;
349 349
        local_pred=false;
350 350
      }
351 351
      _pred = &m;
352 352
      return *this;
353 353
    }
354 354

	
355 355
    ///Sets the map that indicates which nodes are reached.
356 356

	
357 357
    ///Sets the map that indicates which nodes are reached.
358 358
    ///If you don't use this function before calling \ref run(),
359 359
    ///it will allocate one. The destructor deallocates this
360 360
    ///automatically allocated map, of course.
361 361
    ///\return <tt> (*this) </tt>
362 362
    Dfs &reachedMap(ReachedMap &m)
363 363
    {
364 364
      if(local_reached) {
365 365
        delete _reached;
366 366
        local_reached=false;
367 367
      }
368 368
      _reached = &m;
369 369
      return *this;
370 370
    }
371 371

	
372 372
    ///Sets the map that indicates which nodes are processed.
373 373

	
374 374
    ///Sets the map that indicates which nodes are processed.
375 375
    ///If you don't use this function before calling \ref run(),
376 376
    ///it will allocate one. The destructor deallocates this
377 377
    ///automatically allocated map, of course.
378 378
    ///\return <tt> (*this) </tt>
379 379
    Dfs &processedMap(ProcessedMap &m)
380 380
    {
381 381
      if(local_processed) {
382 382
        delete _processed;
383 383
        local_processed=false;
384 384
      }
385 385
      _processed = &m;
386 386
      return *this;
387 387
    }
388 388

	
389 389
    ///Sets the map that stores the distances of the nodes.
390 390

	
391 391
    ///Sets the map that stores the distances of the nodes calculated by
392 392
    ///the algorithm.
393 393
    ///If you don't use this function before calling \ref run(),
394 394
    ///it will allocate one. The destructor deallocates this
395 395
    ///automatically allocated map, of course.
396 396
    ///\return <tt> (*this) </tt>
397 397
    Dfs &distMap(DistMap &m)
398 398
    {
399 399
      if(local_dist) {
400 400
        delete _dist;
401 401
        local_dist=false;
402 402
      }
403 403
      _dist = &m;
404 404
      return *this;
405 405
    }
406 406

	
407 407
  public:
408 408

	
409 409
    ///\name Execution control
410 410
    ///The simplest way to execute the algorithm is to use
411 411
    ///one of the member functions called \ref lemon::Dfs::run() "run()".
412 412
    ///\n
413 413
    ///If you need more control on the execution, first you must call
414 414
    ///\ref lemon::Dfs::init() "init()", then you can add a source node
415 415
    ///with \ref lemon::Dfs::addSource() "addSource()".
416 416
    ///Finally \ref lemon::Dfs::start() "start()" will perform the
417 417
    ///actual path computation.
418 418

	
419 419
    ///@{
420 420

	
421 421
    ///Initializes the internal data structures.
422 422

	
423 423
    ///Initializes the internal data structures.
424 424
    ///
425 425
    void init()
426 426
    {
427 427
      create_maps();
428 428
      _stack.resize(countNodes(*G));
429 429
      _stack_head=-1;
430 430
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
431 431
        _pred->set(u,INVALID);
432 432
        _reached->set(u,false);
433 433
        _processed->set(u,false);
434 434
      }
435 435
    }
436 436

	
437 437
    ///Adds a new source node.
438 438

	
439 439
    ///Adds a new source node to the set of nodes to be processed.
440 440
    ///
441 441
    ///\pre The stack must be empty. (Otherwise the algorithm gives
442 442
    ///false results.)
443 443
    ///
444 444
    ///\warning Distances will be wrong (or at least strange) in case of
445 445
    ///multiple sources.
446 446
    void addSource(Node s)
447 447
    {
448 448
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
449 449
      if(!(*_reached)[s])
450 450
        {
451 451
          _reached->set(s,true);
452 452
          _pred->set(s,INVALID);
453 453
          OutArcIt e(*G,s);
454 454
          if(e!=INVALID) {
455 455
            _stack[++_stack_head]=e;
456 456
            _dist->set(s,_stack_head);
457 457
          }
458 458
          else {
459 459
            _processed->set(s,true);
460 460
            _dist->set(s,0);
461 461
          }
462 462
        }
463 463
    }
464 464

	
465 465
    ///Processes the next arc.
466 466

	
467 467
    ///Processes the next arc.
468 468
    ///
469 469
    ///\return The processed arc.
470 470
    ///
471 471
    ///\pre The stack must not be empty.
472 472
    Arc processNextArc()
473 473
    {
474 474
      Node m;
475 475
      Arc e=_stack[_stack_head];
476 476
      if(!(*_reached)[m=G->target(e)]) {
477 477
        _pred->set(m,e);
478 478
        _reached->set(m,true);
479 479
        ++_stack_head;
480 480
        _stack[_stack_head] = OutArcIt(*G, m);
481 481
        _dist->set(m,_stack_head);
482 482
      }
483 483
      else {
484 484
        m=G->source(e);
485 485
        ++_stack[_stack_head];
486 486
      }
487 487
      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
488 488
        _processed->set(m,true);
489 489
        --_stack_head;
490 490
        if(_stack_head>=0) {
491 491
          m=G->source(_stack[_stack_head]);
492 492
          ++_stack[_stack_head];
493 493
        }
494 494
      }
495 495
      return e;
496 496
    }
497 497

	
498 498
    ///Next arc to be processed.
499 499

	
500 500
    ///Next arc to be processed.
501 501
    ///
502 502
    ///\return The next arc to be processed or \c INVALID if the stack
503 503
    ///is empty.
504 504
    OutArcIt nextArc() const
505 505
    {
506 506
      return _stack_head>=0?_stack[_stack_head]:INVALID;
507 507
    }
508 508

	
509 509
    ///\brief Returns \c false if there are nodes
510 510
    ///to be processed.
511 511
    ///
512 512
    ///Returns \c false if there are nodes
513 513
    ///to be processed in the queue (stack).
514 514
    bool emptyQueue() const { return _stack_head<0; }
515 515

	
516 516
    ///Returns the number of the nodes to be processed.
517 517

	
518 518
    ///Returns the number of the nodes to be processed in the queue (stack).
519 519
    int queueSize() const { return _stack_head+1; }
520 520

	
521 521
    ///Executes the algorithm.
522 522

	
523 523
    ///Executes the algorithm.
524 524
    ///
525 525
    ///This method runs the %DFS algorithm from the root node
526 526
    ///in order to compute the DFS path to each node.
527 527
    ///
528 528
    /// The algorithm computes
529 529
    ///- the %DFS tree,
530 530
    ///- the distance of each node from the root in the %DFS tree.
531 531
    ///
532 532
    ///\pre init() must be called and a root node should be
533 533
    ///added with addSource() before using this function.
534 534
    ///
535 535
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
536 536
    ///\code
537 537
    ///  while ( !d.emptyQueue() ) {
538 538
    ///    d.processNextArc();
539 539
    ///  }
540 540
    ///\endcode
541 541
    void start()
542 542
    {
543 543
      while ( !emptyQueue() ) processNextArc();
544 544
    }
545 545

	
546 546
    ///Executes the algorithm until the given target node is reached.
547 547

	
548 548
    ///Executes the algorithm until the given target node is reached.
549 549
    ///
550 550
    ///This method runs the %DFS algorithm from the root node
551 551
    ///in order to compute the DFS path to \c t.
552 552
    ///
553 553
    ///The algorithm computes
554 554
    ///- the %DFS path to \c t,
555 555
    ///- the distance of \c t from the root in the %DFS tree.
556 556
    ///
557 557
    ///\pre init() must be called and a root node should be
558 558
    ///added with addSource() before using this function.
559 559
    void start(Node t)
560 560
    {
561 561
      while ( !emptyQueue() && !(*_reached)[t] )
562 562
        processNextArc();
563 563
    }
564 564

	
565 565
    ///Executes the algorithm until a condition is met.
566 566

	
567 567
    ///Executes the algorithm until a condition is met.
568 568
    ///
569 569
    ///This method runs the %DFS algorithm from the root node
570 570
    ///until an arc \c a with <tt>am[a]</tt> true is found.
571 571
    ///
572 572
    ///\param am A \c bool (or convertible) arc map. The algorithm
573 573
    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
574 574
    ///
575 575
    ///\return The reached arc \c a with <tt>am[a]</tt> true or
576 576
    ///\c INVALID if no such arc was found.
577 577
    ///
578 578
    ///\pre init() must be called and a root node should be
579 579
    ///added with addSource() before using this function.
580 580
    ///
581 581
    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
582 582
    ///not a node map.
583 583
    template<class ArcBoolMap>
584 584
    Arc start(const ArcBoolMap &am)
585 585
    {
586 586
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
587 587
        processNextArc();
588 588
      return emptyQueue() ? INVALID : _stack[_stack_head];
589 589
    }
590 590

	
591 591
    ///Runs the algorithm from the given source node.
592 592

	
593 593
    ///This method runs the %DFS algorithm from node \c s
594 594
    ///in order to compute the DFS path to each node.
595 595
    ///
596 596
    ///The algorithm computes
597 597
    ///- the %DFS tree,
598 598
    ///- the distance of each node from the root in the %DFS tree.
599 599
    ///
600 600
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
601 601
    ///\code
602 602
    ///  d.init();
603 603
    ///  d.addSource(s);
604 604
    ///  d.start();
605 605
    ///\endcode
606 606
    void run(Node s) {
607 607
      init();
608 608
      addSource(s);
609 609
      start();
610 610
    }
611 611

	
612 612
    ///Finds the %DFS path between \c s and \c t.
613 613

	
614 614
    ///This method runs the %DFS algorithm from node \c s
615 615
    ///in order to compute the DFS path to node \c t
616 616
    ///(it stops searching when \c t is processed)
617 617
    ///
618 618
    ///\return \c true if \c t is reachable form \c s.
619 619
    ///
620 620
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
621 621
    ///just a shortcut of the following code.
622 622
    ///\code
623 623
    ///  d.init();
624 624
    ///  d.addSource(s);
625 625
    ///  d.start(t);
626 626
    ///\endcode
627 627
    bool run(Node s,Node t) {
628 628
      init();
629 629
      addSource(s);
630 630
      start(t);
631 631
      return reached(t);
632 632
    }
633 633

	
634 634
    ///Runs the algorithm to visit all nodes in the digraph.
635 635

	
636 636
    ///This method runs the %DFS algorithm in order to compute the
637 637
    ///%DFS path to each node.
638 638
    ///
639 639
    ///The algorithm computes
640 640
    ///- the %DFS tree,
641 641
    ///- the distance of each node from the root in the %DFS tree.
642 642
    ///
643 643
    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
644 644
    ///\code
645 645
    ///  d.init();
646 646
    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
647 647
    ///    if (!d.reached(n)) {
648 648
    ///      d.addSource(n);
649 649
    ///      d.start();
650 650
    ///    }
651 651
    ///  }
652 652
    ///\endcode
653 653
    void run() {
654 654
      init();
655 655
      for (NodeIt it(*G); it != INVALID; ++it) {
656 656
        if (!reached(it)) {
657 657
          addSource(it);
658 658
          start();
659 659
        }
660 660
      }
661 661
    }
662 662

	
663 663
    ///@}
664 664

	
665 665
    ///\name Query Functions
666 666
    ///The result of the %DFS algorithm can be obtained using these
667 667
    ///functions.\n
668 668
    ///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
669 669
    ///"start()" must be called before using them.
670 670

	
671 671
    ///@{
672 672

	
673 673
    ///The DFS path to a node.
674 674

	
675 675
    ///Returns the DFS path to a node.
676 676
    ///
677 677
    ///\warning \c t should be reachable from the root.
678 678
    ///
679 679
    ///\pre Either \ref run() or \ref start() must be called before
680 680
    ///using this function.
681 681
    Path path(Node t) const { return Path(*G, *_pred, t); }
682 682

	
683 683
    ///The distance of a node from the root.
684 684

	
685 685
    ///Returns the distance of a node from the root.
686 686
    ///
687 687
    ///\warning If node \c v is not reachable from the root, then
688 688
    ///the return value of this function is undefined.
689 689
    ///
690 690
    ///\pre Either \ref run() or \ref start() must be called before
691 691
    ///using this function.
692 692
    int dist(Node v) const { return (*_dist)[v]; }
693 693

	
694 694
    ///Returns the 'previous arc' of the %DFS tree for a node.
695 695

	
696 696
    ///This function returns the 'previous arc' of the %DFS tree for the
697 697
    ///node \c v, i.e. it returns the last arc of a %DFS path from the
698 698
    ///root to \c v. It is \c INVALID
699 699
    ///if \c v is not reachable from the root(s) or if \c v is a root.
700 700
    ///
701 701
    ///The %DFS tree used here is equal to the %DFS tree used in
702 702
    ///\ref predNode().
703 703
    ///
704 704
    ///\pre Either \ref run() or \ref start() must be called before using
705 705
    ///this function.
706 706
    Arc predArc(Node v) const { return (*_pred)[v];}
707 707

	
708 708
    ///Returns the 'previous node' of the %DFS tree.
709 709

	
710 710
    ///This function returns the 'previous node' of the %DFS
711 711
    ///tree for the node \c v, i.e. it returns the last but one node
712 712
    ///from a %DFS path from the root to \c v. It is \c INVALID
713 713
    ///if \c v is not reachable from the root(s) or if \c v is a root.
714 714
    ///
715 715
    ///The %DFS tree used here is equal to the %DFS tree used in
716 716
    ///\ref predArc().
717 717
    ///
718 718
    ///\pre Either \ref run() or \ref start() must be called before
719 719
    ///using this function.
720 720
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
721 721
                                  G->source((*_pred)[v]); }
722 722

	
723 723
    ///\brief Returns a const reference to the node map that stores the
724 724
    ///distances of the nodes.
725 725
    ///
726 726
    ///Returns a const reference to the node map that stores the
727 727
    ///distances of the nodes calculated by the algorithm.
728 728
    ///
729 729
    ///\pre Either \ref run() or \ref init()
730 730
    ///must be called before using this function.
731 731
    const DistMap &distMap() const { return *_dist;}
732 732

	
733 733
    ///\brief Returns a const reference to the node map that stores the
734 734
    ///predecessor arcs.
735 735
    ///
736 736
    ///Returns a const reference to the node map that stores the predecessor
737 737
    ///arcs, which form the DFS tree.
738 738
    ///
739 739
    ///\pre Either \ref run() or \ref init()
740 740
    ///must be called before using this function.
741 741
    const PredMap &predMap() const { return *_pred;}
742 742

	
743 743
    ///Checks if a node is reachable from the root(s).
744 744

	
745 745
    ///Returns \c true if \c v is reachable from the root(s).
746 746
    ///\pre Either \ref run() or \ref start()
747 747
    ///must be called before using this function.
748 748
    bool reached(Node v) const { return (*_reached)[v]; }
749 749

	
750 750
    ///@}
751 751
  };
752 752

	
753 753
  ///Default traits class of dfs() function.
754 754

	
755 755
  ///Default traits class of dfs() function.
756 756
  ///\tparam GR Digraph type.
757 757
  template<class GR>
758 758
  struct DfsWizardDefaultTraits
759 759
  {
760 760
    ///The type of the digraph the algorithm runs on.
761 761
    typedef GR Digraph;
762 762

	
763 763
    ///\brief The type of the map that stores the predecessor
764 764
    ///arcs of the %DFS paths.
765 765
    ///
766 766
    ///The type of the map that stores the predecessor
767 767
    ///arcs of the %DFS paths.
768 768
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
769 769
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
770 770
    ///Instantiates a PredMap.
771 771

	
772 772
    ///This function instantiates a PredMap.
773 773
    ///\param g is the digraph, to which we would like to define the
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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 32
#include<lemon/bits/windows.h>
33 33
#endif
34 34

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

	
43 43

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

	
48 48
namespace lemon {
49 49

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

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

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

	
79 79

	
80 80
  const Graph &g;
81 81

	
82 82
  std::ostream& os;
83 83

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

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

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

	
94 94
  double _arcWidthScale;
95 95

	
96 96
  double _nodeScale;
97 97
  double _xBorder, _yBorder;
98 98
  double _scale;
99 99
  double _nodeBorderQuotient;
100 100

	
101 101
  bool _drawArrows;
102 102
  double _arrowLength, _arrowWidth;
103 103

	
104 104
  bool _showNodes, _showArcs;
105 105

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

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

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

	
117 117
  bool _undirected;
118 118

	
119 119
  bool _pleaseRemoveOsStream;
120 120

	
121 121
  bool _scaleToA4;
122 122

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

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

	
130 130
  bool _autoNodeScale;
131 131
  bool _autoArcWidthScale;
132 132

	
133 133
  bool _absoluteNodeSizes;
134 134
  bool _absoluteArcWidths;
135 135

	
136 136
  bool _negY;
137 137

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

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

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

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

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

	
191 191
  using T::_arcWidthScale;
192 192
  using T::_nodeScale;
193 193
  using T::_xBorder;
194 194
  using T::_yBorder;
195 195
  using T::_scale;
196 196
  using T::_nodeBorderQuotient;
197 197

	
198 198
  using T::_drawArrows;
199 199
  using T::_arrowLength;
200 200
  using T::_arrowWidth;
201 201

	
202 202
  using T::_showNodes;
203 203
  using T::_showArcs;
204 204

	
205 205
  using T::_enableParallel;
206 206
  using T::_parArcDist;
207 207

	
208 208
  using T::_showNodeText;
209 209
  using T::_nodeTexts;
210 210
  using T::_nodeTextSize;
211 211

	
212 212
  using T::_showNodePsText;
213 213
  using T::_nodePsTexts;
214 214
  using T::_nodePsTextsPreamble;
215 215

	
216 216
  using T::_undirected;
217 217

	
218 218
  using T::_pleaseRemoveOsStream;
219 219

	
220 220
  using T::_scaleToA4;
221 221

	
222 222
  using T::_title;
223 223
  using T::_copyright;
224 224

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

	
232 232
  using T::_autoNodeScale;
233 233
  using T::_autoArcWidthScale;
234 234

	
235 235
  using T::_absoluteNodeSizes;
236 236
  using T::_absoluteArcWidths;
237 237

	
238 238

	
239 239
  using T::_negY;
240 240
  using T::_preScale;
241 241

	
242 242
  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
243 243

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

	
252 252
  static const int INTERPOL_PREC;
253 253
  static const double A4HEIGHT;
254 254
  static const double A4WIDTH;
255 255
  static const double A4BORDER;
256 256

	
257 257
  bool dontPrint;
258 258

	
259 259
public:
260 260
  ///Node shapes
261 261

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

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

	
328 328
public:
329 329
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
330 330

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

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

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

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

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

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

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

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

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

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

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

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

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

	
501 501
  ///Turns on/off the absolutematic node size scaling.
502 502

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

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

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

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

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

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

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

	
550 550
  ///Turns on/off the absolutematic arc width scaling.
551 551
  ///
552 552
  ///\sa arcWidthScale()
553 553
  ///
554 554
  GraphToEps<T> &absoluteArcWidths(bool b=true) {
555 555
    _absoluteArcWidths=b;return *this;
556 556
  }
557 557
  ///Sets a global scale factor for the whole picture
558 558
  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
559 559
  ///Sets the width of the border around the picture
560 560
  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
561 561
  ///Sets the width of the border around the picture
562 562
  GraphToEps<T> &border(double x, double y) {
563 563
    _xBorder=x;_yBorder=y;return *this;
564 564
  }
565 565
  ///Sets whether to draw arrows
566 566
  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
567 567
  ///Sets the length of the arrowheads
568 568
  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
569 569
  ///Sets the width of the arrowheads
570 570
  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
571 571

	
572 572
  ///Scales the drawing to fit to A4 page
573 573
  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
574 574

	
575 575
  ///Enables parallel arcs
576 576
  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
577 577

	
578 578
  ///Sets the distance between parallel arcs
579 579
  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
580 580

	
581 581
  ///Hides the arcs
582 582
  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
583 583
  ///Hides the nodes
584 584
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
585 585

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

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

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

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

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

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

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

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

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

	
629 629
  ///Sets the title.
630 630

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

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

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

	
658 658
public:
659 659
  ~GraphToEps() { }
660 660

	
661 661
  ///Draws the graph.
662 662

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

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

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

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

	
685 685
      char cbuf[26];
686 686
      ctime_r(&tv.tv_sec,cbuf);
687 687
      os << cbuf;
688 688
#else
689 689
      os << bits::getWinFormattedDate();
690 690
      os << std::endl;
691 691
#endif
692 692
    }
693 693

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

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

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

	
725 725
    dim2::Box<double> bb;
726 726
    for(NodeIt n(g);n!=INVALID;++n) {
727 727
      double ns=_nodeSizes[n]*_nodeScale;
728 728
      dim2::Point<double> p(ns,ns);
729 729
      switch(_nodeShapes[n]) {
730 730
      case CIRCLE:
731 731
      case SQUARE:
732 732
      case DIAMOND:
733 733
        bb.add(p+mycoords[n]);
734 734
        bb.add(-p+mycoords[n]);
735 735
        break;
736 736
      case MALE:
737 737
        bb.add(-p+mycoords[n]);
738 738
        bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
739 739
        break;
740 740
      case FEMALE:
741 741
        bb.add(p+mycoords[n]);
742 742
        bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
743 743
        break;
744 744
      }
745 745
    }
746 746
    if (bb.empty()) {
747 747
      bb = dim2::Box<double>(dim2::Point<double>(0,0));
748 748
    }
749 749

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

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

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

	
768 768
    //x1 y1 x2 y2 x3 y3 cr cg cb w
769 769
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
770 770
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
771 771
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }"
772 772
       << " bind def\n";
773 773
    //x y r
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2011
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 lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" reader.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_READER_H
25 25
#define LEMON_LGF_READER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <set>
32 32
#include <map>
33 33

	
34 34
#include <lemon/core.h>
35 35

	
36 36
#include <lemon/lgf_writer.h>
37 37

	
38 38
#include <lemon/concept_check.h>
39 39
#include <lemon/concepts/maps.h>
40 40

	
41 41
namespace lemon {
42 42

	
43 43
  namespace _reader_bits {
44 44

	
45 45
    template <typename Value>
46 46
    struct DefaultConverter {
47 47
      Value operator()(const std::string& str) {
48 48
        std::istringstream is(str);
49 49
        Value value;
50 50
        if (!(is >> value)) {
51 51
          throw FormatError("Cannot read token");
52 52
        }
53 53

	
54 54
        char c;
55 55
        if (is >> std::ws >> c) {
56 56
          throw FormatError("Remaining characters in token");
57 57
        }
58 58
        return value;
59 59
      }
60 60
    };
61 61

	
62 62
    template <>
63 63
    struct DefaultConverter<std::string> {
64 64
      std::string operator()(const std::string& str) {
65 65
        return str;
66 66
      }
67 67
    };
68 68

	
69 69
    template <typename _Item>
70 70
    class MapStorageBase {
71 71
    public:
72 72
      typedef _Item Item;
73 73

	
74 74
    public:
75 75
      MapStorageBase() {}
76 76
      virtual ~MapStorageBase() {}
77 77

	
78 78
      virtual void set(const Item& item, const std::string& value) = 0;
79 79

	
80 80
    };
81 81

	
82 82
    template <typename _Item, typename _Map,
83 83
              typename _Converter = DefaultConverter<typename _Map::Value> >
84 84
    class MapStorage : public MapStorageBase<_Item> {
85 85
    public:
86 86
      typedef _Map Map;
87 87
      typedef _Converter Converter;
88 88
      typedef _Item Item;
89 89

	
90 90
    private:
91 91
      Map& _map;
92 92
      Converter _converter;
93 93

	
94 94
    public:
95 95
      MapStorage(Map& map, const Converter& converter = Converter())
96 96
        : _map(map), _converter(converter) {}
97 97
      virtual ~MapStorage() {}
98 98

	
99 99
      virtual void set(const Item& item ,const std::string& value) {
100 100
        _map.set(item, _converter(value));
101 101
      }
102 102
    };
103 103

	
104 104
    template <typename _Graph, bool _dir, typename _Map,
105 105
              typename _Converter = DefaultConverter<typename _Map::Value> >
106 106
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
107 107
    public:
108 108
      typedef _Map Map;
109 109
      typedef _Converter Converter;
110 110
      typedef _Graph Graph;
111 111
      typedef typename Graph::Edge Item;
112 112
      static const bool dir = _dir;
113 113

	
114 114
    private:
115 115
      const Graph& _graph;
116 116
      Map& _map;
117 117
      Converter _converter;
118 118

	
119 119
    public:
120 120
      GraphArcMapStorage(const Graph& graph, Map& map,
121 121
                         const Converter& converter = Converter())
122 122
        : _graph(graph), _map(map), _converter(converter) {}
123 123
      virtual ~GraphArcMapStorage() {}
124 124

	
125 125
      virtual void set(const Item& item ,const std::string& value) {
126 126
        _map.set(_graph.direct(item, dir), _converter(value));
127 127
      }
128 128
    };
129 129

	
130 130
    class ValueStorageBase {
131 131
    public:
132 132
      ValueStorageBase() {}
133 133
      virtual ~ValueStorageBase() {}
134 134

	
135 135
      virtual void set(const std::string&) = 0;
136 136
    };
137 137

	
138 138
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
139 139
    class ValueStorage : public ValueStorageBase {
140 140
    public:
141 141
      typedef _Value Value;
142 142
      typedef _Converter Converter;
143 143

	
144 144
    private:
145 145
      Value& _value;
146 146
      Converter _converter;
147 147

	
148 148
    public:
149 149
      ValueStorage(Value& value, const Converter& converter = Converter())
150 150
        : _value(value), _converter(converter) {}
151 151

	
152 152
      virtual void set(const std::string& value) {
153 153
        _value = _converter(value);
154 154
      }
155 155
    };
156 156

	
157 157
    template <typename Value>
158 158
    struct MapLookUpConverter {
159 159
      const std::map<std::string, Value>& _map;
160 160

	
161 161
      MapLookUpConverter(const std::map<std::string, Value>& map)
162 162
        : _map(map) {}
163 163

	
164 164
      Value operator()(const std::string& str) {
165 165
        typename std::map<std::string, Value>::const_iterator it =
166 166
          _map.find(str);
167 167
        if (it == _map.end()) {
168 168
          std::ostringstream msg;
169 169
          msg << "Item not found: " << str;
170 170
          throw FormatError(msg.str());
171 171
        }
172 172
        return it->second;
173 173
      }
174 174
    };
175 175

	
176 176
    template <typename Graph>
177 177
    struct GraphArcLookUpConverter {
178 178
      const Graph& _graph;
179 179
      const std::map<std::string, typename Graph::Edge>& _map;
180 180

	
181 181
      GraphArcLookUpConverter(const Graph& graph,
182 182
                              const std::map<std::string,
183 183
                                             typename Graph::Edge>& map)
184 184
        : _graph(graph), _map(map) {}
185 185

	
186 186
      typename Graph::Arc operator()(const std::string& str) {
187 187
        if (str.empty() || (str[0] != '+' && str[0] != '-')) {
188 188
          throw FormatError("Item must start with '+' or '-'");
189 189
        }
190 190
        typename std::map<std::string, typename Graph::Edge>
191 191
          ::const_iterator it = _map.find(str.substr(1));
192 192
        if (it == _map.end()) {
193 193
          throw FormatError("Item not found");
194 194
        }
195 195
        return _graph.direct(it->second, str[0] == '+');
196 196
      }
197 197
    };
198 198

	
199 199
    inline bool isWhiteSpace(char c) {
200 200
      return c == ' ' || c == '\t' || c == '\v' ||
201 201
        c == '\n' || c == '\r' || c == '\f';
202 202
    }
203 203

	
204 204
    inline bool isOct(char c) {
205 205
      return '0' <= c && c <='7';
206 206
    }
207 207

	
208 208
    inline int valueOct(char c) {
209 209
      LEMON_ASSERT(isOct(c), "The character is not octal.");
210 210
      return c - '0';
211 211
    }
212 212

	
213 213
    inline bool isHex(char c) {
214 214
      return ('0' <= c && c <= '9') ||
215 215
        ('a' <= c && c <= 'z') ||
216 216
        ('A' <= c && c <= 'Z');
217 217
    }
218 218

	
219 219
    inline int valueHex(char c) {
220 220
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
221 221
      if ('0' <= c && c <= '9') return c - '0';
222 222
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
223 223
      return c - 'A' + 10;
224 224
    }
225 225

	
226 226
    inline bool isIdentifierFirstChar(char c) {
227 227
      return ('a' <= c && c <= 'z') ||
228 228
        ('A' <= c && c <= 'Z') || c == '_';
229 229
    }
230 230

	
231 231
    inline bool isIdentifierChar(char c) {
232 232
      return isIdentifierFirstChar(c) ||
233 233
        ('0' <= c && c <= '9');
234 234
    }
235 235

	
236 236
    inline char readEscape(std::istream& is) {
237 237
      char c;
238 238
      if (!is.get(c))
239 239
        throw FormatError("Escape format error");
240 240

	
241 241
      switch (c) {
242 242
      case '\\':
243 243
        return '\\';
244 244
      case '\"':
245 245
        return '\"';
246 246
      case '\'':
247 247
        return '\'';
248 248
      case '\?':
249 249
        return '\?';
250 250
      case 'a':
251 251
        return '\a';
252 252
      case 'b':
253 253
        return '\b';
254 254
      case 'f':
255 255
        return '\f';
256 256
      case 'n':
257 257
        return '\n';
258 258
      case 'r':
259 259
        return '\r';
260 260
      case 't':
261 261
        return '\t';
262 262
      case 'v':
263 263
        return '\v';
264 264
      case 'x':
265 265
        {
266 266
          int code;
267 267
          if (!is.get(c) || !isHex(c))
268 268
            throw FormatError("Escape format error");
269 269
          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
270 270
          else code = code * 16 + valueHex(c);
271 271
          return code;
272 272
        }
273 273
      default:
274 274
        {
275 275
          int code;
276 276
          if (!isOct(c))
277 277
            throw FormatError("Escape format error");
278 278
          else if (code = valueOct(c), !is.get(c) || !isOct(c))
279 279
            is.putback(c);
280 280
          else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
281 281
            is.putback(c);
282 282
          else code = code * 8 + valueOct(c);
283 283
          return code;
284 284
        }
285 285
      }
286 286
    }
287 287

	
288 288
    inline std::istream& readToken(std::istream& is, std::string& str) {
289 289
      std::ostringstream os;
290 290

	
291 291
      char c;
292 292
      is >> std::ws;
293 293

	
294 294
      if (!is.get(c))
295 295
        return is;
296 296

	
297 297
      if (c == '\"') {
298 298
        while (is.get(c) && c != '\"') {
299 299
          if (c == '\\')
300 300
            c = readEscape(is);
301 301
          os << c;
302 302
        }
303 303
        if (!is)
304 304
          throw FormatError("Quoted format error");
305 305
      } else {
306 306
        is.putback(c);
307 307
        while (is.get(c) && !isWhiteSpace(c)) {
308 308
          if (c == '\\')
309 309
            c = readEscape(is);
310 310
          os << c;
311 311
        }
312 312
        if (!is) {
313 313
          is.clear();
314 314
        } else {
315 315
          is.putback(c);
316 316
        }
317 317
      }
318 318
      str = os.str();
319 319
      return is;
320 320
    }
321 321

	
322 322
    class Section {
323 323
    public:
324 324
      virtual ~Section() {}
325 325
      virtual void process(std::istream& is, int& line_num) = 0;
326 326
    };
327 327

	
328 328
    template <typename Functor>
329 329
    class LineSection : public Section {
330 330
    private:
331 331

	
332 332
      Functor _functor;
333 333

	
334 334
    public:
335 335

	
336 336
      LineSection(const Functor& functor) : _functor(functor) {}
337 337
      virtual ~LineSection() {}
338 338

	
339 339
      virtual void process(std::istream& is, int& line_num) {
340 340
        char c;
341 341
        std::string line;
342 342
        while (is.get(c) && c != '@') {
343 343
          if (c == '\n') {
344 344
            ++line_num;
345 345
          } else if (c == '#') {
346 346
            getline(is, line);
347 347
            ++line_num;
348 348
          } else if (!isWhiteSpace(c)) {
349 349
            is.putback(c);
350 350
            getline(is, line);
351 351
            _functor(line);
352 352
            ++line_num;
353 353
          }
354 354
        }
355 355
        if (is) is.putback(c);
356 356
        else if (is.eof()) is.clear();
357 357
      }
358 358
    };
359 359

	
360 360
    template <typename Functor>
361 361
    class StreamSection : public Section {
362 362
    private:
363 363

	
364 364
      Functor _functor;
365 365

	
366 366
    public:
367 367

	
368 368
      StreamSection(const Functor& functor) : _functor(functor) {}
369 369
      virtual ~StreamSection() {}
370 370

	
371 371
      virtual void process(std::istream& is, int& line_num) {
372 372
        _functor(is, line_num);
373 373
        char c;
374 374
        std::string line;
375 375
        while (is.get(c) && c != '@') {
376 376
          if (c == '\n') {
377 377
            ++line_num;
378 378
          } else if (!isWhiteSpace(c)) {
379 379
            getline(is, line);
380 380
            ++line_num;
381 381
          }
382 382
        }
383 383
        if (is) is.putback(c);
384 384
        else if (is.eof()) is.clear();
385 385
      }
386 386
    };
387 387

	
388 388
  }
389 389

	
390 390
  template <typename Digraph>
391 391
  class DigraphReader;
392 392

	
393 393
  template <typename Digraph>
394
  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
394
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
395 395
                                       std::istream& is = std::cin);
396 396
  template <typename Digraph>
397 397
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
398 398
  template <typename Digraph>
399 399
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
400 400

	
401 401
  /// \ingroup lemon_io
402 402
  ///
403 403
  /// \brief \ref lgf-format "LGF" reader for directed graphs
404 404
  ///
405 405
  /// This utility reads an \ref lgf-format "LGF" file.
406 406
  ///
407 407
  /// The reading method does a batch processing. The user creates a
408 408
  /// reader object, then various reading rules can be added to the
409 409
  /// reader, and eventually the reading is executed with the \c run()
410 410
  /// member function. A map reading rule can be added to the reader
411 411
  /// with the \c nodeMap() or \c arcMap() members. An optional
412 412
  /// converter parameter can also be added as a standard functor
413 413
  /// converting from \c std::string to the value type of the map. If it
414 414
  /// is set, it will determine how the tokens in the file should be
415 415
  /// converted to the value type of the map. If the functor is not set,
416 416
  /// then a default conversion will be used. One map can be read into
417 417
  /// multiple map objects at the same time. The \c attribute(), \c
418 418
  /// node() and \c arc() functions are used to add attribute reading
419 419
  /// rules.
420 420
  ///
421 421
  ///\code
422 422
  /// DigraphReader<Digraph>(digraph, std::cin).
423 423
  ///   nodeMap("coordinates", coord_map).
424 424
  ///   arcMap("capacity", cap_map).
425 425
  ///   node("source", src).
426 426
  ///   node("target", trg).
427 427
  ///   attribute("caption", caption).
428 428
  ///   run();
429 429
  ///\endcode
430 430
  ///
431 431
  /// By default the reader uses the first section in the file of the
432 432
  /// proper type. If a section has an optional name, then it can be
433 433
  /// selected for reading by giving an optional name parameter to the
434 434
  /// \c nodes(), \c arcs() or \c attributes() functions.
435 435
  ///
436 436
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
437 437
  /// that the nodes or arcs should not be constructed (added to the
438 438
  /// graph) during the reading, but instead the label map of the items
439 439
  /// are given as a parameter of these functions. An
440 440
  /// application of these functions is multipass reading, which is
441 441
  /// important if two \c \@arcs sections must be read from the
442 442
  /// file. In this case the first phase would read the node set and one
443 443
  /// of the arc sets, while the second phase would read the second arc
444 444
  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
445 445
  /// The previously read label node map should be passed to the \c
446 446
  /// useNodes() functions. Another application of multipass reading when
447 447
  /// paths are given as a node map or an arc map.
448 448
  /// It is impossible to read this in
449 449
  /// a single pass, because the arcs are not constructed when the node
450 450
  /// maps are read.
451 451
  template <typename _Digraph>
452 452
  class DigraphReader {
453 453
  public:
454 454

	
455 455
    typedef _Digraph Digraph;
456 456
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
457 457

	
458 458
  private:
459 459

	
460 460

	
461 461
    std::istream* _is;
462 462
    bool local_is;
463 463
    std::string _filename;
464 464

	
465 465
    Digraph& _digraph;
466 466

	
467 467
    std::string _nodes_caption;
468 468
    std::string _arcs_caption;
469 469
    std::string _attributes_caption;
470 470

	
471 471
    typedef std::map<std::string, Node> NodeIndex;
472 472
    NodeIndex _node_index;
473 473
    typedef std::map<std::string, Arc> ArcIndex;
474 474
    ArcIndex _arc_index;
475 475

	
476 476
    typedef std::vector<std::pair<std::string,
477 477
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
478 478
    NodeMaps _node_maps;
479 479

	
480 480
    typedef std::vector<std::pair<std::string,
481 481
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
482 482
    ArcMaps _arc_maps;
483 483

	
484 484
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
485 485
      Attributes;
486 486
    Attributes _attributes;
487 487

	
488 488
    bool _use_nodes;
489 489
    bool _use_arcs;
490 490

	
491 491
    bool _skip_nodes;
492 492
    bool _skip_arcs;
493 493

	
494 494
    int line_num;
495 495
    std::istringstream line;
496 496

	
497 497
  public:
498 498

	
499 499
    /// \brief Constructor
500 500
    ///
501 501
    /// Construct a directed graph reader, which reads from the given
502 502
    /// input stream.
503 503
    DigraphReader(Digraph& digraph, std::istream& is = std::cin)
504 504
      : _is(&is), local_is(false), _digraph(digraph),
505 505
        _use_nodes(false), _use_arcs(false),
506 506
        _skip_nodes(false), _skip_arcs(false) {}
507 507

	
508 508
    /// \brief Constructor
509 509
    ///
510 510
    /// Construct a directed graph reader, which reads from the given
511 511
    /// file.
512 512
    DigraphReader(Digraph& digraph, const std::string& fn)
513 513
      : _is(new std::ifstream(fn.c_str())), local_is(true),
514 514
        _filename(fn), _digraph(digraph),
515 515
        _use_nodes(false), _use_arcs(false),
516 516
        _skip_nodes(false), _skip_arcs(false) {
517 517
      if (!(*_is)) {
518 518
        delete _is;
519 519
        throw IoError("Cannot open file", fn);
520 520
      }
521 521
    }
522 522

	
523 523
    /// \brief Constructor
524 524
    ///
525 525
    /// Construct a directed graph reader, which reads from the given
526 526
    /// file.
527 527
    DigraphReader(Digraph& digraph, const char* fn)
528 528
      : _is(new std::ifstream(fn)), local_is(true),
529 529
        _filename(fn), _digraph(digraph),
530 530
        _use_nodes(false), _use_arcs(false),
531 531
        _skip_nodes(false), _skip_arcs(false) {
532 532
      if (!(*_is)) {
533 533
        delete _is;
534 534
        throw IoError("Cannot open file", fn);
535 535
      }
536 536
    }
537 537

	
538 538
    /// \brief Destructor
539 539
    ~DigraphReader() {
540 540
      for (typename NodeMaps::iterator it = _node_maps.begin();
541 541
           it != _node_maps.end(); ++it) {
542 542
        delete it->second;
543 543
      }
544 544

	
545 545
      for (typename ArcMaps::iterator it = _arc_maps.begin();
546 546
           it != _arc_maps.end(); ++it) {
547 547
        delete it->second;
548 548
      }
549 549

	
550 550
      for (typename Attributes::iterator it = _attributes.begin();
551 551
           it != _attributes.end(); ++it) {
552 552
        delete it->second;
553 553
      }
554 554

	
555 555
      if (local_is) {
556 556
        delete _is;
557 557
      }
558 558

	
559 559
    }
560 560

	
561 561
  private:
562 562

	
563 563
    template <typename DGR>
564 564
    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
565 565
    template <typename DGR>
566
    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
566
    friend DigraphReader<DGR> digraphReader(DGR& digraph,
567 567
                                            const std::string& fn);
568 568
    template <typename DGR>
569 569
    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
570 570

	
571 571
    DigraphReader(DigraphReader& other)
572 572
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
573 573
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
574 574
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
575 575

	
576 576
      other._is = 0;
577 577
      other.local_is = false;
578 578

	
579 579
      _node_index.swap(other._node_index);
580 580
      _arc_index.swap(other._arc_index);
581 581

	
582 582
      _node_maps.swap(other._node_maps);
583 583
      _arc_maps.swap(other._arc_maps);
584 584
      _attributes.swap(other._attributes);
585 585

	
586 586
      _nodes_caption = other._nodes_caption;
587 587
      _arcs_caption = other._arcs_caption;
588 588
      _attributes_caption = other._attributes_caption;
589 589

	
590 590
    }
591 591

	
592 592
    DigraphReader& operator=(const DigraphReader&);
593 593

	
594 594
  public:
595 595

	
596 596
    /// \name Reading rules
597 597
    /// @{
598 598

	
599 599
    /// \brief Node map reading rule
600 600
    ///
601 601
    /// Add a node map reading rule to the reader.
602 602
    template <typename Map>
603 603
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
604 604
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
605 605
      _reader_bits::MapStorageBase<Node>* storage =
606 606
        new _reader_bits::MapStorage<Node, Map>(map);
607 607
      _node_maps.push_back(std::make_pair(caption, storage));
608 608
      return *this;
609 609
    }
610 610

	
611 611
    /// \brief Node map reading rule
612 612
    ///
613 613
    /// Add a node map reading rule with specialized converter to the
614 614
    /// reader.
615 615
    template <typename Map, typename Converter>
616 616
    DigraphReader& nodeMap(const std::string& caption, Map& map,
617 617
                           const Converter& converter = Converter()) {
618 618
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
619 619
      _reader_bits::MapStorageBase<Node>* storage =
620 620
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
621 621
      _node_maps.push_back(std::make_pair(caption, storage));
622 622
      return *this;
623 623
    }
624 624

	
625 625
    /// \brief Arc map reading rule
626 626
    ///
627 627
    /// Add an arc map reading rule to the reader.
628 628
    template <typename Map>
629 629
    DigraphReader& arcMap(const std::string& caption, Map& map) {
630 630
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
631 631
      _reader_bits::MapStorageBase<Arc>* storage =
632 632
        new _reader_bits::MapStorage<Arc, Map>(map);
633 633
      _arc_maps.push_back(std::make_pair(caption, storage));
634 634
      return *this;
635 635
    }
636 636

	
637 637
    /// \brief Arc map reading rule
638 638
    ///
639 639
    /// Add an arc map reading rule with specialized converter to the
640 640
    /// reader.
641 641
    template <typename Map, typename Converter>
642 642
    DigraphReader& arcMap(const std::string& caption, Map& map,
643 643
                          const Converter& converter = Converter()) {
644 644
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
645 645
      _reader_bits::MapStorageBase<Arc>* storage =
646 646
        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
647 647
      _arc_maps.push_back(std::make_pair(caption, storage));
648 648
      return *this;
649 649
    }
650 650

	
651 651
    /// \brief Attribute reading rule
652 652
    ///
653 653
    /// Add an attribute reading rule to the reader.
654 654
    template <typename Value>
655 655
    DigraphReader& attribute(const std::string& caption, Value& value) {
656 656
      _reader_bits::ValueStorageBase* storage =
657 657
        new _reader_bits::ValueStorage<Value>(value);
658 658
      _attributes.insert(std::make_pair(caption, storage));
659 659
      return *this;
660 660
    }
661 661

	
662 662
    /// \brief Attribute reading rule
663 663
    ///
664 664
    /// Add an attribute reading rule with specialized converter to the
665 665
    /// reader.
666 666
    template <typename Value, typename Converter>
667 667
    DigraphReader& attribute(const std::string& caption, Value& value,
668 668
                             const Converter& converter = Converter()) {
669 669
      _reader_bits::ValueStorageBase* storage =
670 670
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
671 671
      _attributes.insert(std::make_pair(caption, storage));
672 672
      return *this;
673 673
    }
674 674

	
675 675
    /// \brief Node reading rule
676 676
    ///
677 677
    /// Add a node reading rule to reader.
678 678
    DigraphReader& node(const std::string& caption, Node& node) {
679 679
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
680 680
      Converter converter(_node_index);
681 681
      _reader_bits::ValueStorageBase* storage =
682 682
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
683 683
      _attributes.insert(std::make_pair(caption, storage));
684 684
      return *this;
685 685
    }
686 686

	
687 687
    /// \brief Arc reading rule
688 688
    ///
689 689
    /// Add an arc reading rule to reader.
690 690
    DigraphReader& arc(const std::string& caption, Arc& arc) {
691 691
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
692 692
      Converter converter(_arc_index);
693 693
      _reader_bits::ValueStorageBase* storage =
694 694
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
695 695
      _attributes.insert(std::make_pair(caption, storage));
696 696
      return *this;
697 697
    }
698 698

	
699 699
    /// @}
700 700

	
701 701
    /// \name Select section by name
702 702
    /// @{
703 703

	
704 704
    /// \brief Set \c \@nodes section to be read
705 705
    ///
706 706
    /// Set \c \@nodes section to be read
707 707
    DigraphReader& nodes(const std::string& caption) {
708 708
      _nodes_caption = caption;
709 709
      return *this;
710 710
    }
711 711

	
712 712
    /// \brief Set \c \@arcs section to be read
713 713
    ///
714 714
    /// Set \c \@arcs section to be read
715 715
    DigraphReader& arcs(const std::string& caption) {
716 716
      _arcs_caption = caption;
717 717
      return *this;
718 718
    }
719 719

	
720 720
    /// \brief Set \c \@attributes section to be read
721 721
    ///
722 722
    /// Set \c \@attributes section to be read
723 723
    DigraphReader& attributes(const std::string& caption) {
724 724
      _attributes_caption = caption;
725 725
      return *this;
726 726
    }
727 727

	
728 728
    /// @}
729 729

	
730 730
    /// \name Using previously constructed node or arc set
731 731
    /// @{
732 732

	
733 733
    /// \brief Use previously constructed node set
734 734
    ///
735 735
    /// Use previously constructed node set, and specify the node
736 736
    /// label map.
737 737
    template <typename Map>
738 738
    DigraphReader& useNodes(const Map& map) {
739 739
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
740 740
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
741 741
      _use_nodes = true;
742 742
      _writer_bits::DefaultConverter<typename Map::Value> converter;
743 743
      for (NodeIt n(_digraph); n != INVALID; ++n) {
744 744
        _node_index.insert(std::make_pair(converter(map[n]), n));
745 745
      }
746 746
      return *this;
747 747
    }
748 748

	
749 749
    /// \brief Use previously constructed node set
750 750
    ///
751 751
    /// Use previously constructed node set, and specify the node
752 752
    /// label map and a functor which converts the label map values to
753 753
    /// \c std::string.
754 754
    template <typename Map, typename Converter>
755 755
    DigraphReader& useNodes(const Map& map,
756 756
                            const Converter& converter = Converter()) {
757 757
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
758 758
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
759 759
      _use_nodes = true;
760 760
      for (NodeIt n(_digraph); n != INVALID; ++n) {
761 761
        _node_index.insert(std::make_pair(converter(map[n]), n));
762 762
      }
763 763
      return *this;
764 764
    }
765 765

	
766 766
    /// \brief Use previously constructed arc set
767 767
    ///
768 768
    /// Use previously constructed arc set, and specify the arc
769 769
    /// label map.
770 770
    template <typename Map>
771 771
    DigraphReader& useArcs(const Map& map) {
772 772
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
773 773
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
774 774
      _use_arcs = true;
775 775
      _writer_bits::DefaultConverter<typename Map::Value> converter;
776 776
      for (ArcIt a(_digraph); a != INVALID; ++a) {
777 777
        _arc_index.insert(std::make_pair(converter(map[a]), a));
778 778
      }
779 779
      return *this;
780 780
    }
781 781

	
782 782
    /// \brief Use previously constructed arc set
783 783
    ///
784 784
    /// Use previously constructed arc set, and specify the arc
785 785
    /// label map and a functor which converts the label map values to
786 786
    /// \c std::string.
787 787
    template <typename Map, typename Converter>
788 788
    DigraphReader& useArcs(const Map& map,
789 789
                           const Converter& converter = Converter()) {
790 790
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
791 791
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
792 792
      _use_arcs = true;
793 793
      for (ArcIt a(_digraph); a != INVALID; ++a) {
794 794
        _arc_index.insert(std::make_pair(converter(map[a]), a));
795 795
      }
796 796
      return *this;
797 797
    }
798 798

	
799 799
    /// \brief Skips the reading of node section
800 800
    ///
801 801
    /// Omit the reading of the node section. This implies that each node
802 802
    /// map reading rule will be abandoned, and the nodes of the graph
803 803
    /// will not be constructed, which usually cause that the arc set
804 804
    /// could not be read due to lack of node name resolving.
805 805
    /// Therefore \c skipArcs() function should also be used, or
806 806
    /// \c useNodes() should be used to specify the label of the nodes.
807 807
    DigraphReader& skipNodes() {
808 808
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
809 809
      _skip_nodes = true;
810 810
      return *this;
811 811
    }
812 812

	
813 813
    /// \brief Skips the reading of arc section
814 814
    ///
815 815
    /// Omit the reading of the arc section. This implies that each arc
816 816
    /// map reading rule will be abandoned, and the arcs of the graph
817 817
    /// will not be constructed.
818 818
    DigraphReader& skipArcs() {
819 819
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
820 820
      _skip_arcs = true;
821 821
      return *this;
822 822
    }
823 823

	
824 824
    /// @}
825 825

	
826 826
  private:
827 827

	
828 828
    bool readLine() {
829 829
      std::string str;
830 830
      while(++line_num, std::getline(*_is, str)) {
831 831
        line.clear(); line.str(str);
832 832
        char c;
833 833
        if (line >> std::ws >> c && c != '#') {
834 834
          line.putback(c);
835 835
          return true;
836 836
        }
837 837
      }
838 838
      return false;
839 839
    }
840 840

	
841 841
    bool readSuccess() {
842 842
      return static_cast<bool>(*_is);
843 843
    }
844 844

	
845 845
    void skipSection() {
846 846
      char c;
847 847
      while (readSuccess() && line >> c && c != '@') {
848 848
        readLine();
849 849
      }
850 850
      if (readSuccess()) {
851 851
        line.putback(c);
852 852
      }
853 853
    }
854 854

	
855 855
    void readNodes() {
856 856

	
857 857
      std::vector<int> map_index(_node_maps.size());
858 858
      int map_num, label_index;
859 859

	
860 860
      char c;
861 861
      if (!readLine() || !(line >> c) || c == '@') {
862 862
        if (readSuccess() && line) line.putback(c);
863 863
        if (!_node_maps.empty())
864 864
          throw FormatError("Cannot find map names");
865 865
        return;
866 866
      }
867 867
      line.putback(c);
868 868

	
869 869
      {
870 870
        std::map<std::string, int> maps;
871 871

	
872 872
        std::string map;
873 873
        int index = 0;
874 874
        while (_reader_bits::readToken(line, map)) {
875 875
          if (maps.find(map) != maps.end()) {
876 876
            std::ostringstream msg;
877 877
            msg << "Multiple occurence of node map: " << map;
878 878
            throw FormatError(msg.str());
879 879
          }
880 880
          maps.insert(std::make_pair(map, index));
881 881
          ++index;
882 882
        }
883 883

	
884 884
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
885 885
          std::map<std::string, int>::iterator jt =
886 886
            maps.find(_node_maps[i].first);
887 887
          if (jt == maps.end()) {
888 888
            std::ostringstream msg;
889 889
            msg << "Map not found: " << _node_maps[i].first;
890 890
            throw FormatError(msg.str());
891 891
          }
892 892
          map_index[i] = jt->second;
893 893
        }
894 894

	
895 895
        {
896 896
          std::map<std::string, int>::iterator jt = maps.find("label");
897 897
          if (jt != maps.end()) {
898 898
            label_index = jt->second;
899 899
          } else {
900 900
            label_index = -1;
901 901
          }
902 902
        }
903 903
        map_num = maps.size();
904 904
      }
905 905

	
906 906
      while (readLine() && line >> c && c != '@') {
907 907
        line.putback(c);
908 908

	
909 909
        std::vector<std::string> tokens(map_num);
910 910
        for (int i = 0; i < map_num; ++i) {
911 911
          if (!_reader_bits::readToken(line, tokens[i])) {
912 912
            std::ostringstream msg;
913 913
            msg << "Column not found (" << i + 1 << ")";
914 914
            throw FormatError(msg.str());
915 915
          }
916 916
        }
917 917
        if (line >> std::ws >> c)
918 918
          throw FormatError("Extra character at the end of line");
919 919

	
920 920
        Node n;
921 921
        if (!_use_nodes) {
922 922
          n = _digraph.addNode();
923 923
          if (label_index != -1)
924 924
            _node_index.insert(std::make_pair(tokens[label_index], n));
925 925
        } else {
926 926
          if (label_index == -1)
927 927
            throw FormatError("Label map not found");
928 928
          typename std::map<std::string, Node>::iterator it =
929 929
            _node_index.find(tokens[label_index]);
930 930
          if (it == _node_index.end()) {
931 931
            std::ostringstream msg;
932 932
            msg << "Node with label not found: " << tokens[label_index];
933 933
            throw FormatError(msg.str());
934 934
          }
935 935
          n = it->second;
936 936
        }
937 937

	
938 938
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
939 939
          _node_maps[i].second->set(n, tokens[map_index[i]]);
940 940
        }
941 941

	
942 942
      }
943 943
      if (readSuccess()) {
944 944
        line.putback(c);
945 945
      }
946 946
    }
947 947

	
948 948
    void readArcs() {
949 949

	
950 950
      std::vector<int> map_index(_arc_maps.size());
951 951
      int map_num, label_index;
952 952

	
953 953
      char c;
954 954
      if (!readLine() || !(line >> c) || c == '@') {
955 955
        if (readSuccess() && line) line.putback(c);
956 956
        if (!_arc_maps.empty())
957 957
          throw FormatError("Cannot find map names");
958 958
        return;
959 959
      }
960 960
      line.putback(c);
961 961

	
962 962
      {
963 963
        std::map<std::string, int> maps;
964 964

	
965 965
        std::string map;
966 966
        int index = 0;
967 967
        while (_reader_bits::readToken(line, map)) {
968 968
          if(map == "-") {
969 969
              if(index!=0)
970 970
                throw FormatError("'-' is not allowed as a map name");
971 971
              else if (line >> std::ws >> c)
972 972
                throw FormatError("Extra character at the end of line");
973 973
              else break;
974 974
            }
975 975
          if (maps.find(map) != maps.end()) {
976 976
            std::ostringstream msg;
977 977
            msg << "Multiple occurence of arc map: " << map;
978 978
            throw FormatError(msg.str());
979 979
          }
980 980
          maps.insert(std::make_pair(map, index));
981 981
          ++index;
982 982
        }
983 983

	
984 984
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
985 985
          std::map<std::string, int>::iterator jt =
986 986
            maps.find(_arc_maps[i].first);
987 987
          if (jt == maps.end()) {
988 988
            std::ostringstream msg;
989 989
            msg << "Map not found: " << _arc_maps[i].first;
990 990
            throw FormatError(msg.str());
991 991
          }
992 992
          map_index[i] = jt->second;
993 993
        }
994 994

	
995 995
        {
996 996
          std::map<std::string, int>::iterator jt = maps.find("label");
997 997
          if (jt != maps.end()) {
998 998
            label_index = jt->second;
999 999
          } else {
1000 1000
            label_index = -1;
1001 1001
          }
1002 1002
        }
1003 1003
        map_num = maps.size();
1004 1004
      }
1005 1005

	
1006 1006
      while (readLine() && line >> c && c != '@') {
1007 1007
        line.putback(c);
1008 1008

	
1009 1009
        std::string source_token;
1010 1010
        std::string target_token;
1011 1011

	
1012 1012
        if (!_reader_bits::readToken(line, source_token))
1013 1013
          throw FormatError("Source not found");
1014 1014

	
1015 1015
        if (!_reader_bits::readToken(line, target_token))
1016 1016
          throw FormatError("Target not found");
1017 1017

	
1018 1018
        std::vector<std::string> tokens(map_num);
1019 1019
        for (int i = 0; i < map_num; ++i) {
1020 1020
          if (!_reader_bits::readToken(line, tokens[i])) {
1021 1021
            std::ostringstream msg;
1022 1022
            msg << "Column not found (" << i + 1 << ")";
1023 1023
            throw FormatError(msg.str());
1024 1024
          }
1025 1025
        }
1026 1026
        if (line >> std::ws >> c)
1027 1027
          throw FormatError("Extra character at the end of line");
1028 1028

	
1029 1029
        Arc a;
1030 1030
        if (!_use_arcs) {
1031 1031

	
1032 1032
          typename NodeIndex::iterator it;
1033 1033

	
1034 1034
          it = _node_index.find(source_token);
1035 1035
          if (it == _node_index.end()) {
1036 1036
            std::ostringstream msg;
1037 1037
            msg << "Item not found: " << source_token;
1038 1038
            throw FormatError(msg.str());
1039 1039
          }
1040 1040
          Node source = it->second;
1041 1041

	
1042 1042
          it = _node_index.find(target_token);
1043 1043
          if (it == _node_index.end()) {
1044 1044
            std::ostringstream msg;
1045 1045
            msg << "Item not found: " << target_token;
1046 1046
            throw FormatError(msg.str());
1047 1047
          }
1048 1048
          Node target = it->second;
1049 1049

	
1050 1050
          a = _digraph.addArc(source, target);
1051 1051
          if (label_index != -1)
1052 1052
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1053 1053
        } else {
1054 1054
          if (label_index == -1)
1055 1055
            throw FormatError("Label map not found");
1056 1056
          typename std::map<std::string, Arc>::iterator it =
1057 1057
            _arc_index.find(tokens[label_index]);
1058 1058
          if (it == _arc_index.end()) {
1059 1059
            std::ostringstream msg;
1060 1060
            msg << "Arc with label not found: " << tokens[label_index];
1061 1061
            throw FormatError(msg.str());
1062 1062
          }
1063 1063
          a = it->second;
1064 1064
        }
1065 1065

	
1066 1066
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1067 1067
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1068 1068
        }
1069 1069

	
1070 1070
      }
1071 1071
      if (readSuccess()) {
1072 1072
        line.putback(c);
1073 1073
      }
1074 1074
    }
1075 1075

	
1076 1076
    void readAttributes() {
1077 1077

	
1078 1078
      std::set<std::string> read_attr;
1079 1079

	
1080 1080
      char c;
1081 1081
      while (readLine() && line >> c && c != '@') {
1082 1082
        line.putback(c);
1083 1083

	
1084 1084
        std::string attr, token;
1085 1085
        if (!_reader_bits::readToken(line, attr))
1086 1086
          throw FormatError("Attribute name not found");
1087 1087
        if (!_reader_bits::readToken(line, token))
1088 1088
          throw FormatError("Attribute value not found");
1089 1089
        if (line >> c)
1090 1090
          throw FormatError("Extra character at the end of line");
1091 1091

	
1092 1092
        {
1093 1093
          std::set<std::string>::iterator it = read_attr.find(attr);
1094 1094
          if (it != read_attr.end()) {
1095 1095
            std::ostringstream msg;
1096 1096
            msg << "Multiple occurence of attribute: " << attr;
1097 1097
            throw FormatError(msg.str());
1098 1098
          }
1099 1099
          read_attr.insert(attr);
1100 1100
        }
1101 1101

	
1102 1102
        {
1103 1103
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1104 1104
          while (it != _attributes.end() && it->first == attr) {
1105 1105
            it->second->set(token);
1106 1106
            ++it;
1107 1107
          }
1108 1108
        }
1109 1109

	
1110 1110
      }
1111 1111
      if (readSuccess()) {
1112 1112
        line.putback(c);
1113 1113
      }
1114 1114
      for (typename Attributes::iterator it = _attributes.begin();
1115 1115
           it != _attributes.end(); ++it) {
1116 1116
        if (read_attr.find(it->first) == read_attr.end()) {
1117 1117
          std::ostringstream msg;
1118 1118
          msg << "Attribute not found: " << it->first;
1119 1119
          throw FormatError(msg.str());
1120 1120
        }
1121 1121
      }
1122 1122
    }
1123 1123

	
1124 1124
  public:
1125 1125

	
1126 1126
    /// \name Execution of the reader
1127 1127
    /// @{
1128 1128

	
1129 1129
    /// \brief Start the batch processing
1130 1130
    ///
1131 1131
    /// This function starts the batch processing
1132 1132
    void run() {
1133 1133
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1134 1134

	
1135 1135
      bool nodes_done = _skip_nodes;
1136 1136
      bool arcs_done = _skip_arcs;
1137 1137
      bool attributes_done = false;
1138 1138

	
1139 1139
      line_num = 0;
1140 1140
      readLine();
1141 1141
      skipSection();
1142 1142

	
1143 1143
      while (readSuccess()) {
1144 1144
        try {
1145 1145
          char c;
1146 1146
          std::string section, caption;
1147 1147
          line >> c;
1148 1148
          _reader_bits::readToken(line, section);
1149 1149
          _reader_bits::readToken(line, caption);
1150 1150

	
1151 1151
          if (line >> c)
1152 1152
            throw FormatError("Extra character at the end of line");
1153 1153

	
1154 1154
          if (section == "nodes" && !nodes_done) {
1155 1155
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1156 1156
              readNodes();
1157 1157
              nodes_done = true;
1158 1158
            }
1159 1159
          } else if ((section == "arcs" || section == "edges") &&
1160 1160
                     !arcs_done) {
1161 1161
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1162 1162
              readArcs();
1163 1163
              arcs_done = true;
1164 1164
            }
1165 1165
          } else if (section == "attributes" && !attributes_done) {
1166 1166
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1167 1167
              readAttributes();
1168 1168
              attributes_done = true;
1169 1169
            }
1170 1170
          } else {
1171 1171
            readLine();
1172 1172
            skipSection();
1173 1173
          }
1174 1174
        } catch (FormatError& error) {
1175 1175
          error.line(line_num);
1176 1176
          error.file(_filename);
1177 1177
          throw;
1178 1178
        }
1179 1179
      }
1180 1180

	
1181 1181
      if (!nodes_done) {
1182 1182
        throw FormatError("Section @nodes not found");
1183 1183
      }
1184 1184

	
1185 1185
      if (!arcs_done) {
1186 1186
        throw FormatError("Section @arcs not found");
1187 1187
      }
1188 1188

	
1189 1189
      if (!attributes_done && !_attributes.empty()) {
1190 1190
        throw FormatError("Section @attributes not found");
1191 1191
      }
1192 1192

	
1193 1193
    }
1194 1194

	
1195 1195
    /// @}
1196 1196

	
1197 1197
  };
1198 1198

	
1199 1199
  /// \brief Return a \ref DigraphReader class
1200 1200
  ///
1201 1201
  /// This function just returns a \ref DigraphReader class.
1202 1202
  /// \relates DigraphReader
1203 1203
  template <typename Digraph>
1204 1204
  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
1205 1205
    DigraphReader<Digraph> tmp(digraph, is);
1206 1206
    return tmp;
1207 1207
  }
1208 1208

	
1209 1209
  /// \brief Return a \ref DigraphReader class
1210 1210
  ///
1211 1211
  /// This function just returns a \ref DigraphReader class.
1212 1212
  /// \relates DigraphReader
1213 1213
  template <typename Digraph>
1214 1214
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
1215 1215
                                       const std::string& fn) {
1216 1216
    DigraphReader<Digraph> tmp(digraph, fn);
1217 1217
    return tmp;
1218 1218
  }
1219 1219

	
1220 1220
  /// \brief Return a \ref DigraphReader class
1221 1221
  ///
1222 1222
  /// This function just returns a \ref DigraphReader class.
1223 1223
  /// \relates DigraphReader
1224 1224
  template <typename Digraph>
1225 1225
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
1226 1226
    DigraphReader<Digraph> tmp(digraph, fn);
1227 1227
    return tmp;
1228 1228
  }
1229 1229

	
1230 1230
  template <typename Graph>
1231 1231
  class GraphReader;
1232
 
1232

	
1233 1233
  template <typename Graph>
1234
  GraphReader<Graph> graphReader(Graph& graph, 
1234
  GraphReader<Graph> graphReader(Graph& graph,
1235 1235
                                 std::istream& is = std::cin);
1236 1236
  template <typename Graph>
1237 1237
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1238 1238
  template <typename Graph>
1239 1239
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1240 1240

	
1241 1241
  /// \ingroup lemon_io
1242 1242
  ///
1243 1243
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1244 1244
  ///
1245 1245
  /// This utility reads an \ref lgf-format "LGF" file.
1246 1246
  ///
1247 1247
  /// It can be used almost the same way as \c DigraphReader.
1248 1248
  /// The only difference is that this class can handle edges and
1249 1249
  /// edge maps as well as arcs and arc maps.
1250 1250
  ///
1251 1251
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1252 1252
  /// edge maps. However, if there are two maps with the same name
1253 1253
  /// prefixed with \c '+' and \c '-', then these can be read into an
1254 1254
  /// arc map.  Similarly, an attribute can be read into an arc, if
1255 1255
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1256 1256
  template <typename _Graph>
1257 1257
  class GraphReader {
1258 1258
  public:
1259 1259

	
1260 1260
    typedef _Graph Graph;
1261 1261
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1262 1262

	
1263 1263
  private:
1264 1264

	
1265 1265
    std::istream* _is;
1266 1266
    bool local_is;
1267 1267
    std::string _filename;
1268 1268

	
1269 1269
    Graph& _graph;
1270 1270

	
1271 1271
    std::string _nodes_caption;
1272 1272
    std::string _edges_caption;
1273 1273
    std::string _attributes_caption;
1274 1274

	
1275 1275
    typedef std::map<std::string, Node> NodeIndex;
1276 1276
    NodeIndex _node_index;
1277 1277
    typedef std::map<std::string, Edge> EdgeIndex;
1278 1278
    EdgeIndex _edge_index;
1279 1279

	
1280 1280
    typedef std::vector<std::pair<std::string,
1281 1281
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1282 1282
    NodeMaps _node_maps;
1283 1283

	
1284 1284
    typedef std::vector<std::pair<std::string,
1285 1285
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1286 1286
    EdgeMaps _edge_maps;
1287 1287

	
1288 1288
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1289 1289
      Attributes;
1290 1290
    Attributes _attributes;
1291 1291

	
1292 1292
    bool _use_nodes;
1293 1293
    bool _use_edges;
1294 1294

	
1295 1295
    bool _skip_nodes;
1296 1296
    bool _skip_edges;
1297 1297

	
1298 1298
    int line_num;
1299 1299
    std::istringstream line;
1300 1300

	
1301 1301
  public:
1302 1302

	
1303 1303
    /// \brief Constructor
1304 1304
    ///
1305 1305
    /// Construct an undirected graph reader, which reads from the given
1306 1306
    /// input stream.
1307 1307
    GraphReader(Graph& graph, std::istream& is = std::cin)
1308 1308
      : _is(&is), local_is(false), _graph(graph),
1309 1309
        _use_nodes(false), _use_edges(false),
1310 1310
        _skip_nodes(false), _skip_edges(false) {}
1311 1311

	
1312 1312
    /// \brief Constructor
1313 1313
    ///
1314 1314
    /// Construct an undirected graph reader, which reads from the given
1315 1315
    /// file.
1316 1316
    GraphReader(Graph& graph, const std::string& fn)
1317 1317
      : _is(new std::ifstream(fn.c_str())), local_is(true),
1318 1318
        _filename(fn), _graph(graph),
1319 1319
        _use_nodes(false), _use_edges(false),
1320 1320
        _skip_nodes(false), _skip_edges(false) {
1321 1321
      if (!(*_is)) {
1322 1322
        delete _is;
1323 1323
        throw IoError("Cannot open file", fn);
1324 1324
      }
1325 1325
    }
1326 1326

	
1327 1327
    /// \brief Constructor
1328 1328
    ///
1329 1329
    /// Construct an undirected graph reader, which reads from the given
1330 1330
    /// file.
1331 1331
    GraphReader(Graph& graph, const char* fn)
1332 1332
      : _is(new std::ifstream(fn)), local_is(true),
1333 1333
        _filename(fn), _graph(graph),
1334 1334
        _use_nodes(false), _use_edges(false),
1335 1335
        _skip_nodes(false), _skip_edges(false) {
1336 1336
      if (!(*_is)) {
1337 1337
        delete _is;
1338 1338
        throw IoError("Cannot open file", fn);
1339 1339
      }
1340 1340
    }
1341 1341

	
1342 1342
    /// \brief Destructor
1343 1343
    ~GraphReader() {
1344 1344
      for (typename NodeMaps::iterator it = _node_maps.begin();
1345 1345
           it != _node_maps.end(); ++it) {
1346 1346
        delete it->second;
1347 1347
      }
1348 1348

	
1349 1349
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1350 1350
           it != _edge_maps.end(); ++it) {
1351 1351
        delete it->second;
1352 1352
      }
1353 1353

	
1354 1354
      for (typename Attributes::iterator it = _attributes.begin();
1355 1355
           it != _attributes.end(); ++it) {
1356 1356
        delete it->second;
1357 1357
      }
1358 1358

	
1359 1359
      if (local_is) {
1360 1360
        delete _is;
1361 1361
      }
1362 1362

	
1363 1363
    }
1364 1364

	
1365 1365
  private:
1366 1366
    template <typename GR>
1367 1367
    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
1368 1368
    template <typename GR>
1369
    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
1369
    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn);
1370 1370
    template <typename GR>
1371 1371
    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
1372 1372

	
1373 1373
    GraphReader(GraphReader& other)
1374 1374
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1375 1375
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1376 1376
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1377 1377

	
1378 1378
      other._is = 0;
1379 1379
      other.local_is = false;
1380 1380

	
1381 1381
      _node_index.swap(other._node_index);
1382 1382
      _edge_index.swap(other._edge_index);
1383 1383

	
1384 1384
      _node_maps.swap(other._node_maps);
1385 1385
      _edge_maps.swap(other._edge_maps);
1386 1386
      _attributes.swap(other._attributes);
1387 1387

	
1388 1388
      _nodes_caption = other._nodes_caption;
1389 1389
      _edges_caption = other._edges_caption;
1390 1390
      _attributes_caption = other._attributes_caption;
1391 1391

	
1392 1392
    }
1393 1393

	
1394 1394
    GraphReader& operator=(const GraphReader&);
1395 1395

	
1396 1396
  public:
1397 1397

	
1398 1398
    /// \name Reading rules
1399 1399
    /// @{
1400 1400

	
1401 1401
    /// \brief Node map reading rule
1402 1402
    ///
1403 1403
    /// Add a node map reading rule to the reader.
1404 1404
    template <typename Map>
1405 1405
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1406 1406
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1407 1407
      _reader_bits::MapStorageBase<Node>* storage =
1408 1408
        new _reader_bits::MapStorage<Node, Map>(map);
1409 1409
      _node_maps.push_back(std::make_pair(caption, storage));
1410 1410
      return *this;
1411 1411
    }
1412 1412

	
1413 1413
    /// \brief Node map reading rule
1414 1414
    ///
1415 1415
    /// Add a node map reading rule with specialized converter to the
1416 1416
    /// reader.
1417 1417
    template <typename Map, typename Converter>
1418 1418
    GraphReader& nodeMap(const std::string& caption, Map& map,
1419 1419
                           const Converter& converter = Converter()) {
1420 1420
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1421 1421
      _reader_bits::MapStorageBase<Node>* storage =
1422 1422
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1423 1423
      _node_maps.push_back(std::make_pair(caption, storage));
1424 1424
      return *this;
1425 1425
    }
1426 1426

	
1427 1427
    /// \brief Edge map reading rule
1428 1428
    ///
1429 1429
    /// Add an edge map reading rule to the reader.
1430 1430
    template <typename Map>
1431 1431
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1432 1432
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1433 1433
      _reader_bits::MapStorageBase<Edge>* storage =
1434 1434
        new _reader_bits::MapStorage<Edge, Map>(map);
1435 1435
      _edge_maps.push_back(std::make_pair(caption, storage));
1436 1436
      return *this;
1437 1437
    }
1438 1438

	
1439 1439
    /// \brief Edge map reading rule
1440 1440
    ///
1441 1441
    /// Add an edge map reading rule with specialized converter to the
1442 1442
    /// reader.
1443 1443
    template <typename Map, typename Converter>
1444 1444
    GraphReader& edgeMap(const std::string& caption, Map& map,
1445 1445
                          const Converter& converter = Converter()) {
1446 1446
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1447 1447
      _reader_bits::MapStorageBase<Edge>* storage =
1448 1448
        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1449 1449
      _edge_maps.push_back(std::make_pair(caption, storage));
1450 1450
      return *this;
1451 1451
    }
1452 1452

	
1453 1453
    /// \brief Arc map reading rule
1454 1454
    ///
1455 1455
    /// Add an arc map reading rule to the reader.
1456 1456
    template <typename Map>
1457 1457
    GraphReader& arcMap(const std::string& caption, Map& map) {
1458 1458
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1459 1459
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1460 1460
        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1461 1461
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1462 1462
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1463 1463
        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1464 1464
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1465 1465
      return *this;
1466 1466
    }
1467 1467

	
1468 1468
    /// \brief Arc map reading rule
1469 1469
    ///
1470 1470
    /// Add an arc map reading rule with specialized converter to the
1471 1471
    /// reader.
1472 1472
    template <typename Map, typename Converter>
1473 1473
    GraphReader& arcMap(const std::string& caption, Map& map,
1474 1474
                          const Converter& converter = Converter()) {
1475 1475
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1476 1476
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1477 1477
        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1478 1478
        (_graph, map, converter);
1479 1479
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1480 1480
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1481 1481
        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1482 1482
        (_graph, map, converter);
1483 1483
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1484 1484
      return *this;
1485 1485
    }
1486 1486

	
1487 1487
    /// \brief Attribute reading rule
1488 1488
    ///
1489 1489
    /// Add an attribute reading rule to the reader.
1490 1490
    template <typename Value>
1491 1491
    GraphReader& attribute(const std::string& caption, Value& value) {
1492 1492
      _reader_bits::ValueStorageBase* storage =
1493 1493
        new _reader_bits::ValueStorage<Value>(value);
1494 1494
      _attributes.insert(std::make_pair(caption, storage));
1495 1495
      return *this;
1496 1496
    }
1497 1497

	
1498 1498
    /// \brief Attribute reading rule
1499 1499
    ///
1500 1500
    /// Add an attribute reading rule with specialized converter to the
1501 1501
    /// reader.
1502 1502
    template <typename Value, typename Converter>
1503 1503
    GraphReader& attribute(const std::string& caption, Value& value,
1504 1504
                             const Converter& converter = Converter()) {
1505 1505
      _reader_bits::ValueStorageBase* storage =
1506 1506
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1507 1507
      _attributes.insert(std::make_pair(caption, storage));
1508 1508
      return *this;
1509 1509
    }
1510 1510

	
1511 1511
    /// \brief Node reading rule
1512 1512
    ///
1513 1513
    /// Add a node reading rule to reader.
1514 1514
    GraphReader& node(const std::string& caption, Node& node) {
1515 1515
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1516 1516
      Converter converter(_node_index);
1517 1517
      _reader_bits::ValueStorageBase* storage =
1518 1518
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1519 1519
      _attributes.insert(std::make_pair(caption, storage));
1520 1520
      return *this;
1521 1521
    }
1522 1522

	
1523 1523
    /// \brief Edge reading rule
1524 1524
    ///
1525 1525
    /// Add an edge reading rule to reader.
1526 1526
    GraphReader& edge(const std::string& caption, Edge& edge) {
1527 1527
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1528 1528
      Converter converter(_edge_index);
1529 1529
      _reader_bits::ValueStorageBase* storage =
1530 1530
        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1531 1531
      _attributes.insert(std::make_pair(caption, storage));
1532 1532
      return *this;
1533 1533
    }
1534 1534

	
1535 1535
    /// \brief Arc reading rule
1536 1536
    ///
1537 1537
    /// Add an arc reading rule to reader.
1538 1538
    GraphReader& arc(const std::string& caption, Arc& arc) {
1539 1539
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1540 1540
      Converter converter(_graph, _edge_index);
1541 1541
      _reader_bits::ValueStorageBase* storage =
1542 1542
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1543 1543
      _attributes.insert(std::make_pair(caption, storage));
1544 1544
      return *this;
1545 1545
    }
1546 1546

	
1547 1547
    /// @}
1548 1548

	
1549 1549
    /// \name Select section by name
1550 1550
    /// @{
1551 1551

	
1552 1552
    /// \brief Set \c \@nodes section to be read
1553 1553
    ///
1554 1554
    /// Set \c \@nodes section to be read.
1555 1555
    GraphReader& nodes(const std::string& caption) {
1556 1556
      _nodes_caption = caption;
1557 1557
      return *this;
1558 1558
    }
1559 1559

	
1560 1560
    /// \brief Set \c \@edges section to be read
1561 1561
    ///
1562 1562
    /// Set \c \@edges section to be read.
1563 1563
    GraphReader& edges(const std::string& caption) {
1564 1564
      _edges_caption = caption;
1565 1565
      return *this;
1566 1566
    }
1567 1567

	
1568 1568
    /// \brief Set \c \@attributes section to be read
1569 1569
    ///
1570 1570
    /// Set \c \@attributes section to be read.
1571 1571
    GraphReader& attributes(const std::string& caption) {
1572 1572
      _attributes_caption = caption;
1573 1573
      return *this;
1574 1574
    }
1575 1575

	
1576 1576
    /// @}
1577 1577

	
1578 1578
    /// \name Using previously constructed node or edge set
1579 1579
    /// @{
1580 1580

	
1581 1581
    /// \brief Use previously constructed node set
1582 1582
    ///
1583 1583
    /// Use previously constructed node set, and specify the node
1584 1584
    /// label map.
1585 1585
    template <typename Map>
1586 1586
    GraphReader& useNodes(const Map& map) {
1587 1587
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1588 1588
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1589 1589
      _use_nodes = true;
1590 1590
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1591 1591
      for (NodeIt n(_graph); n != INVALID; ++n) {
1592 1592
        _node_index.insert(std::make_pair(converter(map[n]), n));
1593 1593
      }
1594 1594
      return *this;
1595 1595
    }
1596 1596

	
1597 1597
    /// \brief Use previously constructed node set
1598 1598
    ///
1599 1599
    /// Use previously constructed node set, and specify the node
1600 1600
    /// label map and a functor which converts the label map values to
1601 1601
    /// \c std::string.
1602 1602
    template <typename Map, typename Converter>
1603 1603
    GraphReader& useNodes(const Map& map,
1604 1604
                            const Converter& converter = Converter()) {
1605 1605
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1606 1606
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1607 1607
      _use_nodes = true;
1608 1608
      for (NodeIt n(_graph); n != INVALID; ++n) {
1609 1609
        _node_index.insert(std::make_pair(converter(map[n]), n));
1610 1610
      }
1611 1611
      return *this;
1612 1612
    }
1613 1613

	
1614 1614
    /// \brief Use previously constructed edge set
1615 1615
    ///
1616 1616
    /// Use previously constructed edge set, and specify the edge
1617 1617
    /// label map.
1618 1618
    template <typename Map>
1619 1619
    GraphReader& useEdges(const Map& map) {
1620 1620
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1621 1621
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1622 1622
      _use_edges = true;
1623 1623
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1624 1624
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1625 1625
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1626 1626
      }
1627 1627
      return *this;
1628 1628
    }
1629 1629

	
1630 1630
    /// \brief Use previously constructed edge set
1631 1631
    ///
1632 1632
    /// Use previously constructed edge set, and specify the edge
1633 1633
    /// label map and a functor which converts the label map values to
1634 1634
    /// \c std::string.
1635 1635
    template <typename Map, typename Converter>
1636 1636
    GraphReader& useEdges(const Map& map,
1637 1637
                            const Converter& converter = Converter()) {
1638 1638
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1639 1639
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1640 1640
      _use_edges = true;
1641 1641
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1642 1642
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1643 1643
      }
1644 1644
      return *this;
1645 1645
    }
1646 1646

	
1647 1647
    /// \brief Skip the reading of node section
1648 1648
    ///
1649 1649
    /// Omit the reading of the node section. This implies that each node
1650 1650
    /// map reading rule will be abandoned, and the nodes of the graph
1651 1651
    /// will not be constructed, which usually cause that the edge set
1652 1652
    /// could not be read due to lack of node name
1653 1653
    /// could not be read due to lack of node name resolving.
1654 1654
    /// Therefore \c skipEdges() function should also be used, or
1655 1655
    /// \c useNodes() should be used to specify the label of the nodes.
1656 1656
    GraphReader& skipNodes() {
1657 1657
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1658 1658
      _skip_nodes = true;
1659 1659
      return *this;
1660 1660
    }
1661 1661

	
1662 1662
    /// \brief Skip the reading of edge section
1663 1663
    ///
1664 1664
    /// Omit the reading of the edge section. This implies that each edge
1665 1665
    /// map reading rule will be abandoned, and the edges of the graph
1666 1666
    /// will not be constructed.
1667 1667
    GraphReader& skipEdges() {
1668 1668
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1669 1669
      _skip_edges = true;
1670 1670
      return *this;
1671 1671
    }
1672 1672

	
1673 1673
    /// @}
1674 1674

	
1675 1675
  private:
1676 1676

	
1677 1677
    bool readLine() {
1678 1678
      std::string str;
1679 1679
      while(++line_num, std::getline(*_is, str)) {
1680 1680
        line.clear(); line.str(str);
1681 1681
        char c;
1682 1682
        if (line >> std::ws >> c && c != '#') {
1683 1683
          line.putback(c);
1684 1684
          return true;
1685 1685
        }
1686 1686
      }
1687 1687
      return false;
1688 1688
    }
1689 1689

	
1690 1690
    bool readSuccess() {
1691 1691
      return static_cast<bool>(*_is);
1692 1692
    }
1693 1693

	
1694 1694
    void skipSection() {
1695 1695
      char c;
1696 1696
      while (readSuccess() && line >> c && c != '@') {
1697 1697
        readLine();
1698 1698
      }
1699 1699
      if (readSuccess()) {
1700 1700
        line.putback(c);
1701 1701
      }
1702 1702
    }
1703 1703

	
1704 1704
    void readNodes() {
1705 1705

	
1706 1706
      std::vector<int> map_index(_node_maps.size());
1707 1707
      int map_num, label_index;
1708 1708

	
1709 1709
      char c;
1710 1710
      if (!readLine() || !(line >> c) || c == '@') {
1711 1711
        if (readSuccess() && line) line.putback(c);
1712 1712
        if (!_node_maps.empty())
1713 1713
          throw FormatError("Cannot find map names");
1714 1714
        return;
1715 1715
      }
1716 1716
      line.putback(c);
1717 1717

	
1718 1718
      {
1719 1719
        std::map<std::string, int> maps;
1720 1720

	
1721 1721
        std::string map;
1722 1722
        int index = 0;
1723 1723
        while (_reader_bits::readToken(line, map)) {
1724 1724
          if (maps.find(map) != maps.end()) {
1725 1725
            std::ostringstream msg;
1726 1726
            msg << "Multiple occurence of node map: " << map;
1727 1727
            throw FormatError(msg.str());
1728 1728
          }
1729 1729
          maps.insert(std::make_pair(map, index));
1730 1730
          ++index;
1731 1731
        }
1732 1732

	
1733 1733
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1734 1734
          std::map<std::string, int>::iterator jt =
1735 1735
            maps.find(_node_maps[i].first);
1736 1736
          if (jt == maps.end()) {
1737 1737
            std::ostringstream msg;
1738 1738
            msg << "Map not found: " << _node_maps[i].first;
1739 1739
            throw FormatError(msg.str());
1740 1740
          }
1741 1741
          map_index[i] = jt->second;
1742 1742
        }
1743 1743

	
1744 1744
        {
1745 1745
          std::map<std::string, int>::iterator jt = maps.find("label");
1746 1746
          if (jt != maps.end()) {
1747 1747
            label_index = jt->second;
1748 1748
          } else {
1749 1749
            label_index = -1;
1750 1750
          }
1751 1751
        }
1752 1752
        map_num = maps.size();
1753 1753
      }
1754 1754

	
1755 1755
      while (readLine() && line >> c && c != '@') {
1756 1756
        line.putback(c);
1757 1757

	
1758 1758
        std::vector<std::string> tokens(map_num);
1759 1759
        for (int i = 0; i < map_num; ++i) {
1760 1760
          if (!_reader_bits::readToken(line, tokens[i])) {
1761 1761
            std::ostringstream msg;
1762 1762
            msg << "Column not found (" << i + 1 << ")";
1763 1763
            throw FormatError(msg.str());
1764 1764
          }
1765 1765
        }
1766 1766
        if (line >> std::ws >> c)
1767 1767
          throw FormatError("Extra character at the end of line");
1768 1768

	
1769 1769
        Node n;
1770 1770
        if (!_use_nodes) {
1771 1771
          n = _graph.addNode();
1772 1772
          if (label_index != -1)
1773 1773
            _node_index.insert(std::make_pair(tokens[label_index], n));
1774 1774
        } else {
1775 1775
          if (label_index == -1)
1776 1776
            throw FormatError("Label map not found");
1777 1777
          typename std::map<std::string, Node>::iterator it =
1778 1778
            _node_index.find(tokens[label_index]);
1779 1779
          if (it == _node_index.end()) {
1780 1780
            std::ostringstream msg;
1781 1781
            msg << "Node with label not found: " << tokens[label_index];
1782 1782
            throw FormatError(msg.str());
1783 1783
          }
1784 1784
          n = it->second;
1785 1785
        }
1786 1786

	
1787 1787
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1788 1788
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1789 1789
        }
1790 1790

	
1791 1791
      }
1792 1792
      if (readSuccess()) {
1793 1793
        line.putback(c);
1794 1794
      }
1795 1795
    }
1796 1796

	
1797 1797
    void readEdges() {
1798 1798

	
1799 1799
      std::vector<int> map_index(_edge_maps.size());
1800 1800
      int map_num, label_index;
1801 1801

	
1802 1802
      char c;
1803 1803
      if (!readLine() || !(line >> c) || c == '@') {
1804 1804
        if (readSuccess() && line) line.putback(c);
1805 1805
        if (!_edge_maps.empty())
1806 1806
          throw FormatError("Cannot find map names");
1807 1807
        return;
1808 1808
      }
1809 1809
      line.putback(c);
1810 1810

	
1811 1811
      {
1812 1812
        std::map<std::string, int> maps;
1813 1813

	
1814 1814
        std::string map;
1815 1815
        int index = 0;
1816 1816
        while (_reader_bits::readToken(line, map)) {
1817 1817
          if(map == "-") {
1818 1818
              if(index!=0)
1819 1819
                throw FormatError("'-' is not allowed as a map name");
1820 1820
              else if (line >> std::ws >> c)
1821 1821
                throw FormatError("Extra character at the end of line");
1822 1822
              else break;
1823 1823
            }
1824 1824
          if (maps.find(map) != maps.end()) {
1825 1825
            std::ostringstream msg;
1826 1826
            msg << "Multiple occurence of edge map: " << map;
1827 1827
            throw FormatError(msg.str());
1828 1828
          }
1829 1829
          maps.insert(std::make_pair(map, index));
1830 1830
          ++index;
1831 1831
        }
1832 1832

	
1833 1833
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1834 1834
          std::map<std::string, int>::iterator jt =
1835 1835
            maps.find(_edge_maps[i].first);
1836 1836
          if (jt == maps.end()) {
1837 1837
            std::ostringstream msg;
1838 1838
            msg << "Map not found: " << _edge_maps[i].first;
1839 1839
            throw FormatError(msg.str());
1840 1840
          }
1841 1841
          map_index[i] = jt->second;
1842 1842
        }
1843 1843

	
1844 1844
        {
1845 1845
          std::map<std::string, int>::iterator jt = maps.find("label");
1846 1846
          if (jt != maps.end()) {
1847 1847
            label_index = jt->second;
1848 1848
          } else {
1849 1849
            label_index = -1;
1850 1850
          }
1851 1851
        }
1852 1852
        map_num = maps.size();
1853 1853
      }
1854 1854

	
1855 1855
      while (readLine() && line >> c && c != '@') {
1856 1856
        line.putback(c);
1857 1857

	
1858 1858
        std::string source_token;
1859 1859
        std::string target_token;
1860 1860

	
1861 1861
        if (!_reader_bits::readToken(line, source_token))
1862 1862
          throw FormatError("Node u not found");
1863 1863

	
1864 1864
        if (!_reader_bits::readToken(line, target_token))
1865 1865
          throw FormatError("Node v not found");
1866 1866

	
1867 1867
        std::vector<std::string> tokens(map_num);
1868 1868
        for (int i = 0; i < map_num; ++i) {
1869 1869
          if (!_reader_bits::readToken(line, tokens[i])) {
1870 1870
            std::ostringstream msg;
1871 1871
            msg << "Column not found (" << i + 1 << ")";
1872 1872
            throw FormatError(msg.str());
1873 1873
          }
1874 1874
        }
1875 1875
        if (line >> std::ws >> c)
1876 1876
          throw FormatError("Extra character at the end of line");
1877 1877

	
1878 1878
        Edge e;
1879 1879
        if (!_use_edges) {
1880 1880

	
1881 1881
          typename NodeIndex::iterator it;
1882 1882

	
1883 1883
          it = _node_index.find(source_token);
1884 1884
          if (it == _node_index.end()) {
1885 1885
            std::ostringstream msg;
1886 1886
            msg << "Item not found: " << source_token;
1887 1887
            throw FormatError(msg.str());
1888 1888
          }
1889 1889
          Node source = it->second;
1890 1890

	
1891 1891
          it = _node_index.find(target_token);
1892 1892
          if (it == _node_index.end()) {
1893 1893
            std::ostringstream msg;
1894 1894
            msg << "Item not found: " << target_token;
1895 1895
            throw FormatError(msg.str());
1896 1896
          }
1897 1897
          Node target = it->second;
1898 1898

	
1899 1899
          e = _graph.addEdge(source, target);
1900 1900
          if (label_index != -1)
1901 1901
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1902 1902
        } else {
1903 1903
          if (label_index == -1)
1904 1904
            throw FormatError("Label map not found");
1905 1905
          typename std::map<std::string, Edge>::iterator it =
1906 1906
            _edge_index.find(tokens[label_index]);
1907 1907
          if (it == _edge_index.end()) {
1908 1908
            std::ostringstream msg;
1909 1909
            msg << "Edge with label not found: " << tokens[label_index];
1910 1910
            throw FormatError(msg.str());
1911 1911
          }
1912 1912
          e = it->second;
1913 1913
        }
1914 1914

	
1915 1915
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1916 1916
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1917 1917
        }
1918 1918

	
1919 1919
      }
1920 1920
      if (readSuccess()) {
1921 1921
        line.putback(c);
1922 1922
      }
1923 1923
    }
1924 1924

	
1925 1925
    void readAttributes() {
1926 1926

	
1927 1927
      std::set<std::string> read_attr;
1928 1928

	
1929 1929
      char c;
1930 1930
      while (readLine() && line >> c && c != '@') {
1931 1931
        line.putback(c);
1932 1932

	
1933 1933
        std::string attr, token;
1934 1934
        if (!_reader_bits::readToken(line, attr))
1935 1935
          throw FormatError("Attribute name not found");
1936 1936
        if (!_reader_bits::readToken(line, token))
1937 1937
          throw FormatError("Attribute value not found");
1938 1938
        if (line >> c)
1939 1939
          throw FormatError("Extra character at the end of line");
1940 1940

	
1941 1941
        {
1942 1942
          std::set<std::string>::iterator it = read_attr.find(attr);
1943 1943
          if (it != read_attr.end()) {
1944 1944
            std::ostringstream msg;
1945 1945
            msg << "Multiple occurence of attribute: " << attr;
1946 1946
            throw FormatError(msg.str());
1947 1947
          }
1948 1948
          read_attr.insert(attr);
1949 1949
        }
1950 1950

	
1951 1951
        {
1952 1952
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1953 1953
          while (it != _attributes.end() && it->first == attr) {
1954 1954
            it->second->set(token);
1955 1955
            ++it;
1956 1956
          }
1957 1957
        }
1958 1958

	
1959 1959
      }
1960 1960
      if (readSuccess()) {
1961 1961
        line.putback(c);
1962 1962
      }
1963 1963
      for (typename Attributes::iterator it = _attributes.begin();
1964 1964
           it != _attributes.end(); ++it) {
1965 1965
        if (read_attr.find(it->first) == read_attr.end()) {
1966 1966
          std::ostringstream msg;
1967 1967
          msg << "Attribute not found: " << it->first;
1968 1968
          throw FormatError(msg.str());
1969 1969
        }
1970 1970
      }
1971 1971
    }
1972 1972

	
1973 1973
  public:
1974 1974

	
1975 1975
    /// \name Execution of the reader
1976 1976
    /// @{
1977 1977

	
1978 1978
    /// \brief Start the batch processing
1979 1979
    ///
1980 1980
    /// This function starts the batch processing
1981 1981
    void run() {
1982 1982

	
1983 1983
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1984 1984

	
1985 1985
      bool nodes_done = _skip_nodes;
1986 1986
      bool edges_done = _skip_edges;
1987 1987
      bool attributes_done = false;
1988 1988

	
1989 1989
      line_num = 0;
1990 1990
      readLine();
1991 1991
      skipSection();
1992 1992

	
1993 1993
      while (readSuccess()) {
1994 1994
        try {
1995 1995
          char c;
1996 1996
          std::string section, caption;
1997 1997
          line >> c;
1998 1998
          _reader_bits::readToken(line, section);
1999 1999
          _reader_bits::readToken(line, caption);
2000 2000

	
2001 2001
          if (line >> c)
2002 2002
            throw FormatError("Extra character at the end of line");
2003 2003

	
2004 2004
          if (section == "nodes" && !nodes_done) {
2005 2005
            if (_nodes_caption.empty() || _nodes_caption == caption) {
2006 2006
              readNodes();
2007 2007
              nodes_done = true;
2008 2008
            }
2009 2009
          } else if ((section == "edges" || section == "arcs") &&
2010 2010
                     !edges_done) {
2011 2011
            if (_edges_caption.empty() || _edges_caption == caption) {
2012 2012
              readEdges();
2013 2013
              edges_done = true;
2014 2014
            }
2015 2015
          } else if (section == "attributes" && !attributes_done) {
2016 2016
            if (_attributes_caption.empty() || _attributes_caption == caption) {
2017 2017
              readAttributes();
2018 2018
              attributes_done = true;
2019 2019
            }
2020 2020
          } else {
2021 2021
            readLine();
2022 2022
            skipSection();
2023 2023
          }
2024 2024
        } catch (FormatError& error) {
2025 2025
          error.line(line_num);
2026 2026
          error.file(_filename);
2027 2027
          throw;
2028 2028
        }
2029 2029
      }
2030 2030

	
2031 2031
      if (!nodes_done) {
2032 2032
        throw FormatError("Section @nodes not found");
2033 2033
      }
2034 2034

	
2035 2035
      if (!edges_done) {
2036 2036
        throw FormatError("Section @edges not found");
2037 2037
      }
2038 2038

	
2039 2039
      if (!attributes_done && !_attributes.empty()) {
2040 2040
        throw FormatError("Section @attributes not found");
2041 2041
      }
2042 2042

	
2043 2043
    }
2044 2044

	
2045 2045
    /// @}
2046 2046

	
2047 2047
  };
2048 2048

	
2049 2049
  /// \brief Return a \ref GraphReader class
2050 2050
  ///
2051 2051
  /// This function just returns a \ref GraphReader class.
2052 2052
  /// \relates GraphReader
2053 2053
  template <typename Graph>
2054 2054
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
2055 2055
    GraphReader<Graph> tmp(graph, is);
2056 2056
    return tmp;
2057 2057
  }
2058 2058

	
2059 2059
  /// \brief Return a \ref GraphReader class
2060 2060
  ///
2061 2061
  /// This function just returns a \ref GraphReader class.
2062 2062
  /// \relates GraphReader
2063 2063
  template <typename Graph>
2064 2064
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
2065 2065
    GraphReader<Graph> tmp(graph, fn);
2066 2066
    return tmp;
2067 2067
  }
2068 2068

	
2069 2069
  /// \brief Return a \ref GraphReader class
2070 2070
  ///
2071 2071
  /// This function just returns a \ref GraphReader class.
2072 2072
  /// \relates GraphReader
2073 2073
  template <typename Graph>
2074 2074
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2075 2075
    GraphReader<Graph> tmp(graph, fn);
2076 2076
    return tmp;
2077 2077
  }
2078 2078

	
2079 2079
  class SectionReader;
2080 2080

	
2081 2081
  SectionReader sectionReader(std::istream& is);
2082 2082
  SectionReader sectionReader(const std::string& fn);
2083 2083
  SectionReader sectionReader(const char* fn);
2084 2084

	
2085 2085
  /// \ingroup lemon_io
2086 2086
  ///
2087 2087
  /// \brief Section reader class
2088 2088
  ///
2089 2089
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2090 2090
  /// which contain any data in arbitrary format. Such sections can be
2091 2091
  /// read with this class. A reading rule can be added to the class
2092 2092
  /// with two different functions. With the \c sectionLines() function a
2093 2093
  /// functor can process the section line-by-line, while with the \c
2094 2094
  /// sectionStream() member the section can be read from an input
2095 2095
  /// stream.
2096 2096
  class SectionReader {
2097 2097
  private:
2098 2098

	
2099 2099
    std::istream* _is;
2100 2100
    bool local_is;
2101 2101
    std::string _filename;
2102 2102

	
2103 2103
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2104 2104
    Sections _sections;
2105 2105

	
2106 2106
    int line_num;
2107 2107
    std::istringstream line;
2108 2108

	
2109 2109
  public:
2110 2110

	
2111 2111
    /// \brief Constructor
2112 2112
    ///
2113 2113
    /// Construct a section reader, which reads from the given input
2114 2114
    /// stream.
2115 2115
    SectionReader(std::istream& is)
2116 2116
      : _is(&is), local_is(false) {}
2117 2117

	
2118 2118
    /// \brief Constructor
2119 2119
    ///
2120 2120
    /// Construct a section reader, which reads from the given file.
2121 2121
    SectionReader(const std::string& fn)
2122 2122
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2123 2123
        _filename(fn) {
2124 2124
      if (!(*_is)) {
2125 2125
        delete _is;
2126 2126
        throw IoError("Cannot open file", fn);
2127 2127
      }
2128 2128
    }
2129 2129

	
2130 2130
    /// \brief Constructor
2131 2131
    ///
2132 2132
    /// Construct a section reader, which reads from the given file.
2133 2133
    SectionReader(const char* fn)
2134 2134
      : _is(new std::ifstream(fn)), local_is(true),
2135 2135
        _filename(fn) {
2136 2136
      if (!(*_is)) {
2137 2137
        delete _is;
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2011
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 lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" writer.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_WRITER_H
25 25
#define LEMON_LGF_WRITER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <algorithm>
32 32

	
33 33
#include <vector>
34 34
#include <functional>
35 35

	
36 36
#include <lemon/core.h>
37 37
#include <lemon/maps.h>
38 38

	
39 39
#include <lemon/concept_check.h>
40 40
#include <lemon/concepts/maps.h>
41 41

	
42 42
namespace lemon {
43 43

	
44 44
  namespace _writer_bits {
45 45

	
46 46
    template <typename Value>
47 47
    struct DefaultConverter {
48 48
      std::string operator()(const Value& value) {
49 49
        std::ostringstream os;
50 50
        os << value;
51 51
        return os.str();
52 52
      }
53 53
    };
54 54

	
55 55
    template <typename T>
56 56
    bool operator<(const T&, const T&) {
57 57
      throw FormatError("Label map is not comparable");
58 58
    }
59 59

	
60 60
    template <typename _Map>
61 61
    class MapLess {
62 62
    public:
63 63
      typedef _Map Map;
64 64
      typedef typename Map::Key Item;
65 65

	
66 66
    private:
67 67
      const Map& _map;
68 68

	
69 69
    public:
70 70
      MapLess(const Map& map) : _map(map) {}
71 71

	
72 72
      bool operator()(const Item& left, const Item& right) {
73 73
        return _map[left] < _map[right];
74 74
      }
75 75
    };
76 76

	
77 77
    template <typename _Graph, bool _dir, typename _Map>
78 78
    class GraphArcMapLess {
79 79
    public:
80 80
      typedef _Map Map;
81 81
      typedef _Graph Graph;
82 82
      typedef typename Graph::Edge Item;
83 83

	
84 84
    private:
85 85
      const Graph& _graph;
86 86
      const Map& _map;
87 87

	
88 88
    public:
89 89
      GraphArcMapLess(const Graph& graph, const Map& map)
90 90
        : _graph(graph), _map(map) {}
91 91

	
92 92
      bool operator()(const Item& left, const Item& right) {
93 93
        return _map[_graph.direct(left, _dir)] <
94 94
          _map[_graph.direct(right, _dir)];
95 95
      }
96 96
    };
97 97

	
98 98
    template <typename _Item>
99 99
    class MapStorageBase {
100 100
    public:
101 101
      typedef _Item Item;
102 102

	
103 103
    public:
104 104
      MapStorageBase() {}
105 105
      virtual ~MapStorageBase() {}
106 106

	
107 107
      virtual std::string get(const Item& item) = 0;
108 108
      virtual void sort(std::vector<Item>&) = 0;
109 109
    };
110 110

	
111 111
    template <typename _Item, typename _Map,
112 112
              typename _Converter = DefaultConverter<typename _Map::Value> >
113 113
    class MapStorage : public MapStorageBase<_Item> {
114 114
    public:
115 115
      typedef _Map Map;
116 116
      typedef _Converter Converter;
117 117
      typedef _Item Item;
118 118

	
119 119
    private:
120 120
      const Map& _map;
121 121
      Converter _converter;
122 122

	
123 123
    public:
124 124
      MapStorage(const Map& map, const Converter& converter = Converter())
125 125
        : _map(map), _converter(converter) {}
126 126
      virtual ~MapStorage() {}
127 127

	
128 128
      virtual std::string get(const Item& item) {
129 129
        return _converter(_map[item]);
130 130
      }
131 131
      virtual void sort(std::vector<Item>& items) {
132 132
        MapLess<Map> less(_map);
133 133
        std::sort(items.begin(), items.end(), less);
134 134
      }
135 135
    };
136 136

	
137 137
    template <typename _Graph, bool _dir, typename _Map,
138 138
              typename _Converter = DefaultConverter<typename _Map::Value> >
139 139
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
140 140
    public:
141 141
      typedef _Map Map;
142 142
      typedef _Converter Converter;
143 143
      typedef _Graph Graph;
144 144
      typedef typename Graph::Edge Item;
145 145
      static const bool dir = _dir;
146 146

	
147 147
    private:
148 148
      const Graph& _graph;
149 149
      const Map& _map;
150 150
      Converter _converter;
151 151

	
152 152
    public:
153 153
      GraphArcMapStorage(const Graph& graph, const Map& map,
154 154
                         const Converter& converter = Converter())
155 155
        : _graph(graph), _map(map), _converter(converter) {}
156 156
      virtual ~GraphArcMapStorage() {}
157 157

	
158 158
      virtual std::string get(const Item& item) {
159 159
        return _converter(_map[_graph.direct(item, dir)]);
160 160
      }
161 161
      virtual void sort(std::vector<Item>& items) {
162 162
        GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
163 163
        std::sort(items.begin(), items.end(), less);
164 164
      }
165 165
    };
166 166

	
167 167
    class ValueStorageBase {
168 168
    public:
169 169
      ValueStorageBase() {}
170 170
      virtual ~ValueStorageBase() {}
171 171

	
172 172
      virtual std::string get() = 0;
173 173
    };
174 174

	
175 175
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
176 176
    class ValueStorage : public ValueStorageBase {
177 177
    public:
178 178
      typedef _Value Value;
179 179
      typedef _Converter Converter;
180 180

	
181 181
    private:
182 182
      const Value& _value;
183 183
      Converter _converter;
184 184

	
185 185
    public:
186 186
      ValueStorage(const Value& value, const Converter& converter = Converter())
187 187
        : _value(value), _converter(converter) {}
188 188

	
189 189
      virtual std::string get() {
190 190
        return _converter(_value);
191 191
      }
192 192
    };
193 193

	
194 194
    template <typename Value>
195 195
    struct MapLookUpConverter {
196 196
      const std::map<Value, std::string>& _map;
197 197

	
198 198
      MapLookUpConverter(const std::map<Value, std::string>& map)
199 199
        : _map(map) {}
200 200

	
201 201
      std::string operator()(const Value& str) {
202 202
        typename std::map<Value, std::string>::const_iterator it =
203 203
          _map.find(str);
204 204
        if (it == _map.end()) {
205 205
          throw FormatError("Item not found");
206 206
        }
207 207
        return it->second;
208 208
      }
209 209
    };
210 210

	
211 211
    template <typename Graph>
212 212
    struct GraphArcLookUpConverter {
213 213
      const Graph& _graph;
214 214
      const std::map<typename Graph::Edge, std::string>& _map;
215 215

	
216 216
      GraphArcLookUpConverter(const Graph& graph,
217 217
                              const std::map<typename Graph::Edge,
218 218
                                             std::string>& map)
219 219
        : _graph(graph), _map(map) {}
220 220

	
221 221
      std::string operator()(const typename Graph::Arc& val) {
222 222
        typename std::map<typename Graph::Edge, std::string>
223 223
          ::const_iterator it = _map.find(val);
224 224
        if (it == _map.end()) {
225 225
          throw FormatError("Item not found");
226 226
        }
227 227
        return (_graph.direction(val) ? '+' : '-') + it->second;
228 228
      }
229 229
    };
230 230

	
231 231
    inline bool isWhiteSpace(char c) {
232 232
      return c == ' ' || c == '\t' || c == '\v' ||
233 233
        c == '\n' || c == '\r' || c == '\f';
234 234
    }
235 235

	
236 236
    inline bool isEscaped(char c) {
237 237
      return c == '\\' || c == '\"' || c == '\'' ||
238 238
        c == '\a' || c == '\b';
239 239
    }
240 240

	
241 241
    inline static void writeEscape(std::ostream& os, char c) {
242 242
      switch (c) {
243 243
      case '\\':
244 244
        os << "\\\\";
245 245
        return;
246 246
      case '\"':
247 247
        os << "\\\"";
248 248
        return;
249 249
      case '\a':
250 250
        os << "\\a";
251 251
        return;
252 252
      case '\b':
253 253
        os << "\\b";
254 254
        return;
255 255
      case '\f':
256 256
        os << "\\f";
257 257
        return;
258 258
      case '\r':
259 259
        os << "\\r";
260 260
        return;
261 261
      case '\n':
262 262
        os << "\\n";
263 263
        return;
264 264
      case '\t':
265 265
        os << "\\t";
266 266
        return;
267 267
      case '\v':
268 268
        os << "\\v";
269 269
        return;
270 270
      default:
271 271
        if (c < 0x20) {
272 272
          std::ios::fmtflags flags = os.flags();
273 273
          os << '\\' << std::oct << static_cast<int>(c);
274 274
          os.flags(flags);
275 275
        } else {
276 276
          os << c;
277 277
        }
278 278
        return;
279 279
      }
280 280
    }
281 281

	
282 282
    inline bool requireEscape(const std::string& str) {
283 283
      if (str.empty() || str[0] == '@') return true;
284 284
      std::istringstream is(str);
285 285
      char c;
286 286
      while (is.get(c)) {
287 287
        if (isWhiteSpace(c) || isEscaped(c)) {
288 288
          return true;
289 289
        }
290 290
      }
291 291
      return false;
292 292
    }
293 293

	
294 294
    inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
295 295

	
296 296
      if (requireEscape(str)) {
297 297
        os << '\"';
298 298
        for (std::string::const_iterator it = str.begin();
299 299
             it != str.end(); ++it) {
300 300
          writeEscape(os, *it);
301 301
        }
302 302
        os << '\"';
303 303
      } else {
304 304
        os << str;
305 305
      }
306 306
      return os;
307 307
    }
308 308

	
309 309
    class Section {
310 310
    public:
311 311
      virtual ~Section() {}
312 312
      virtual void process(std::ostream& os) = 0;
313 313
    };
314 314

	
315 315
    template <typename Functor>
316 316
    class LineSection : public Section {
317 317
    private:
318 318

	
319 319
      Functor _functor;
320 320

	
321 321
    public:
322 322

	
323 323
      LineSection(const Functor& functor) : _functor(functor) {}
324 324
      virtual ~LineSection() {}
325 325

	
326 326
      virtual void process(std::ostream& os) {
327 327
        std::string line;
328 328
        while (!(line = _functor()).empty()) os << line << std::endl;
329 329
      }
330 330
    };
331 331

	
332 332
    template <typename Functor>
333 333
    class StreamSection : public Section {
334 334
    private:
335 335

	
336 336
      Functor _functor;
337 337

	
338 338
    public:
339 339

	
340 340
      StreamSection(const Functor& functor) : _functor(functor) {}
341 341
      virtual ~StreamSection() {}
342 342

	
343 343
      virtual void process(std::ostream& os) {
344 344
        _functor(os);
345 345
      }
346 346
    };
347 347

	
348 348
  }
349 349

	
350 350
  template <typename Digraph>
351 351
  class DigraphWriter;
352 352

	
353 353
  template <typename Digraph>
354 354
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
355 355
                                       std::ostream& os = std::cout);
356 356
  template <typename Digraph>
357 357
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
358 358
                                       const std::string& fn);
359 359

	
360 360
  template <typename Digraph>
361 361
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
362 362
                                       const char* fn);
363 363

	
364 364

	
365 365
  /// \ingroup lemon_io
366 366
  ///
367 367
  /// \brief \ref lgf-format "LGF" writer for directed graphs
368 368
  ///
369 369
  /// This utility writes an \ref lgf-format "LGF" file.
370 370
  ///
371 371
  /// The writing method does a batch processing. The user creates a
372 372
  /// writer object, then various writing rules can be added to the
373 373
  /// writer, and eventually the writing is executed with the \c run()
374 374
  /// member function. A map writing rule can be added to the writer
375 375
  /// with the \c nodeMap() or \c arcMap() members. An optional
376 376
  /// converter parameter can also be added as a standard functor
377 377
  /// converting from the value type of the map to \c std::string. If it
378 378
  /// is set, it will determine how the value type of the map is written to
379 379
  /// the output stream. If the functor is not set, then a default
380 380
  /// conversion will be used. The \c attribute(), \c node() and \c
381 381
  /// arc() functions are used to add attribute writing rules.
382 382
  ///
383 383
  ///\code
384 384
  /// DigraphWriter<Digraph>(digraph, std::cout).
385 385
  ///   nodeMap("coordinates", coord_map).
386 386
  ///   nodeMap("size", size).
387 387
  ///   nodeMap("title", title).
388 388
  ///   arcMap("capacity", cap_map).
389 389
  ///   node("source", src).
390 390
  ///   node("target", trg).
391 391
  ///   attribute("caption", caption).
392 392
  ///   run();
393 393
  ///\endcode
394 394
  ///
395 395
  ///
396 396
  /// By default, the writer does not write additional captions to the
397 397
  /// sections, but they can be give as an optional parameter of
398 398
  /// the \c nodes(), \c arcs() or \c
399 399
  /// attributes() functions.
400 400
  ///
401 401
  /// The \c skipNodes() and \c skipArcs() functions forbid the
402 402
  /// writing of the sections. If two arc sections should be written
403 403
  /// to the output, it can be done in two passes, the first pass
404 404
  /// writes the node section and the first arc section, then the
405 405
  /// second pass skips the node section and writes just the arc
406 406
  /// section to the stream. The output stream can be retrieved with
407 407
  /// the \c ostream() function, hence the second pass can append its
408 408
  /// output to the output of the first pass.
409 409
  template <typename _Digraph>
410 410
  class DigraphWriter {
411 411
  public:
412 412

	
413 413
    typedef _Digraph Digraph;
414 414
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
415 415

	
416 416
  private:
417 417

	
418 418

	
419 419
    std::ostream* _os;
420 420
    bool local_os;
421 421

	
422 422
    const Digraph& _digraph;
423 423

	
424 424
    std::string _nodes_caption;
425 425
    std::string _arcs_caption;
426 426
    std::string _attributes_caption;
427 427

	
428 428
    typedef std::map<Node, std::string> NodeIndex;
429 429
    NodeIndex _node_index;
430 430
    typedef std::map<Arc, std::string> ArcIndex;
431 431
    ArcIndex _arc_index;
432 432

	
433 433
    typedef std::vector<std::pair<std::string,
434 434
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
435 435
    NodeMaps _node_maps;
436 436

	
437 437
    typedef std::vector<std::pair<std::string,
438 438
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
439 439
    ArcMaps _arc_maps;
440 440

	
441 441
    typedef std::vector<std::pair<std::string,
442 442
      _writer_bits::ValueStorageBase*> > Attributes;
443 443
    Attributes _attributes;
444 444

	
445 445
    bool _skip_nodes;
446 446
    bool _skip_arcs;
447 447

	
448 448
  public:
449 449

	
450 450
    /// \brief Constructor
451 451
    ///
452 452
    /// Construct a directed graph writer, which writes to the given
453 453
    /// output stream.
454 454
    DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
455 455
      : _os(&os), local_os(false), _digraph(digraph),
456 456
        _skip_nodes(false), _skip_arcs(false) {}
457 457

	
458 458
    /// \brief Constructor
459 459
    ///
460 460
    /// Construct a directed graph writer, which writes to the given
461 461
    /// output file.
462 462
    DigraphWriter(const Digraph& digraph, const std::string& fn)
463 463
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
464 464
        _skip_nodes(false), _skip_arcs(false) {
465 465
      if (!(*_os)) {
466 466
        delete _os;
467 467
        throw IoError("Cannot write file", fn);
468 468
      }
469 469
    }
470 470

	
471 471
    /// \brief Constructor
472 472
    ///
473 473
    /// Construct a directed graph writer, which writes to the given
474 474
    /// output file.
475 475
    DigraphWriter(const Digraph& digraph, const char* fn)
476 476
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
477 477
        _skip_nodes(false), _skip_arcs(false) {
478 478
      if (!(*_os)) {
479 479
        delete _os;
480 480
        throw IoError("Cannot write file", fn);
481 481
      }
482 482
    }
483 483

	
484 484
    /// \brief Destructor
485 485
    ~DigraphWriter() {
486 486
      for (typename NodeMaps::iterator it = _node_maps.begin();
487 487
           it != _node_maps.end(); ++it) {
488 488
        delete it->second;
489 489
      }
490 490

	
491 491
      for (typename ArcMaps::iterator it = _arc_maps.begin();
492 492
           it != _arc_maps.end(); ++it) {
493 493
        delete it->second;
494 494
      }
495 495

	
496 496
      for (typename Attributes::iterator it = _attributes.begin();
497 497
           it != _attributes.end(); ++it) {
498 498
        delete it->second;
499 499
      }
500 500

	
501 501
      if (local_os) {
502 502
        delete _os;
503 503
      }
504 504
    }
505 505

	
506 506
  private:
507 507

	
508 508
    template <typename DGR>
509
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
509
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
510 510
                                            std::ostream& os);
511 511
    template <typename DGR>
512 512
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
513 513
                                            const std::string& fn);
514 514
    template <typename DGR>
515 515
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
516 516
                                            const char *fn);
517 517

	
518 518
    DigraphWriter(DigraphWriter& other)
519 519
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
520 520
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
521 521

	
522 522
      other._os = 0;
523 523
      other.local_os = false;
524 524

	
525 525
      _node_index.swap(other._node_index);
526 526
      _arc_index.swap(other._arc_index);
527 527

	
528 528
      _node_maps.swap(other._node_maps);
529 529
      _arc_maps.swap(other._arc_maps);
530 530
      _attributes.swap(other._attributes);
531 531

	
532 532
      _nodes_caption = other._nodes_caption;
533 533
      _arcs_caption = other._arcs_caption;
534 534
      _attributes_caption = other._attributes_caption;
535 535
    }
536 536

	
537 537
    DigraphWriter& operator=(const DigraphWriter&);
538 538

	
539 539
  public:
540 540

	
541 541
    /// \name Writing rules
542 542
    /// @{
543 543

	
544 544
    /// \brief Node map writing rule
545 545
    ///
546 546
    /// Add a node map writing rule to the writer.
547 547
    template <typename Map>
548 548
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
549 549
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
550 550
      _writer_bits::MapStorageBase<Node>* storage =
551 551
        new _writer_bits::MapStorage<Node, Map>(map);
552 552
      _node_maps.push_back(std::make_pair(caption, storage));
553 553
      return *this;
554 554
    }
555 555

	
556 556
    /// \brief Node map writing rule
557 557
    ///
558 558
    /// Add a node map writing rule with specialized converter to the
559 559
    /// writer.
560 560
    template <typename Map, typename Converter>
561 561
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
562 562
                           const Converter& converter = Converter()) {
563 563
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
564 564
      _writer_bits::MapStorageBase<Node>* storage =
565 565
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
566 566
      _node_maps.push_back(std::make_pair(caption, storage));
567 567
      return *this;
568 568
    }
569 569

	
570 570
    /// \brief Arc map writing rule
571 571
    ///
572 572
    /// Add an arc map writing rule to the writer.
573 573
    template <typename Map>
574 574
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
575 575
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
576 576
      _writer_bits::MapStorageBase<Arc>* storage =
577 577
        new _writer_bits::MapStorage<Arc, Map>(map);
578 578
      _arc_maps.push_back(std::make_pair(caption, storage));
579 579
      return *this;
580 580
    }
581 581

	
582 582
    /// \brief Arc map writing rule
583 583
    ///
584 584
    /// Add an arc map writing rule with specialized converter to the
585 585
    /// writer.
586 586
    template <typename Map, typename Converter>
587 587
    DigraphWriter& arcMap(const std::string& caption, const Map& map,
588 588
                          const Converter& converter = Converter()) {
589 589
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
590 590
      _writer_bits::MapStorageBase<Arc>* storage =
591 591
        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
592 592
      _arc_maps.push_back(std::make_pair(caption, storage));
593 593
      return *this;
594 594
    }
595 595

	
596 596
    /// \brief Attribute writing rule
597 597
    ///
598 598
    /// Add an attribute writing rule to the writer.
599 599
    template <typename Value>
600 600
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
601 601
      _writer_bits::ValueStorageBase* storage =
602 602
        new _writer_bits::ValueStorage<Value>(value);
603 603
      _attributes.push_back(std::make_pair(caption, storage));
604 604
      return *this;
605 605
    }
606 606

	
607 607
    /// \brief Attribute writing rule
608 608
    ///
609 609
    /// Add an attribute writing rule with specialized converter to the
610 610
    /// writer.
611 611
    template <typename Value, typename Converter>
612 612
    DigraphWriter& attribute(const std::string& caption, const Value& value,
613 613
                             const Converter& converter = Converter()) {
614 614
      _writer_bits::ValueStorageBase* storage =
615 615
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
616 616
      _attributes.push_back(std::make_pair(caption, storage));
617 617
      return *this;
618 618
    }
619 619

	
620 620
    /// \brief Node writing rule
621 621
    ///
622 622
    /// Add a node writing rule to the writer.
623 623
    DigraphWriter& node(const std::string& caption, const Node& node) {
624 624
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
625 625
      Converter converter(_node_index);
626 626
      _writer_bits::ValueStorageBase* storage =
627 627
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
628 628
      _attributes.push_back(std::make_pair(caption, storage));
629 629
      return *this;
630 630
    }
631 631

	
632 632
    /// \brief Arc writing rule
633 633
    ///
634 634
    /// Add an arc writing rule to writer.
635 635
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
636 636
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
637 637
      Converter converter(_arc_index);
638 638
      _writer_bits::ValueStorageBase* storage =
639 639
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
640 640
      _attributes.push_back(std::make_pair(caption, storage));
641 641
      return *this;
642 642
    }
643 643

	
644 644
    /// \name Section captions
645 645
    /// @{
646 646

	
647 647
    /// \brief Add an additional caption to the \c \@nodes section
648 648
    ///
649 649
    /// Add an additional caption to the \c \@nodes section.
650 650
    DigraphWriter& nodes(const std::string& caption) {
651 651
      _nodes_caption = caption;
652 652
      return *this;
653 653
    }
654 654

	
655 655
    /// \brief Add an additional caption to the \c \@arcs section
656 656
    ///
657 657
    /// Add an additional caption to the \c \@arcs section.
658 658
    DigraphWriter& arcs(const std::string& caption) {
659 659
      _arcs_caption = caption;
660 660
      return *this;
661 661
    }
662 662

	
663 663
    /// \brief Add an additional caption to the \c \@attributes section
664 664
    ///
665 665
    /// Add an additional caption to the \c \@attributes section.
666 666
    DigraphWriter& attributes(const std::string& caption) {
667 667
      _attributes_caption = caption;
668 668
      return *this;
669 669
    }
670 670

	
671 671
    /// \name Skipping section
672 672
    /// @{
673 673

	
674 674
    /// \brief Skip writing the node set
675 675
    ///
676 676
    /// The \c \@nodes section will not be written to the stream.
677 677
    DigraphWriter& skipNodes() {
678 678
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
679 679
      _skip_nodes = true;
680 680
      return *this;
681 681
    }
682 682

	
683 683
    /// \brief Skip writing arc set
684 684
    ///
685 685
    /// The \c \@arcs section will not be written to the stream.
686 686
    DigraphWriter& skipArcs() {
687 687
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
688 688
      _skip_arcs = true;
689 689
      return *this;
690 690
    }
691 691

	
692 692
    /// @}
693 693

	
694 694
  private:
695 695

	
696 696
    void writeNodes() {
697 697
      _writer_bits::MapStorageBase<Node>* label = 0;
698 698
      for (typename NodeMaps::iterator it = _node_maps.begin();
699 699
           it != _node_maps.end(); ++it) {
700 700
        if (it->first == "label") {
701 701
          label = it->second;
702 702
          break;
703 703
        }
704 704
      }
705 705

	
706 706
      *_os << "@nodes";
707 707
      if (!_nodes_caption.empty()) {
708 708
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
709 709
      }
710 710
      *_os << std::endl;
711 711

	
712 712
      if (label == 0) {
713 713
        *_os << "label" << '\t';
714 714
      }
715 715
      for (typename NodeMaps::iterator it = _node_maps.begin();
716 716
           it != _node_maps.end(); ++it) {
717 717
        _writer_bits::writeToken(*_os, it->first) << '\t';
718 718
      }
719 719
      *_os << std::endl;
720 720

	
721 721
      std::vector<Node> nodes;
722 722
      for (NodeIt n(_digraph); n != INVALID; ++n) {
723 723
        nodes.push_back(n);
724 724
      }
725 725

	
726 726
      if (label == 0) {
727 727
        IdMap<Digraph, Node> id_map(_digraph);
728 728
        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
729 729
        std::sort(nodes.begin(), nodes.end(), id_less);
730 730
      } else {
731 731
        label->sort(nodes);
732 732
      }
733 733

	
734 734
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
735 735
        Node n = nodes[i];
736 736
        if (label == 0) {
737 737
          std::ostringstream os;
738 738
          os << _digraph.id(n);
739 739
          _writer_bits::writeToken(*_os, os.str());
740 740
          *_os << '\t';
741 741
          _node_index.insert(std::make_pair(n, os.str()));
742 742
        }
743 743
        for (typename NodeMaps::iterator it = _node_maps.begin();
744 744
             it != _node_maps.end(); ++it) {
745 745
          std::string value = it->second->get(n);
746 746
          _writer_bits::writeToken(*_os, value);
747 747
          if (it->first == "label") {
748 748
            _node_index.insert(std::make_pair(n, value));
749 749
          }
750 750
          *_os << '\t';
751 751
        }
752 752
        *_os << std::endl;
753 753
      }
754 754
    }
755 755

	
756 756
    void createNodeIndex() {
757 757
      _writer_bits::MapStorageBase<Node>* label = 0;
758 758
      for (typename NodeMaps::iterator it = _node_maps.begin();
759 759
           it != _node_maps.end(); ++it) {
760 760
        if (it->first == "label") {
761 761
          label = it->second;
762 762
          break;
763 763
        }
764 764
      }
765 765

	
766 766
      if (label == 0) {
767 767
        for (NodeIt n(_digraph); n != INVALID; ++n) {
768 768
          std::ostringstream os;
769 769
          os << _digraph.id(n);
770 770
          _node_index.insert(std::make_pair(n, os.str()));
771 771
        }
772 772
      } else {
773 773
        for (NodeIt n(_digraph); n != INVALID; ++n) {
774 774
          std::string value = label->get(n);
775 775
          _node_index.insert(std::make_pair(n, value));
776 776
        }
777 777
      }
778 778
    }
779 779

	
780 780
    void writeArcs() {
781 781
      _writer_bits::MapStorageBase<Arc>* label = 0;
782 782
      for (typename ArcMaps::iterator it = _arc_maps.begin();
783 783
           it != _arc_maps.end(); ++it) {
784 784
        if (it->first == "label") {
785 785
          label = it->second;
786 786
          break;
787 787
        }
788 788
      }
789 789

	
790 790
      *_os << "@arcs";
791 791
      if (!_arcs_caption.empty()) {
792 792
        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
793 793
      }
794 794
      *_os << std::endl;
795 795

	
796 796
      *_os << '\t' << '\t';
797 797
      if (label == 0) {
798 798
        *_os << "label" << '\t';
799 799
      }
800 800
      for (typename ArcMaps::iterator it = _arc_maps.begin();
801 801
           it != _arc_maps.end(); ++it) {
802 802
        _writer_bits::writeToken(*_os, it->first) << '\t';
803 803
      }
804 804
      *_os << std::endl;
805 805

	
806 806
      std::vector<Arc> arcs;
807 807
      for (ArcIt n(_digraph); n != INVALID; ++n) {
808 808
        arcs.push_back(n);
809 809
      }
810 810

	
811 811
      if (label == 0) {
812 812
        IdMap<Digraph, Arc> id_map(_digraph);
813 813
        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
814 814
        std::sort(arcs.begin(), arcs.end(), id_less);
815 815
      } else {
816 816
        label->sort(arcs);
817 817
      }
818 818

	
819 819
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
820 820
        Arc a = arcs[i];
821 821
        _writer_bits::writeToken(*_os, _node_index.
822 822
                                 find(_digraph.source(a))->second);
823 823
        *_os << '\t';
824 824
        _writer_bits::writeToken(*_os, _node_index.
825 825
                                 find(_digraph.target(a))->second);
826 826
        *_os << '\t';
827 827
        if (label == 0) {
828 828
          std::ostringstream os;
829 829
          os << _digraph.id(a);
830 830
          _writer_bits::writeToken(*_os, os.str());
831 831
          *_os << '\t';
832 832
          _arc_index.insert(std::make_pair(a, os.str()));
833 833
        }
834 834
        for (typename ArcMaps::iterator it = _arc_maps.begin();
835 835
             it != _arc_maps.end(); ++it) {
836 836
          std::string value = it->second->get(a);
837 837
          _writer_bits::writeToken(*_os, value);
838 838
          if (it->first == "label") {
839 839
            _arc_index.insert(std::make_pair(a, value));
840 840
          }
841 841
          *_os << '\t';
842 842
        }
843 843
        *_os << std::endl;
844 844
      }
845 845
    }
846 846

	
847 847
    void createArcIndex() {
848 848
      _writer_bits::MapStorageBase<Arc>* label = 0;
849 849
      for (typename ArcMaps::iterator it = _arc_maps.begin();
850 850
           it != _arc_maps.end(); ++it) {
851 851
        if (it->first == "label") {
852 852
          label = it->second;
853 853
          break;
854 854
        }
855 855
      }
856 856

	
857 857
      if (label == 0) {
858 858
        for (ArcIt a(_digraph); a != INVALID; ++a) {
859 859
          std::ostringstream os;
860 860
          os << _digraph.id(a);
861 861
          _arc_index.insert(std::make_pair(a, os.str()));
862 862
        }
863 863
      } else {
864 864
        for (ArcIt a(_digraph); a != INVALID; ++a) {
865 865
          std::string value = label->get(a);
866 866
          _arc_index.insert(std::make_pair(a, value));
867 867
        }
868 868
      }
869 869
    }
870 870

	
871 871
    void writeAttributes() {
872 872
      if (_attributes.empty()) return;
873 873
      *_os << "@attributes";
874 874
      if (!_attributes_caption.empty()) {
875 875
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
876 876
      }
877 877
      *_os << std::endl;
878 878
      for (typename Attributes::iterator it = _attributes.begin();
879 879
           it != _attributes.end(); ++it) {
880 880
        _writer_bits::writeToken(*_os, it->first) << ' ';
881 881
        _writer_bits::writeToken(*_os, it->second->get());
882 882
        *_os << std::endl;
883 883
      }
884 884
    }
885 885

	
886 886
  public:
887 887

	
888 888
    /// \name Execution of the writer
889 889
    /// @{
890 890

	
891 891
    /// \brief Start the batch processing
892 892
    ///
893 893
    /// This function starts the batch processing.
894 894
    void run() {
895 895
      if (!_skip_nodes) {
896 896
        writeNodes();
897 897
      } else {
898 898
        createNodeIndex();
899 899
      }
900 900
      if (!_skip_arcs) {
901 901
        writeArcs();
902 902
      } else {
903 903
        createArcIndex();
904 904
      }
905 905
      writeAttributes();
906 906
    }
907 907

	
908 908
    /// \brief Give back the stream of the writer
909 909
    ///
910 910
    /// Give back the stream of the writer.
911 911
    std::ostream& ostream() {
912 912
      return *_os;
913 913
    }
914 914

	
915 915
    /// @}
916 916
  };
917 917

	
918 918
  /// \brief Return a \ref DigraphWriter class
919 919
  ///
920 920
  /// This function just returns a \ref DigraphWriter class.
921 921
  /// \relates DigraphWriter
922 922
  template <typename Digraph>
923 923
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
924 924
                                       std::ostream& os) {
925 925
    DigraphWriter<Digraph> tmp(digraph, os);
926 926
    return tmp;
927 927
  }
928 928

	
929 929
  /// \brief Return a \ref DigraphWriter class
930 930
  ///
931 931
  /// This function just returns a \ref DigraphWriter class.
932 932
  /// \relates DigraphWriter
933 933
  template <typename Digraph>
934 934
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
935 935
                                       const std::string& fn) {
936 936
    DigraphWriter<Digraph> tmp(digraph, fn);
937 937
    return tmp;
938 938
  }
939 939

	
940 940
  /// \brief Return a \ref DigraphWriter class
941 941
  ///
942 942
  /// This function just returns a \ref DigraphWriter class.
943 943
  /// \relates DigraphWriter
944 944
  template <typename Digraph>
945 945
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
946 946
                                       const char* fn) {
947 947
    DigraphWriter<Digraph> tmp(digraph, fn);
948 948
    return tmp;
949 949
  }
950 950

	
951 951
  template <typename Graph>
952 952
  class GraphWriter;
953 953

	
954 954
  template <typename Graph>
955 955
  GraphWriter<Graph> graphWriter(const Graph& graph,
956 956
                                 std::ostream& os = std::cout);
957 957
  template <typename Graph>
958 958
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
959 959
  template <typename Graph>
960 960
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
961 961

	
962 962
  /// \ingroup lemon_io
963 963
  ///
964 964
  /// \brief \ref lgf-format "LGF" writer for directed graphs
965 965
  ///
966 966
  /// This utility writes an \ref lgf-format "LGF" file.
967 967
  ///
968 968
  /// It can be used almost the same way as \c DigraphWriter.
969 969
  /// The only difference is that this class can handle edges and
970 970
  /// edge maps as well as arcs and arc maps.
971 971
  ///
972 972
  /// The arc maps are written into the file as two columns, the
973 973
  /// caption of the columns are the name of the map prefixed with \c
974 974
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
975 975
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
976 976
  /// of the arc) and the label of corresponding edge.
977 977
  template <typename _Graph>
978 978
  class GraphWriter {
979 979
  public:
980 980

	
981 981
    typedef _Graph Graph;
982 982
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
983 983

	
984 984
  private:
985 985

	
986 986

	
987 987
    std::ostream* _os;
988 988
    bool local_os;
989 989

	
990 990
    const Graph& _graph;
991 991

	
992 992
    std::string _nodes_caption;
993 993
    std::string _edges_caption;
994 994
    std::string _attributes_caption;
995 995

	
996 996
    typedef std::map<Node, std::string> NodeIndex;
997 997
    NodeIndex _node_index;
998 998
    typedef std::map<Edge, std::string> EdgeIndex;
999 999
    EdgeIndex _edge_index;
1000 1000

	
1001 1001
    typedef std::vector<std::pair<std::string,
1002 1002
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
1003 1003
    NodeMaps _node_maps;
1004 1004

	
1005 1005
    typedef std::vector<std::pair<std::string,
1006 1006
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
1007 1007
    EdgeMaps _edge_maps;
1008 1008

	
1009 1009
    typedef std::vector<std::pair<std::string,
1010 1010
      _writer_bits::ValueStorageBase*> > Attributes;
1011 1011
    Attributes _attributes;
1012 1012

	
1013 1013
    bool _skip_nodes;
1014 1014
    bool _skip_edges;
1015 1015

	
1016 1016
  public:
1017 1017

	
1018 1018
    /// \brief Constructor
1019 1019
    ///
1020 1020
    /// Construct a directed graph writer, which writes to the given
1021 1021
    /// output stream.
1022 1022
    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
1023 1023
      : _os(&os), local_os(false), _graph(graph),
1024 1024
        _skip_nodes(false), _skip_edges(false) {}
1025 1025

	
1026 1026
    /// \brief Constructor
1027 1027
    ///
1028 1028
    /// Construct a directed graph writer, which writes to the given
1029 1029
    /// output file.
1030 1030
    GraphWriter(const Graph& graph, const std::string& fn)
1031 1031
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1032 1032
        _skip_nodes(false), _skip_edges(false) {
1033 1033
      if (!(*_os)) {
1034 1034
        delete _os;
1035 1035
        throw IoError("Cannot write file", fn);
1036 1036
      }
1037 1037
    }
1038 1038

	
1039 1039
    /// \brief Constructor
1040 1040
    ///
1041 1041
    /// Construct a directed graph writer, which writes to the given
1042 1042
    /// output file.
1043 1043
    GraphWriter(const Graph& graph, const char* fn)
1044 1044
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
1045 1045
        _skip_nodes(false), _skip_edges(false) {
1046 1046
      if (!(*_os)) {
1047 1047
        delete _os;
1048 1048
        throw IoError("Cannot write file", fn);
1049 1049
      }
1050 1050
    }
1051 1051

	
1052 1052
    /// \brief Destructor
1053 1053
    ~GraphWriter() {
1054 1054
      for (typename NodeMaps::iterator it = _node_maps.begin();
1055 1055
           it != _node_maps.end(); ++it) {
1056 1056
        delete it->second;
1057 1057
      }
1058 1058

	
1059 1059
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1060 1060
           it != _edge_maps.end(); ++it) {
1061 1061
        delete it->second;
1062 1062
      }
1063 1063

	
1064 1064
      for (typename Attributes::iterator it = _attributes.begin();
1065 1065
           it != _attributes.end(); ++it) {
1066 1066
        delete it->second;
1067 1067
      }
1068 1068

	
1069 1069
      if (local_os) {
1070 1070
        delete _os;
1071 1071
      }
1072 1072
    }
1073 1073

	
1074 1074
  private:
1075 1075

	
1076 1076
    template <typename GR>
1077 1077
    friend GraphWriter<GR> graphWriter(const GR& graph,
1078 1078
                                       std::ostream& os);
1079 1079
    template <typename GR>
1080 1080
    friend GraphWriter<GR> graphWriter(const GR& graph,
1081 1081
                                       const std::string& fn);
1082 1082
    template <typename GR>
1083 1083
    friend GraphWriter<GR> graphWriter(const GR& graph,
1084 1084
                                       const char *fn);
1085
    
1085

	
1086 1086
    GraphWriter(GraphWriter& other)
1087 1087
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1088 1088
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1089 1089

	
1090 1090
      other._os = 0;
1091 1091
      other.local_os = false;
1092 1092

	
1093 1093
      _node_index.swap(other._node_index);
1094 1094
      _edge_index.swap(other._edge_index);
1095 1095

	
1096 1096
      _node_maps.swap(other._node_maps);
1097 1097
      _edge_maps.swap(other._edge_maps);
1098 1098
      _attributes.swap(other._attributes);
1099 1099

	
1100 1100
      _nodes_caption = other._nodes_caption;
1101 1101
      _edges_caption = other._edges_caption;
1102 1102
      _attributes_caption = other._attributes_caption;
1103 1103
    }
1104 1104

	
1105 1105
    GraphWriter& operator=(const GraphWriter&);
1106 1106

	
1107 1107
  public:
1108 1108

	
1109 1109
    /// \name Writing rules
1110 1110
    /// @{
1111 1111

	
1112 1112
    /// \brief Node map writing rule
1113 1113
    ///
1114 1114
    /// Add a node map writing rule to the writer.
1115 1115
    template <typename Map>
1116 1116
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1117 1117
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1118 1118
      _writer_bits::MapStorageBase<Node>* storage =
1119 1119
        new _writer_bits::MapStorage<Node, Map>(map);
1120 1120
      _node_maps.push_back(std::make_pair(caption, storage));
1121 1121
      return *this;
1122 1122
    }
1123 1123

	
1124 1124
    /// \brief Node map writing rule
1125 1125
    ///
1126 1126
    /// Add a node map writing rule with specialized converter to the
1127 1127
    /// writer.
1128 1128
    template <typename Map, typename Converter>
1129 1129
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1130 1130
                           const Converter& converter = Converter()) {
1131 1131
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1132 1132
      _writer_bits::MapStorageBase<Node>* storage =
1133 1133
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1134 1134
      _node_maps.push_back(std::make_pair(caption, storage));
1135 1135
      return *this;
1136 1136
    }
1137 1137

	
1138 1138
    /// \brief Edge map writing rule
1139 1139
    ///
1140 1140
    /// Add an edge map writing rule to the writer.
1141 1141
    template <typename Map>
1142 1142
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1143 1143
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1144 1144
      _writer_bits::MapStorageBase<Edge>* storage =
1145 1145
        new _writer_bits::MapStorage<Edge, Map>(map);
1146 1146
      _edge_maps.push_back(std::make_pair(caption, storage));
1147 1147
      return *this;
1148 1148
    }
1149 1149

	
1150 1150
    /// \brief Edge map writing rule
1151 1151
    ///
1152 1152
    /// Add an edge map writing rule with specialized converter to the
1153 1153
    /// writer.
1154 1154
    template <typename Map, typename Converter>
1155 1155
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1156 1156
                          const Converter& converter = Converter()) {
1157 1157
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1158 1158
      _writer_bits::MapStorageBase<Edge>* storage =
1159 1159
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1160 1160
      _edge_maps.push_back(std::make_pair(caption, storage));
1161 1161
      return *this;
1162 1162
    }
1163 1163

	
1164 1164
    /// \brief Arc map writing rule
1165 1165
    ///
1166 1166
    /// Add an arc map writing rule to the writer.
1167 1167
    template <typename Map>
1168 1168
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1169 1169
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1170 1170
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1171 1171
        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1172 1172
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1173 1173
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1174 1174
        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1175 1175
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1176 1176
      return *this;
1177 1177
    }
1178 1178

	
1179 1179
    /// \brief Arc map writing rule
1180 1180
    ///
1181 1181
    /// Add an arc map writing rule with specialized converter to the
1182 1182
    /// writer.
1183 1183
    template <typename Map, typename Converter>
1184 1184
    GraphWriter& arcMap(const std::string& caption, const Map& map,
1185 1185
                          const Converter& converter = Converter()) {
1186 1186
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1187 1187
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1188 1188
        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1189 1189
        (_graph, map, converter);
1190 1190
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1191 1191
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1192 1192
        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1193 1193
        (_graph, map, converter);
1194 1194
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1195 1195
      return *this;
1196 1196
    }
1197 1197

	
1198 1198
    /// \brief Attribute writing rule
1199 1199
    ///
1200 1200
    /// Add an attribute writing rule to the writer.
1201 1201
    template <typename Value>
1202 1202
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1203 1203
      _writer_bits::ValueStorageBase* storage =
1204 1204
        new _writer_bits::ValueStorage<Value>(value);
1205 1205
      _attributes.push_back(std::make_pair(caption, storage));
1206 1206
      return *this;
1207 1207
    }
1208 1208

	
1209 1209
    /// \brief Attribute writing rule
1210 1210
    ///
1211 1211
    /// Add an attribute writing rule with specialized converter to the
1212 1212
    /// writer.
1213 1213
    template <typename Value, typename Converter>
1214 1214
    GraphWriter& attribute(const std::string& caption, const Value& value,
1215 1215
                             const Converter& converter = Converter()) {
1216 1216
      _writer_bits::ValueStorageBase* storage =
1217 1217
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1218 1218
      _attributes.push_back(std::make_pair(caption, storage));
1219 1219
      return *this;
1220 1220
    }
1221 1221

	
1222 1222
    /// \brief Node writing rule
1223 1223
    ///
1224 1224
    /// Add a node writing rule to the writer.
1225 1225
    GraphWriter& node(const std::string& caption, const Node& node) {
1226 1226
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1227 1227
      Converter converter(_node_index);
1228 1228
      _writer_bits::ValueStorageBase* storage =
1229 1229
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1230 1230
      _attributes.push_back(std::make_pair(caption, storage));
1231 1231
      return *this;
1232 1232
    }
1233 1233

	
1234 1234
    /// \brief Edge writing rule
1235 1235
    ///
1236 1236
    /// Add an edge writing rule to writer.
1237 1237
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1238 1238
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1239 1239
      Converter converter(_edge_index);
1240 1240
      _writer_bits::ValueStorageBase* storage =
1241 1241
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1242 1242
      _attributes.push_back(std::make_pair(caption, storage));
1243 1243
      return *this;
1244 1244
    }
1245 1245

	
1246 1246
    /// \brief Arc writing rule
1247 1247
    ///
1248 1248
    /// Add an arc writing rule to writer.
1249 1249
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1250 1250
      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1251 1251
      Converter converter(_graph, _edge_index);
1252 1252
      _writer_bits::ValueStorageBase* storage =
1253 1253
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1254 1254
      _attributes.push_back(std::make_pair(caption, storage));
1255 1255
      return *this;
1256 1256
    }
1257 1257

	
1258 1258
    /// \name Section captions
1259 1259
    /// @{
1260 1260

	
1261 1261
    /// \brief Add an additional caption to the \c \@nodes section
1262 1262
    ///
1263 1263
    /// Add an additional caption to the \c \@nodes section.
1264 1264
    GraphWriter& nodes(const std::string& caption) {
1265 1265
      _nodes_caption = caption;
1266 1266
      return *this;
1267 1267
    }
1268 1268

	
1269 1269
    /// \brief Add an additional caption to the \c \@arcs section
1270 1270
    ///
1271 1271
    /// Add an additional caption to the \c \@arcs section.
1272 1272
    GraphWriter& edges(const std::string& caption) {
1273 1273
      _edges_caption = caption;
1274 1274
      return *this;
1275 1275
    }
1276 1276

	
1277 1277
    /// \brief Add an additional caption to the \c \@attributes section
1278 1278
    ///
1279 1279
    /// Add an additional caption to the \c \@attributes section.
1280 1280
    GraphWriter& attributes(const std::string& caption) {
1281 1281
      _attributes_caption = caption;
1282 1282
      return *this;
1283 1283
    }
1284 1284

	
1285 1285
    /// \name Skipping section
1286 1286
    /// @{
1287 1287

	
1288 1288
    /// \brief Skip writing the node set
1289 1289
    ///
1290 1290
    /// The \c \@nodes section will not be written to the stream.
1291 1291
    GraphWriter& skipNodes() {
1292 1292
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1293 1293
      _skip_nodes = true;
1294 1294
      return *this;
1295 1295
    }
1296 1296

	
1297 1297
    /// \brief Skip writing edge set
1298 1298
    ///
1299 1299
    /// The \c \@edges section will not be written to the stream.
1300 1300
    GraphWriter& skipEdges() {
1301 1301
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1302 1302
      _skip_edges = true;
1303 1303
      return *this;
1304 1304
    }
1305 1305

	
1306 1306
    /// @}
1307 1307

	
1308 1308
  private:
1309 1309

	
1310 1310
    void writeNodes() {
1311 1311
      _writer_bits::MapStorageBase<Node>* label = 0;
1312 1312
      for (typename NodeMaps::iterator it = _node_maps.begin();
1313 1313
           it != _node_maps.end(); ++it) {
1314 1314
        if (it->first == "label") {
1315 1315
          label = it->second;
1316 1316
          break;
1317 1317
        }
1318 1318
      }
1319 1319

	
1320 1320
      *_os << "@nodes";
1321 1321
      if (!_nodes_caption.empty()) {
1322 1322
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1323 1323
      }
1324 1324
      *_os << std::endl;
1325 1325

	
1326 1326
      if (label == 0) {
1327 1327
        *_os << "label" << '\t';
1328 1328
      }
1329 1329
      for (typename NodeMaps::iterator it = _node_maps.begin();
1330 1330
           it != _node_maps.end(); ++it) {
1331 1331
        _writer_bits::writeToken(*_os, it->first) << '\t';
1332 1332
      }
1333 1333
      *_os << std::endl;
1334 1334

	
1335 1335
      std::vector<Node> nodes;
1336 1336
      for (NodeIt n(_graph); n != INVALID; ++n) {
1337 1337
        nodes.push_back(n);
1338 1338
      }
1339 1339

	
1340 1340
      if (label == 0) {
1341 1341
        IdMap<Graph, Node> id_map(_graph);
1342 1342
        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1343 1343
        std::sort(nodes.begin(), nodes.end(), id_less);
1344 1344
      } else {
1345 1345
        label->sort(nodes);
1346 1346
      }
1347 1347

	
1348 1348
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1349 1349
        Node n = nodes[i];
1350 1350
        if (label == 0) {
1351 1351
          std::ostringstream os;
1352 1352
          os << _graph.id(n);
1353 1353
          _writer_bits::writeToken(*_os, os.str());
1354 1354
          *_os << '\t';
1355 1355
          _node_index.insert(std::make_pair(n, os.str()));
1356 1356
        }
1357 1357
        for (typename NodeMaps::iterator it = _node_maps.begin();
1358 1358
             it != _node_maps.end(); ++it) {
1359 1359
          std::string value = it->second->get(n);
1360 1360
          _writer_bits::writeToken(*_os, value);
1361 1361
          if (it->first == "label") {
1362 1362
            _node_index.insert(std::make_pair(n, value));
1363 1363
          }
1364 1364
          *_os << '\t';
1365 1365
        }
1366 1366
        *_os << std::endl;
1367 1367
      }
1368 1368
    }
1369 1369

	
1370 1370
    void createNodeIndex() {
1371 1371
      _writer_bits::MapStorageBase<Node>* label = 0;
1372 1372
      for (typename NodeMaps::iterator it = _node_maps.begin();
1373 1373
           it != _node_maps.end(); ++it) {
1374 1374
        if (it->first == "label") {
1375 1375
          label = it->second;
1376 1376
          break;
1377 1377
        }
1378 1378
      }
1379 1379

	
1380 1380
      if (label == 0) {
1381 1381
        for (NodeIt n(_graph); n != INVALID; ++n) {
1382 1382
          std::ostringstream os;
1383 1383
          os << _graph.id(n);
1384 1384
          _node_index.insert(std::make_pair(n, os.str()));
1385 1385
        }
1386 1386
      } else {
1387 1387
        for (NodeIt n(_graph); n != INVALID; ++n) {
1388 1388
          std::string value = label->get(n);
1389 1389
          _node_index.insert(std::make_pair(n, value));
1390 1390
        }
1391 1391
      }
1392 1392
    }
1393 1393

	
1394 1394
    void writeEdges() {
1395 1395
      _writer_bits::MapStorageBase<Edge>* label = 0;
1396 1396
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1397 1397
           it != _edge_maps.end(); ++it) {
1398 1398
        if (it->first == "label") {
1399 1399
          label = it->second;
1400 1400
          break;
1401 1401
        }
1402 1402
      }
1403 1403

	
1404 1404
      *_os << "@edges";
1405 1405
      if (!_edges_caption.empty()) {
1406 1406
        _writer_bits::writeToken(*_os << ' ', _edges_caption);
1407 1407
      }
1408 1408
      *_os << std::endl;
1409 1409

	
1410 1410
      *_os << '\t' << '\t';
1411 1411
      if (label == 0) {
1412 1412
        *_os << "label" << '\t';
1413 1413
      }
1414 1414
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1415 1415
           it != _edge_maps.end(); ++it) {
1416 1416
        _writer_bits::writeToken(*_os, it->first) << '\t';
1417 1417
      }
1418 1418
      *_os << std::endl;
1419 1419

	
1420 1420
      std::vector<Edge> edges;
1421 1421
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1422 1422
        edges.push_back(n);
1423 1423
      }
1424 1424

	
1425 1425
      if (label == 0) {
1426 1426
        IdMap<Graph, Edge> id_map(_graph);
1427 1427
        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1428 1428
        std::sort(edges.begin(), edges.end(), id_less);
1429 1429
      } else {
1430 1430
        label->sort(edges);
1431 1431
      }
1432 1432

	
1433 1433
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1434 1434
        Edge e = edges[i];
1435 1435
        _writer_bits::writeToken(*_os, _node_index.
1436 1436
                                 find(_graph.u(e))->second);
1437 1437
        *_os << '\t';
1438 1438
        _writer_bits::writeToken(*_os, _node_index.
1439 1439
                                 find(_graph.v(e))->second);
1440 1440
        *_os << '\t';
1441 1441
        if (label == 0) {
1442 1442
          std::ostringstream os;
1443 1443
          os << _graph.id(e);
1444 1444
          _writer_bits::writeToken(*_os, os.str());
1445 1445
          *_os << '\t';
1446 1446
          _edge_index.insert(std::make_pair(e, os.str()));
1447 1447
        }
1448 1448
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1449 1449
             it != _edge_maps.end(); ++it) {
1450 1450
          std::string value = it->second->get(e);
1451 1451
          _writer_bits::writeToken(*_os, value);
1452 1452
          if (it->first == "label") {
1453 1453
            _edge_index.insert(std::make_pair(e, value));
1454 1454
          }
1455 1455
          *_os << '\t';
1456 1456
        }
1457 1457
        *_os << std::endl;
1458 1458
      }
1459 1459
    }
1460 1460

	
1461 1461
    void createEdgeIndex() {
1462 1462
      _writer_bits::MapStorageBase<Edge>* label = 0;
1463 1463
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1464 1464
           it != _edge_maps.end(); ++it) {
1465 1465
        if (it->first == "label") {
1466 1466
          label = it->second;
1467 1467
          break;
1468 1468
        }
1469 1469
      }
1470 1470

	
1471 1471
      if (label == 0) {
1472 1472
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1473 1473
          std::ostringstream os;
1474 1474
          os << _graph.id(e);
1475 1475
          _edge_index.insert(std::make_pair(e, os.str()));
1476 1476
        }
1477 1477
      } else {
1478 1478
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1479 1479
          std::string value = label->get(e);
1480 1480
          _edge_index.insert(std::make_pair(e, value));
1481 1481
        }
1482 1482
      }
1483 1483
    }
1484 1484

	
1485 1485
    void writeAttributes() {
1486 1486
      if (_attributes.empty()) return;
1487 1487
      *_os << "@attributes";
1488 1488
      if (!_attributes_caption.empty()) {
1489 1489
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1490 1490
      }
1491 1491
      *_os << std::endl;
1492 1492
      for (typename Attributes::iterator it = _attributes.begin();
1493 1493
           it != _attributes.end(); ++it) {
1494 1494
        _writer_bits::writeToken(*_os, it->first) << ' ';
1495 1495
        _writer_bits::writeToken(*_os, it->second->get());
1496 1496
        *_os << std::endl;
1497 1497
      }
1498 1498
    }
1499 1499

	
1500 1500
  public:
1501 1501

	
1502 1502
    /// \name Execution of the writer
1503 1503
    /// @{
1504 1504

	
1505 1505
    /// \brief Start the batch processing
1506 1506
    ///
1507 1507
    /// This function starts the batch processing.
1508 1508
    void run() {
1509 1509
      if (!_skip_nodes) {
1510 1510
        writeNodes();
1511 1511
      } else {
1512 1512
        createNodeIndex();
1513 1513
      }
1514 1514
      if (!_skip_edges) {
1515 1515
        writeEdges();
1516 1516
      } else {
1517 1517
        createEdgeIndex();
1518 1518
      }
1519 1519
      writeAttributes();
1520 1520
    }
1521 1521

	
1522 1522
    /// \brief Give back the stream of the writer
1523 1523
    ///
1524 1524
    /// Give back the stream of the writer
1525 1525
    std::ostream& ostream() {
1526 1526
      return *_os;
1527 1527
    }
1528 1528

	
1529 1529
    /// @}
1530 1530
  };
1531 1531

	
1532 1532
  /// \brief Return a \ref GraphWriter class
1533 1533
  ///
1534 1534
  /// This function just returns a \ref GraphWriter class.
1535 1535
  /// \relates GraphWriter
1536 1536
  template <typename Graph>
1537 1537
  GraphWriter<Graph> graphWriter(const Graph& graph,
1538 1538
                                 std::ostream& os) {
1539 1539
    GraphWriter<Graph> tmp(graph, os);
1540 1540
    return tmp;
1541 1541
  }
1542 1542

	
1543 1543
  /// \brief Return a \ref GraphWriter class
1544 1544
  ///
1545 1545
  /// This function just returns a \ref GraphWriter class.
1546 1546
  /// \relates GraphWriter
1547 1547
  template <typename Graph>
1548 1548
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
1549 1549
    GraphWriter<Graph> tmp(graph, fn);
1550 1550
    return tmp;
1551 1551
  }
1552 1552

	
1553 1553
  /// \brief Return a \ref GraphWriter class
1554 1554
  ///
1555 1555
  /// This function just returns a \ref GraphWriter class.
1556 1556
  /// \relates GraphWriter
1557 1557
  template <typename Graph>
1558 1558
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
1559 1559
    GraphWriter<Graph> tmp(graph, fn);
1560 1560
    return tmp;
1561 1561
  }
1562 1562

	
1563 1563
  class SectionWriter;
1564 1564

	
1565 1565
  SectionWriter sectionWriter(std::istream& is);
1566 1566
  SectionWriter sectionWriter(const std::string& fn);
1567 1567
  SectionWriter sectionWriter(const char* fn);
1568 1568

	
1569 1569
  /// \ingroup lemon_io
1570 1570
  ///
1571 1571
  /// \brief Section writer class
1572 1572
  ///
1573 1573
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1574 1574
  /// which contain any data in arbitrary format. Such sections can be
1575 1575
  /// written with this class. A writing rule can be added to the
1576 1576
  /// class with two different functions. With the \c sectionLines()
1577 1577
  /// function a generator can write the section line-by-line, while
1578 1578
  /// with the \c sectionStream() member the section can be written to
1579 1579
  /// an output stream.
1580 1580
  class SectionWriter {
1581 1581
  private:
1582 1582

	
1583 1583
    std::ostream* _os;
1584 1584
    bool local_os;
1585 1585

	
1586 1586
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1587 1587
    Sections;
1588 1588

	
1589 1589
    Sections _sections;
1590 1590

	
1591 1591
  public:
1592 1592

	
1593 1593
    /// \brief Constructor
1594 1594
    ///
1595 1595
    /// Construct a section writer, which writes to the given output
1596 1596
    /// stream.
1597 1597
    SectionWriter(std::ostream& os)
1598 1598
      : _os(&os), local_os(false) {}
1599 1599

	
1600 1600
    /// \brief Constructor
1601 1601
    ///
1602 1602
    /// Construct a section writer, which writes into the given file.
1603 1603
    SectionWriter(const std::string& fn)
1604 1604
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1605 1605
      if (!(*_os)) {
1606 1606
        delete _os;
1607 1607
        throw IoError("Cannot write file", fn);
1608 1608
      }
1609 1609
    }
1610 1610

	
1611 1611
    /// \brief Constructor
1612 1612
    ///
1613 1613
    /// Construct a section writer, which writes into the given file.
1614 1614
    SectionWriter(const char* fn)
1615 1615
      : _os(new std::ofstream(fn)), local_os(true) {
1616 1616
      if (!(*_os)) {
1617 1617
        delete _os;
1618 1618
        throw IoError("Cannot write file", fn);
1619 1619
      }
1620 1620
    }
1621 1621

	
1622 1622
    /// \brief Destructor
1623 1623
    ~SectionWriter() {
1624 1624
      for (Sections::iterator it = _sections.begin();
1625 1625
           it != _sections.end(); ++it) {
1626 1626
        delete it->second;
1627 1627
      }
1628 1628

	
1629 1629
      if (local_os) {
1630 1630
        delete _os;
1631 1631
      }
1632 1632

	
1633 1633
    }
1634 1634

	
1635 1635
  private:
1636 1636

	
1637 1637
    friend SectionWriter sectionWriter(std::ostream& os);
1638 1638
    friend SectionWriter sectionWriter(const std::string& fn);
1639 1639
    friend SectionWriter sectionWriter(const char* fn);
1640 1640

	
1641 1641
    SectionWriter(SectionWriter& other)
1642 1642
      : _os(other._os), local_os(other.local_os) {
1643 1643

	
1644 1644
      other._os = 0;
1645 1645
      other.local_os = false;
1646 1646

	
1647 1647
      _sections.swap(other._sections);
1648 1648
    }
1649 1649

	
1650 1650
    SectionWriter& operator=(const SectionWriter&);
1651 1651

	
1652 1652
  public:
1653 1653

	
1654 1654
    /// \name Section writers
1655 1655
    /// @{
1656 1656

	
1657 1657
    /// \brief Add a section writer with line oriented writing
1658 1658
    ///
1659 1659
    /// The first parameter is the type descriptor of the section, the
1660 1660
    /// second is a generator with std::string values. At the writing
1661 1661
    /// process, the returned \c std::string will be written into the
1662 1662
    /// output file until it is an empty string.
1663 1663
    ///
1664 1664
    /// For example, an integer vector is written into a section.
1665 1665
    ///\code
1666 1666
    ///  @numbers
1667 1667
    ///  12 45 23 78
1668 1668
    ///  4 28 38 28
1669 1669
    ///  23 6 16
1670 1670
    ///\endcode
1671 1671
    ///
1672 1672
    /// The generator is implemented as a struct.
1673 1673
    ///\code
1674 1674
    ///  struct NumberSection {
1675 1675
    ///    std::vector<int>::const_iterator _it, _end;
1676 1676
    ///    NumberSection(const std::vector<int>& data)
1677 1677
    ///      : _it(data.begin()), _end(data.end()) {}
1678 1678
    ///    std::string operator()() {
1679 1679
    ///      int rem_in_line = 4;
1680 1680
    ///      std::ostringstream ls;
1681 1681
    ///      while (rem_in_line > 0 && _it != _end) {
1682 1682
    ///        ls << *(_it++) << ' ';
1683 1683
    ///        --rem_in_line;
1684 1684
    ///      }
1685 1685
    ///      return ls.str();
1686 1686
    ///    }
1687 1687
    ///  };
1688 1688
    ///
1689 1689
    ///  // ...
1690 1690
    ///
1691 1691
    ///  writer.sectionLines("numbers", NumberSection(vec));
1692 1692
    ///\endcode
1693 1693
    template <typename Functor>
1694 1694
    SectionWriter& sectionLines(const std::string& type, Functor functor) {
1695 1695
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1696 1696
      _sections.push_back(std::make_pair(type,
1697 1697
        new _writer_bits::LineSection<Functor>(functor)));
1698 1698
      return *this;
1699 1699
    }
1700 1700

	
1701 1701

	
1702 1702
    /// \brief Add a section writer with stream oriented writing
1703 1703
    ///
1704 1704
    /// The first parameter is the type of the section, the second is
1705 1705
    /// a functor, which takes a \c std::ostream& parameter. The
1706 1706
    /// functor writes the section to the output stream.
1707 1707
    /// \warning The last line must be closed with end-line character.
1708 1708
    template <typename Functor>
1709 1709
    SectionWriter& sectionStream(const std::string& type, Functor functor) {
1710 1710
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1711 1711
      _sections.push_back(std::make_pair(type,
1712 1712
         new _writer_bits::StreamSection<Functor>(functor)));
1713 1713
      return *this;
1714 1714
    }
1715 1715

	
1716 1716
    /// @}
1717 1717

	
1718 1718
  public:
1719 1719

	
1720 1720

	
1721 1721
    /// \name Execution of the writer
1722 1722
    /// @{
1723 1723

	
1724 1724
    /// \brief Start the batch processing
1725 1725
    ///
1726 1726
    /// This function starts the batch processing.
1727 1727
    void run() {
1728 1728

	
1729 1729
      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
1730 1730

	
1731 1731
      for (Sections::iterator it = _sections.begin();
1732 1732
           it != _sections.end(); ++it) {
1733 1733
        (*_os) << '@' << it->first << std::endl;
1734 1734
        it->second->process(*_os);
1735 1735
      }
1736 1736
    }
1737 1737

	
1738 1738
    /// \brief Give back the stream of the writer
1739 1739
    ///
1740 1740
    /// Returns the stream of the writer
1741 1741
    std::ostream& ostream() {
1742 1742
      return *_os;
1743 1743
    }
1744 1744

	
1745 1745
    /// @}
1746 1746

	
1747 1747
  };
1748 1748

	
1749 1749
  /// \brief Return a \ref SectionWriter class
1750 1750
  ///
1751 1751
  /// This function just returns a \ref SectionWriter class.
1752 1752
  /// \relates SectionWriter
1753 1753
  inline SectionWriter sectionWriter(std::ostream& os) {
1754 1754
    SectionWriter tmp(os);
1755 1755
    return tmp;
1756 1756
  }
1757 1757

	
1758 1758
  /// \brief Return a \ref SectionWriter class
1759 1759
  ///
1760 1760
  /// This function just returns a \ref SectionWriter class.
1761 1761
  /// \relates SectionWriter
1762 1762
  inline SectionWriter sectionWriter(const std::string& fn) {
1763 1763
    SectionWriter tmp(fn);
1764 1764
    return tmp;
1765 1765
  }
1766 1766

	
1767 1767
  /// \brief Return a \ref SectionWriter class
1768 1768
  ///
1769 1769
  /// This function just returns a \ref SectionWriter class.
1770 1770
  /// \relates SectionWriter
1771 1771
  inline SectionWriter sectionWriter(const char* fn) {
1772 1772
    SectionWriter tmp(fn);
1773 1773
    return tmp;
1774 1774
  }
1775 1775
}
1776 1776

	
1777 1777
#endif

Changeset was too big and was cut off... Show full diff

0 comments (0 inline)