↑ 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

	
... ...
@@ -210,111 +210,111 @@
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 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
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 '-',
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 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * 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

	
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
      }
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;
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;           \
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.
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;
Ignore white space 6 line context
... ...
@@ -298,365 +298,365 @@
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
... ...
@@ -1136,330 +1136,330 @@
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;
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;
... ...
@@ -413,193 +413,193 @@
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
    }
... ...
@@ -989,193 +989,193 @@
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
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_LIST_GRAPH_H
20 20
#define LEMON_LIST_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief ListDigraph, ListGraph classes.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/error.h>
28 28
#include <lemon/bits/graph_extender.h>
29 29

	
30 30
#include <vector>
31 31
#include <list>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  class ListDigraphBase {
36 36

	
37 37
  protected:
38 38
    struct NodeT {
39 39
      int first_in, first_out;
40 40
      int prev, next;
41 41
    };
42 42

	
43 43
    struct ArcT {
44 44
      int target, source;
45 45
      int prev_in, prev_out;
46 46
      int next_in, next_out;
47 47
    };
48 48

	
49 49
    std::vector<NodeT> nodes;
50 50

	
51 51
    int first_node;
52 52

	
53 53
    int first_free_node;
54 54

	
55 55
    std::vector<ArcT> arcs;
56 56

	
57 57
    int first_free_arc;
58 58

	
59 59
  public:
60 60

	
61 61
    typedef ListDigraphBase Digraph;
62 62

	
63 63
    class Node {
64 64
      friend class ListDigraphBase;
65 65
    protected:
66 66

	
67 67
      int id;
68 68
      explicit Node(int pid) { id = pid;}
69 69

	
70 70
    public:
71 71
      Node() {}
72 72
      Node (Invalid) { id = -1; }
73 73
      bool operator==(const Node& node) const {return id == node.id;}
74 74
      bool operator!=(const Node& node) const {return id != node.id;}
75 75
      bool operator<(const Node& node) const {return id < node.id;}
76 76
    };
77 77

	
78 78
    class Arc {
79 79
      friend class ListDigraphBase;
80 80
    protected:
81 81

	
82 82
      int id;
83 83
      explicit Arc(int pid) { id = pid;}
84 84

	
85 85
    public:
86 86
      Arc() {}
87 87
      Arc (Invalid) { id = -1; }
88 88
      bool operator==(const Arc& arc) const {return id == arc.id;}
89 89
      bool operator!=(const Arc& arc) const {return id != arc.id;}
90 90
      bool operator<(const Arc& arc) const {return id < arc.id;}
91 91
    };
92 92

	
93 93

	
94 94

	
95 95
    ListDigraphBase()
96 96
      : nodes(), first_node(-1),
97 97
        first_free_node(-1), arcs(), first_free_arc(-1) {}
98 98

	
99 99

	
100 100
    int maxNodeId() const { return nodes.size()-1; }
101 101
    int maxArcId() const { return arcs.size()-1; }
... ...
@@ -747,194 +747,194 @@
747 747
      /// Undo the changes until the last snapshot created by save().
748 748
      void restore() {
749 749
        detach();
750 750
        for(std::list<Arc>::iterator it = added_arcs.begin();
751 751
            it != added_arcs.end(); ++it) {
752 752
          digraph->erase(*it);
753 753
        }
754 754
        for(std::list<Node>::iterator it = added_nodes.begin();
755 755
            it != added_nodes.end(); ++it) {
756 756
          digraph->erase(*it);
757 757
        }
758 758
        clear();
759 759
      }
760 760

	
761 761
      /// \brief Gives back true when the snapshot is valid.
762 762
      ///
763 763
      /// Gives back true when the snapshot is valid.
764 764
      bool valid() const {
765 765
        return attached();
766 766
      }
767 767
    };
768 768

	
769 769
  };
770 770

	
771 771
  ///@}
772 772

	
773 773
  class ListGraphBase {
774 774

	
775 775
  protected:
776 776

	
777 777
    struct NodeT {
778 778
      int first_out;
779 779
      int prev, next;
780 780
    };
781 781

	
782 782
    struct ArcT {
783 783
      int target;
784 784
      int prev_out, next_out;
785 785
    };
786 786

	
787 787
    std::vector<NodeT> nodes;
788 788

	
789 789
    int first_node;
790 790

	
791 791
    int first_free_node;
792 792

	
793 793
    std::vector<ArcT> arcs;
794 794

	
795 795
    int first_free_arc;
796 796

	
797 797
  public:
798 798

	
799 799
    typedef ListGraphBase Digraph;
800 800

	
801 801
    class Node;
802 802
    class Arc;
803 803
    class Edge;
804 804

	
805 805
    class Node {
806 806
      friend class ListGraphBase;
807 807
    protected:
808 808

	
809 809
      int id;
810 810
      explicit Node(int pid) { id = pid;}
811 811

	
812 812
    public:
813 813
      Node() {}
814 814
      Node (Invalid) { id = -1; }
815 815
      bool operator==(const Node& node) const {return id == node.id;}
816 816
      bool operator!=(const Node& node) const {return id != node.id;}
817 817
      bool operator<(const Node& node) const {return id < node.id;}
818 818
    };
819 819

	
820 820
    class Edge {
821 821
      friend class ListGraphBase;
822 822
    protected:
823 823

	
824 824
      int id;
825 825
      explicit Edge(int pid) { id = pid;}
826 826

	
827 827
    public:
828 828
      Edge() {}
829 829
      Edge (Invalid) { id = -1; }
830 830
      bool operator==(const Edge& edge) const {return id == edge.id;}
831 831
      bool operator!=(const Edge& edge) const {return id != edge.id;}
832 832
      bool operator<(const Edge& edge) const {return id < edge.id;}
833 833
    };
834 834

	
835 835
    class Arc {
836 836
      friend class ListGraphBase;
837 837
    protected:
838 838

	
839 839
      int id;
840 840
      explicit Arc(int pid) { id = pid;}
841 841

	
842 842
    public:
843
      operator Edge() const { 
844
        return id != -1 ? edgeFromId(id / 2) : INVALID; 
843
      operator Edge() const {
844
        return id != -1 ? edgeFromId(id / 2) : INVALID;
845 845
      }
846 846

	
847 847
      Arc() {}
848 848
      Arc (Invalid) { id = -1; }
849 849
      bool operator==(const Arc& arc) const {return id == arc.id;}
850 850
      bool operator!=(const Arc& arc) const {return id != arc.id;}
851 851
      bool operator<(const Arc& arc) const {return id < arc.id;}
852 852
    };
853 853

	
854 854

	
855 855

	
856 856
    ListGraphBase()
857 857
      : nodes(), first_node(-1),
858 858
        first_free_node(-1), arcs(), first_free_arc(-1) {}
859 859

	
860 860

	
861 861
    int maxNodeId() const { return nodes.size()-1; }
862 862
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
863 863
    int maxArcId() const { return arcs.size()-1; }
864 864

	
865 865
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
866 866
    Node target(Arc e) const { return Node(arcs[e.id].target); }
867 867

	
868 868
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
869 869
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
870 870

	
871 871
    static bool direction(Arc e) {
872 872
      return (e.id & 1) == 1;
873 873
    }
874 874

	
875 875
    static Arc direct(Edge e, bool d) {
876 876
      return Arc(e.id * 2 + (d ? 1 : 0));
877 877
    }
878 878

	
879 879
    void first(Node& node) const {
880 880
      node.id = first_node;
881 881
    }
882 882

	
883 883
    void next(Node& node) const {
884 884
      node.id = nodes[node.id].next;
885 885
    }
886 886

	
887 887
    void first(Arc& e) const {
888 888
      int n = first_node;
889 889
      while (n != -1 && nodes[n].first_out == -1) {
890 890
        n = nodes[n].next;
891 891
      }
892 892
      e.id = (n == -1) ? -1 : nodes[n].first_out;
893 893
    }
894 894

	
895 895
    void next(Arc& e) const {
896 896
      if (arcs[e.id].next_out != -1) {
897 897
        e.id = arcs[e.id].next_out;
898 898
      } else {
899 899
        int n = nodes[arcs[e.id ^ 1].target].next;
900 900
        while(n != -1 && nodes[n].first_out == -1) {
901 901
          n = nodes[n].next;
902 902
        }
903 903
        e.id = (n == -1) ? -1 : nodes[n].first_out;
904 904
      }
905 905
    }
906 906

	
907 907
    void first(Edge& e) const {
908 908
      int n = first_node;
909 909
      while (n != -1) {
910 910
        e.id = nodes[n].first_out;
911 911
        while ((e.id & 1) != 1) {
912 912
          e.id = arcs[e.id].next_out;
913 913
        }
914 914
        if (e.id != -1) {
915 915
          e.id /= 2;
916 916
          return;
917 917
        }
918 918
        n = nodes[n].next;
919 919
      }
920 920
      e.id = -1;
921 921
    }
922 922

	
923 923
    void next(Edge& e) const {
924 924
      int n = arcs[e.id * 2].target;
925 925
      e.id = arcs[(e.id * 2) | 1].next_out;
926 926
      while ((e.id & 1) != 1) {
927 927
        e.id = arcs[e.id].next_out;
928 928
      }
929 929
      if (e.id != -1) {
930 930
        e.id /= 2;
931 931
        return;
932 932
      }
933 933
      n = nodes[n].next;
934 934
      while (n != -1) {
935 935
        e.id = nodes[n].first_out;
936 936
        while ((e.id & 1) != 1) {
937 937
          e.id = arcs[e.id].next_out;
938 938
        }
939 939
        if (e.id != -1) {
940 940
          e.id /= 2;
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 paths
20 20
///\file
21 21
///\brief Classes for representing paths in digraphs.
22 22
///
23 23

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

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

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

	
34 34
namespace lemon {
35 35

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

	
39 39

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

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

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

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

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

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

	
99 99
    private:
100 100

	
101 101
      ArcIt(const Path &_path, int _idx)
... ...
@@ -873,206 +873,206 @@
873 873
    void build(const CPath& path) {
874 874
      len = path.length();
875 875
      arcs = new Arc[len];
876 876
      int index = 0;
877 877
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
878 878
        arcs[index] = it;
879 879
        ++index;
880 880
      }
881 881
    }
882 882

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

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

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

	
903 903
  namespace _path_bits {
904 904

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

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

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

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

	
931 931
    template <typename From, typename To,
932 932
              bool buildEnable = BuildTagIndicator<To>::value>
933 933
    struct PathCopySelectorForward {
934 934
      static void copy(const From& from, To& to) {
935 935
        to.clear();
936 936
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
937 937
          to.addBack(it);
938 938
        }
939 939
      }
940 940
    };
941 941

	
942 942
    template <typename From, typename To>
943 943
    struct PathCopySelectorForward<From, To, true> {
944 944
      static void copy(const From& from, To& to) {
945 945
        to.clear();
946 946
        to.build(from);
947 947
      }
948 948
    };
949 949

	
950 950
    template <typename From, typename To,
951 951
              bool buildEnable = BuildTagIndicator<To>::value>
952 952
    struct PathCopySelectorBackward {
953 953
      static void copy(const From& from, To& to) {
954 954
        to.clear();
955 955
        for (typename From::RevArcIt it(from); it != INVALID; ++it) {
956 956
          to.addFront(it);
957 957
        }
958 958
      }
959 959
    };
960 960

	
961 961
    template <typename From, typename To>
962 962
    struct PathCopySelectorBackward<From, To, true> {
963 963
      static void copy(const From& from, To& to) {
964 964
        to.clear();
965 965
        to.buildRev(from);
966 966
      }
967 967
    };
968 968

	
969
    
969

	
970 970
    template <typename From, typename To,
971 971
              bool revEnable = RevPathTagIndicator<From>::value>
972 972
    struct PathCopySelector {
973 973
      static void copy(const From& from, To& to) {
974 974
        PathCopySelectorForward<From, To>::copy(from, to);
975
      }      
975
      }
976 976
    };
977 977

	
978 978
    template <typename From, typename To>
979 979
    struct PathCopySelector<From, To, true> {
980 980
      static void copy(const From& from, To& to) {
981 981
        PathCopySelectorBackward<From, To>::copy(from, to);
982
      }      
982
      }
983 983
    };
984 984

	
985 985
  }
986 986

	
987 987

	
988 988
  /// \brief Make a copy of a path.
989 989
  ///
990 990
  /// This function makes a copy of a path.
991 991
  template <typename From, typename To>
992 992
  void pathCopy(const From& from, To& to) {
993 993
    checkConcept<concepts::PathDumper<typename From::Digraph>, From>();
994 994
    _path_bits::PathCopySelector<From, To>::copy(from, to);
995 995
  }
996 996

	
997 997
  /// \brief Deprecated version of \ref pathCopy().
998 998
  ///
999 999
  /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
1000 1000
  template <typename To, typename From>
1001 1001
  void copyPath(To& to, const From& from) {
1002 1002
    pathCopy(from, to);
1003 1003
  }
1004 1004

	
1005 1005
  /// \brief Check the consistency of a path.
1006 1006
  ///
1007 1007
  /// This function checks that the target of each arc is the same
1008 1008
  /// as the source of the next one.
1009 1009
  ///
1010 1010
  template <typename Digraph, typename Path>
1011 1011
  bool checkPath(const Digraph& digraph, const Path& path) {
1012 1012
    typename Path::ArcIt it(path);
1013 1013
    if (it == INVALID) return true;
1014 1014
    typename Digraph::Node node = digraph.target(it);
1015 1015
    ++it;
1016 1016
    while (it != INVALID) {
1017 1017
      if (digraph.source(it) != node) return false;
1018 1018
      node = digraph.target(it);
1019 1019
      ++it;
1020 1020
    }
1021 1021
    return true;
1022 1022
  }
1023 1023

	
1024 1024
  /// \brief The source of a path
1025 1025
  ///
1026 1026
  /// This function returns the source node of the given path.
1027 1027
  /// If the path is empty, then it returns \c INVALID.
1028 1028
  template <typename Digraph, typename Path>
1029 1029
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1030 1030
    return path.empty() ? INVALID : digraph.source(path.front());
1031 1031
  }
1032 1032

	
1033 1033
  /// \brief The target of a path
1034 1034
  ///
1035 1035
  /// This function returns the target node of the given path.
1036 1036
  /// If the path is empty, then it returns \c INVALID.
1037 1037
  template <typename Digraph, typename Path>
1038 1038
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1039 1039
    return path.empty() ? INVALID : digraph.target(path.back());
1040 1040
  }
1041 1041

	
1042 1042
  /// \brief Class which helps to iterate through the nodes of a path
1043 1043
  ///
1044 1044
  /// In a sense, the path can be treated as a list of arcs. The
1045 1045
  /// lemon path type stores only this list. As a consequence, it
1046 1046
  /// cannot enumerate the nodes in the path and the zero length paths
1047 1047
  /// cannot have a source node.
1048 1048
  ///
1049 1049
  /// This class implements the node iterator of a path structure. To
1050 1050
  /// provide this feature, the underlying digraph should be passed to
1051 1051
  /// the constructor of the iterator.
1052 1052
  template <typename Path>
1053 1053
  class PathNodeIt {
1054 1054
  private:
1055 1055
    const typename Path::Digraph *_digraph;
1056 1056
    typename Path::ArcIt _it;
1057 1057
    typename Path::Digraph::Node _nd;
1058 1058

	
1059 1059
  public:
1060 1060

	
1061 1061
    typedef typename Path::Digraph Digraph;
1062 1062
    typedef typename Digraph::Node Node;
1063 1063

	
1064 1064
    /// Default constructor
1065 1065
    PathNodeIt() {}
1066 1066
    /// Invalid constructor
1067 1067
    PathNodeIt(Invalid)
1068 1068
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1069 1069
    /// Constructor
1070 1070
    PathNodeIt(const Digraph& digraph, const Path& path)
1071 1071
      : _digraph(&digraph), _it(path) {
1072 1072
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1073 1073
    }
1074 1074
    /// Constructor
1075 1075
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1076 1076
      : _digraph(&digraph), _it(path), _nd(src) {}
1077 1077

	
1078 1078
    ///Conversion to Digraph::Node
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
 * This file contains the reimplemented version of the Mersenne Twister
21 21
 * Generator of Matsumoto and Nishimura.
22 22
 *
23 23
 * See the appropriate copyright notice below.
24 24
 *
25 25
 * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
26 26
 * All rights reserved.
27 27
 *
28 28
 * Redistribution and use in source and binary forms, with or without
29 29
 * modification, are permitted provided that the following conditions
30 30
 * are met:
31 31
 *
32 32
 * 1. Redistributions of source code must retain the above copyright
33 33
 *    notice, this list of conditions and the following disclaimer.
34 34
 *
35 35
 * 2. Redistributions in binary form must reproduce the above copyright
36 36
 *    notice, this list of conditions and the following disclaimer in the
37 37
 *    documentation and/or other materials provided with the distribution.
38 38
 *
39 39
 * 3. The names of its contributors may not be used to endorse or promote
40 40
 *    products derived from this software without specific prior written
41 41
 *    permission.
42 42
 *
43 43
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 44
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 45
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46 46
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
47 47
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48 48
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49 49
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 50
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 51
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 52
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 53
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 54
 * OF THE POSSIBILITY OF SUCH DAMAGE.
55 55
 *
56 56
 *
57 57
 * Any feedback is very welcome.
58 58
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
59 59
 * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
60 60
 */
61 61

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

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

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

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

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

	
87 87
namespace lemon {
88 88

	
89 89
  namespace _random_bits {
90 90

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

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

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

	
100 100
      static const int length = 624;
101 101
      static const int shift = 397;
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_SMART_GRAPH_H
20 20
#define LEMON_SMART_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief SmartDigraph and SmartGraph classes.
25 25

	
26 26
#include <vector>
27 27

	
28 28
#include <lemon/core.h>
29 29
#include <lemon/error.h>
30 30
#include <lemon/bits/graph_extender.h>
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  class SmartDigraph;
35 35
  ///Base of SmartDigraph
36 36

	
37 37
  ///Base of SmartDigraph
38 38
  ///
39 39
  class SmartDigraphBase {
40 40
  protected:
41 41

	
42 42
    struct NodeT
43 43
    {
44 44
      int first_in, first_out;
45 45
      NodeT() {}
46 46
    };
47 47
    struct ArcT
48 48
    {
49 49
      int target, source, next_in, next_out;
50 50
      ArcT() {}
51 51
    };
52 52

	
53 53
    std::vector<NodeT> nodes;
54 54
    std::vector<ArcT> arcs;
55 55

	
56 56
  public:
57 57

	
58 58
    typedef SmartDigraphBase Graph;
59 59

	
60 60
    class Node;
61 61
    class Arc;
62 62

	
63 63
  public:
64 64

	
65 65
    SmartDigraphBase() : nodes(), arcs() { }
66 66
    SmartDigraphBase(const SmartDigraphBase &_g)
67 67
      : nodes(_g.nodes), arcs(_g.arcs) { }
68 68

	
69 69
    typedef True NodeNumTag;
70 70
    typedef True EdgeNumTag;
71 71

	
72 72
    int nodeNum() const { return nodes.size(); }
73 73
    int arcNum() const { return arcs.size(); }
74 74

	
75 75
    int maxNodeId() const { return nodes.size()-1; }
76 76
    int maxArcId() const { return arcs.size()-1; }
77 77

	
78 78
    Node addNode() {
79 79
      int n = nodes.size();
80 80
      nodes.push_back(NodeT());
81 81
      nodes[n].first_in = -1;
82 82
      nodes[n].first_out = -1;
83 83
      return Node(n);
84 84
    }
85 85

	
86 86
    Arc addArc(Node u, Node v) {
87 87
      int n = arcs.size();
88 88
      arcs.push_back(ArcT());
89 89
      arcs[n].source = u._id;
90 90
      arcs[n].target = v._id;
91 91
      arcs[n].next_out = nodes[u._id].first_out;
92 92
      arcs[n].next_in = nodes[v._id].first_in;
93 93
      nodes[u._id].first_out = nodes[v._id].first_in = n;
94 94

	
95 95
      return Arc(n);
96 96
    }
97 97

	
98 98
    void clear() {
99 99
      arcs.clear();
100 100
      nodes.clear();
101 101
    }
... ...
@@ -373,194 +373,194 @@
373 373
        arc_num=_graph->arcs.size();
374 374
      }
375 375

	
376 376
      ///Make a snapshot.
377 377

	
378 378
      ///Make a snapshot of the digraph.
379 379
      ///
380 380
      ///This function can be called more than once. In case of a repeated
381 381
      ///call, the previous snapshot gets lost.
382 382
      ///\param graph The digraph we make the snapshot of.
383 383
      void save(SmartDigraph &graph)
384 384
      {
385 385
        _graph=&graph;
386 386
        node_num=_graph->nodes.size();
387 387
        arc_num=_graph->arcs.size();
388 388
      }
389 389

	
390 390
      ///Undo the changes until a snapshot.
391 391

	
392 392
      ///Undo the changes until a snapshot created by save().
393 393
      ///
394 394
      ///\note After you restored a state, you cannot restore
395 395
      ///a later state, in other word you cannot add again the arcs deleted
396 396
      ///by restore().
397 397
      void restore()
398 398
      {
399 399
        _graph->restoreSnapshot(*this);
400 400
      }
401 401
    };
402 402
  };
403 403

	
404 404

	
405 405
  class SmartGraphBase {
406 406

	
407 407
  protected:
408 408

	
409 409
    struct NodeT {
410 410
      int first_out;
411 411
    };
412 412

	
413 413
    struct ArcT {
414 414
      int target;
415 415
      int next_out;
416 416
    };
417 417

	
418 418
    std::vector<NodeT> nodes;
419 419
    std::vector<ArcT> arcs;
420 420

	
421 421
    int first_free_arc;
422 422

	
423 423
  public:
424 424

	
425 425
    typedef SmartGraphBase Digraph;
426 426

	
427 427
    class Node;
428 428
    class Arc;
429 429
    class Edge;
430 430

	
431 431
    class Node {
432 432
      friend class SmartGraphBase;
433 433
    protected:
434 434

	
435 435
      int _id;
436 436
      explicit Node(int id) { _id = id;}
437 437

	
438 438
    public:
439 439
      Node() {}
440 440
      Node (Invalid) { _id = -1; }
441 441
      bool operator==(const Node& node) const {return _id == node._id;}
442 442
      bool operator!=(const Node& node) const {return _id != node._id;}
443 443
      bool operator<(const Node& node) const {return _id < node._id;}
444 444
    };
445 445

	
446 446
    class Edge {
447 447
      friend class SmartGraphBase;
448 448
    protected:
449 449

	
450 450
      int _id;
451 451
      explicit Edge(int id) { _id = id;}
452 452

	
453 453
    public:
454 454
      Edge() {}
455 455
      Edge (Invalid) { _id = -1; }
456 456
      bool operator==(const Edge& arc) const {return _id == arc._id;}
457 457
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
458 458
      bool operator<(const Edge& arc) const {return _id < arc._id;}
459 459
    };
460 460

	
461 461
    class Arc {
462 462
      friend class SmartGraphBase;
463 463
    protected:
464 464

	
465 465
      int _id;
466 466
      explicit Arc(int id) { _id = id;}
467 467

	
468 468
    public:
469
      operator Edge() const { 
470
        return _id != -1 ? edgeFromId(_id / 2) : INVALID; 
469
      operator Edge() const {
470
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
471 471
      }
472 472

	
473 473
      Arc() {}
474 474
      Arc (Invalid) { _id = -1; }
475 475
      bool operator==(const Arc& arc) const {return _id == arc._id;}
476 476
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
477 477
      bool operator<(const Arc& arc) const {return _id < arc._id;}
478 478
    };
479 479

	
480 480

	
481 481

	
482 482
    SmartGraphBase()
483 483
      : nodes(), arcs() {}
484 484

	
485 485

	
486 486
    int maxNodeId() const { return nodes.size()-1; }
487 487
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
488 488
    int maxArcId() const { return arcs.size()-1; }
489 489

	
490 490
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
491 491
    Node target(Arc e) const { return Node(arcs[e._id].target); }
492 492

	
493 493
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
494 494
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
495 495

	
496 496
    static bool direction(Arc e) {
497 497
      return (e._id & 1) == 1;
498 498
    }
499 499

	
500 500
    static Arc direct(Edge e, bool d) {
501 501
      return Arc(e._id * 2 + (d ? 1 : 0));
502 502
    }
503 503

	
504 504
    void first(Node& node) const {
505 505
      node._id = nodes.size() - 1;
506 506
    }
507 507

	
508 508
    void next(Node& node) const {
509 509
      --node._id;
510 510
    }
511 511

	
512 512
    void first(Arc& arc) const {
513 513
      arc._id = arcs.size() - 1;
514 514
    }
515 515

	
516 516
    void next(Arc& arc) const {
517 517
      --arc._id;
518 518
    }
519 519

	
520 520
    void first(Edge& arc) const {
521 521
      arc._id = arcs.size() / 2 - 1;
522 522
    }
523 523

	
524 524
    void next(Edge& arc) const {
525 525
      --arc._id;
526 526
    }
527 527

	
528 528
    void firstOut(Arc &arc, const Node& v) const {
529 529
      arc._id = nodes[v._id].first_out;
530 530
    }
531 531
    void nextOut(Arc &arc) const {
532 532
      arc._id = arcs[arc._id].next_out;
533 533
    }
534 534

	
535 535
    void firstIn(Arc &arc, const Node& v) const {
536 536
      arc._id = ((nodes[v._id].first_out) ^ 1);
537 537
      if (arc._id == -2) arc._id = -1;
538 538
    }
539 539
    void nextIn(Arc &arc) const {
540 540
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
541 541
      if (arc._id == -2) arc._id = -1;
542 542
    }
543 543

	
544 544
    void firstInc(Edge &arc, bool& d, const Node& v) const {
545 545
      int de = nodes[v._id].first_out;
546 546
      if (de != -1) {
547 547
        arc._id = de / 2;
548 548
        d = ((de & 1) == 1);
549 549
      } else {
550 550
        arc._id = -1;
551 551
        d = true;
552 552
      }
553 553
    }
554 554
    void nextInc(Edge &arc, bool& d) const {
555 555
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
556 556
      if (de != -1) {
557 557
        arc._id = de / 2;
558 558
        d = ((de & 1) == 1);
559 559
      } else {
560 560
        arc._id = -1;
561 561
        d = true;
562 562
      }
563 563
    }
564 564

	
565 565
    static int id(Node v) { return v._id; }
566 566
    static int id(Arc e) { return e._id; }
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_TIME_MEASURE_H
20 20
#define LEMON_TIME_MEASURE_H
21 21

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

	
26 26
#ifdef WIN32
27 27
#include <lemon/bits/windows.h>
28 28
#else
29 29
#include <unistd.h>
30 30
#include <sys/times.h>
31 31
#include <sys/time.h>
32 32
#endif
33 33

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

	
38 38
namespace lemon {
39 39

	
40 40
  /// \addtogroup timecount
41 41
  /// @{
42 42

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

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

	
58 58
  class TimeStamp
59 59
  {
60 60
    double utime;
61 61
    double stime;
62 62
    double cutime;
63 63
    double cstime;
64 64
    double rtime;
65 65

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

	
70 70
  public:
71 71

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

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

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

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

	
101 101
    ///\e
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_TOLERANCE_H
20 20
#define LEMON_TOLERANCE_H
21 21

	
22 22
///\ingroup misc
23 23
///\file
24 24
///\brief A basic tool to handle the anomalies of calculation with
25 25
///floating point numbers.
26 26
///
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  /// \addtogroup misc
31 31
  /// @{
32 32

	
33 33
  ///\brief A class to provide a basic way to
34 34
  ///handle the comparison of numbers that are obtained
35 35
  ///as a result of a probably inexact computation.
36 36
  ///
37 37
  ///\ref Tolerance is a class to provide a basic way to
38 38
  ///handle the comparison of numbers that are obtained
39 39
  ///as a result of a probably inexact computation.
40 40
  ///
41 41
  ///The general implementation is suitable only if the data type is exact,
42 42
  ///like the integer types, otherwise a specialized version must be
43 43
  ///implemented. These specialized classes like
44 44
  ///Tolerance<double> may offer additional tuning parameters.
45 45
  ///
46 46
  ///\sa Tolerance<float>
47 47
  ///\sa Tolerance<double>
48 48
  ///\sa Tolerance<long double>
49 49

	
50 50
  template<class T>
51 51
  class Tolerance
52 52
  {
53 53
  public:
54 54
    typedef T Value;
55 55

	
56 56
    ///\name Comparisons
57 57
    ///The concept is that these bool functions return \c true only if
58 58
    ///the related comparisons hold even if some numerical error appeared
59 59
    ///during the computations.
60 60

	
61 61
    ///@{
62 62

	
63 63
    ///Returns \c true if \c a is \e surely strictly less than \c b
64 64
    static bool less(Value a,Value b) {return a<b;}
65 65
    ///Returns \c true if \c a is \e surely different from \c b
66 66
    static bool different(Value a,Value b) {return a!=b;}
67 67
    ///Returns \c true if \c a is \e surely positive
68 68
    static bool positive(Value a) {return static_cast<Value>(0) < a;}
69 69
    ///Returns \c true if \c a is \e surely negative
70 70
    static bool negative(Value a) {return a < static_cast<Value>(0);}
71 71
    ///Returns \c true if \c a is \e surely non-zero
72 72
    static bool nonZero(Value a) {return a != static_cast<Value>(0);}
73 73

	
74 74
    ///@}
75 75

	
76 76
    ///Returns the zero value.
77 77
    static Value zero() {return static_cast<Value>(0);}
78 78

	
79 79
    //   static bool finite(Value a) {}
80 80
    //   static Value big() {}
81 81
    //   static Value negativeBig() {}
82 82
  };
83 83

	
84 84

	
85 85
  ///Float specialization of Tolerance.
86 86

	
87 87
  ///Float specialization of Tolerance.
88 88
  ///\sa Tolerance
89 89
  ///\relates Tolerance
90 90
  template<>
91 91
  class Tolerance<float>
92 92
  {
93 93
    static float def_epsilon;
94 94
    float _epsilon;
95 95
  public:
96 96
    ///\e
97 97
    typedef float Value;
98 98

	
99 99
    ///Constructor setting the epsilon tolerance to the default value.
100 100
    Tolerance() : _epsilon(def_epsilon) {}
101 101
    ///Constructor setting the epsilon tolerance to the given value.
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_UNION_FIND_H
20 20
#define LEMON_UNION_FIND_H
21 21

	
22 22
//!\ingroup auxdat
23 23
//!\file
24 24
//!\brief Union-Find data structures.
25 25
//!
26 26

	
27 27
#include <vector>
28 28
#include <list>
29 29
#include <utility>
30 30
#include <algorithm>
31 31
#include <functional>
32 32

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

	
35 35
namespace lemon {
36 36

	
37 37
  /// \ingroup auxdat
38 38
  ///
39 39
  /// \brief A \e Union-Find data structure implementation
40 40
  ///
41 41
  /// The class implements the \e Union-Find data structure.
42 42
  /// The union operation uses rank heuristic, while
43 43
  /// the find operation uses path compression.
44 44
  /// This is a very simple but efficient implementation, providing
45 45
  /// only four methods: join (union), find, insert and size.
46 46
  /// For more features see the \ref UnionFindEnum class.
47 47
  ///
48 48
  /// It is primarily used in Kruskal algorithm for finding minimal
49 49
  /// cost spanning tree in a graph.
50 50
  /// \sa kruskal()
51 51
  ///
52 52
  /// \pre You need to add all the elements by the \ref insert()
53 53
  /// method.
54 54
  template <typename _ItemIntMap>
55 55
  class UnionFind {
56 56
  public:
57 57

	
58 58
    typedef _ItemIntMap ItemIntMap;
59 59
    typedef typename ItemIntMap::Key Item;
60 60

	
61 61
  private:
62 62
    // If the items vector stores negative value for an item then
63 63
    // that item is root item and it has -items[it] component size.
64 64
    // Else the items[it] contains the index of the parent.
65 65
    std::vector<int> items;
66 66
    ItemIntMap& index;
67 67

	
68 68
    bool rep(int idx) const {
69 69
      return items[idx] < 0;
70 70
    }
71 71

	
72 72
    int repIndex(int idx) const {
73 73
      int k = idx;
74 74
      while (!rep(k)) {
75 75
        k = items[k] ;
76 76
      }
77 77
      while (idx != k) {
78 78
        int next = items[idx];
79 79
        const_cast<int&>(items[idx]) = k;
80 80
        idx = next;
81 81
      }
82 82
      return k;
83 83
    }
84 84

	
85 85
  public:
86 86

	
87 87
    /// \brief Constructor
88 88
    ///
89 89
    /// Constructor of the UnionFind class. You should give an item to
90 90
    /// integer map which will be used from the data structure. If you
91 91
    /// modify directly this map that may cause segmentation fault,
92 92
    /// invalid data structure, or infinite loop when you use again
93 93
    /// the union-find.
94 94
    UnionFind(ItemIntMap& m) : index(m) {}
95 95

	
96 96
    /// \brief Returns the index of the element's component.
97 97
    ///
98 98
    /// The method returns the index of the element's component.
99 99
    /// This is an integer between zero and the number of inserted elements.
100 100
    ///
101 101
    int find(const Item& a) {
... ...
@@ -1096,193 +1096,193 @@
1096 1096
      }
1097 1097
      nodes[jd].next = nodes[id].next;
1098 1098
      nodes[jd].prev = id;
1099 1099
      nodes[id].next = jd;
1100 1100
      nodes[jd].parent = kd;
1101 1101
    }
1102 1102

	
1103 1103
    void pushRight(int id, int jd) {
1104 1104
      nodes[id].size += 1;
1105 1105
      nodes[jd].prev = nodes[id].right;
1106 1106
      nodes[jd].next = -1;
1107 1107
      nodes[nodes[id].right].next = jd;
1108 1108
      nodes[id].right = jd;
1109 1109
      nodes[jd].parent = id;
1110 1110
    }
1111 1111

	
1112 1112
    void popRight(int id) {
1113 1113
      nodes[id].size -= 1;
1114 1114
      int jd = nodes[id].right;
1115 1115
      nodes[nodes[jd].prev].next = -1;
1116 1116
      nodes[id].right = nodes[jd].prev;
1117 1117
    }
1118 1118

	
1119 1119
    void splice(int id, int jd) {
1120 1120
      nodes[id].size += nodes[jd].size;
1121 1121
      nodes[nodes[id].right].next = nodes[jd].left;
1122 1122
      nodes[nodes[jd].left].prev = nodes[id].right;
1123 1123
      int kd = nodes[jd].left;
1124 1124
      while (kd != -1) {
1125 1125
        nodes[kd].parent = id;
1126 1126
        kd = nodes[kd].next;
1127 1127
      }
1128 1128
      nodes[id].right = nodes[jd].right;
1129 1129
    }
1130 1130

	
1131 1131
    void split(int id, int jd) {
1132 1132
      int kd = nodes[id].parent;
1133 1133
      nodes[kd].right = nodes[id].prev;
1134 1134
      nodes[nodes[id].prev].next = -1;
1135 1135

	
1136 1136
      nodes[jd].left = id;
1137 1137
      nodes[id].prev = -1;
1138 1138
      int num = 0;
1139 1139
      while (id != -1) {
1140 1140
        nodes[id].parent = jd;
1141 1141
        nodes[jd].right = id;
1142 1142
        id = nodes[id].next;
1143 1143
        ++num;
1144 1144
      }
1145 1145
      nodes[kd].size -= num;
1146 1146
      nodes[jd].size = num;
1147 1147
    }
1148 1148

	
1149 1149
    void pushLeft(int id, int jd) {
1150 1150
      nodes[id].size += 1;
1151 1151
      nodes[jd].next = nodes[id].left;
1152 1152
      nodes[jd].prev = -1;
1153 1153
      nodes[nodes[id].left].prev = jd;
1154 1154
      nodes[id].left = jd;
1155 1155
      nodes[jd].parent = id;
1156 1156
    }
1157 1157

	
1158 1158
    void popLeft(int id) {
1159 1159
      nodes[id].size -= 1;
1160 1160
      int jd = nodes[id].left;
1161 1161
      nodes[nodes[jd].next].prev = -1;
1162 1162
      nodes[id].left = nodes[jd].next;
1163 1163
    }
1164 1164

	
1165 1165
    void repairLeft(int id) {
1166 1166
      int jd = ~(classes[id].parent);
1167 1167
      while (nodes[jd].left != -1) {
1168 1168
        int kd = nodes[jd].left;
1169 1169
        if (nodes[jd].size == 1) {
1170 1170
          if (nodes[jd].parent < 0) {
1171 1171
            classes[id].parent = ~kd;
1172 1172
            classes[id].depth -= 1;
1173 1173
            nodes[kd].parent = ~id;
1174 1174
            deleteNode(jd);
1175 1175
            jd = kd;
1176 1176
          } else {
1177 1177
            int pd = nodes[jd].parent;
1178 1178
            if (nodes[nodes[jd].next].size < cmax) {
1179 1179
              pushLeft(nodes[jd].next, nodes[jd].left);
1180 1180
              if (less(jd, nodes[jd].next) ||
1181 1181
                  nodes[jd].item == nodes[pd].item) {
1182 1182
                nodes[nodes[jd].next].prio = nodes[jd].prio;
1183 1183
                nodes[nodes[jd].next].item = nodes[jd].item;
1184 1184
              }
1185 1185
              popLeft(pd);
1186 1186
              deleteNode(jd);
1187 1187
              jd = pd;
1188 1188
            } else {
1189 1189
              int ld = nodes[nodes[jd].next].left;
1190 1190
              popLeft(nodes[jd].next);
1191 1191
              pushRight(jd, ld);
1192
              if (less(ld, nodes[jd].left) || 
1192
              if (less(ld, nodes[jd].left) ||
1193 1193
                  nodes[ld].item == nodes[pd].item) {
1194 1194
                nodes[jd].item = nodes[ld].item;
1195 1195
                nodes[jd].prio = nodes[ld].prio;
1196 1196
              }
1197 1197
              if (nodes[nodes[jd].next].item == nodes[ld].item) {
1198 1198
                setPrio(nodes[jd].next);
1199 1199
              }
1200 1200
              jd = nodes[jd].left;
1201 1201
            }
1202 1202
          }
1203 1203
        } else {
1204 1204
          jd = nodes[jd].left;
1205 1205
        }
1206 1206
      }
1207 1207
    }
1208 1208

	
1209 1209
    void repairRight(int id) {
1210 1210
      int jd = ~(classes[id].parent);
1211 1211
      while (nodes[jd].right != -1) {
1212 1212
        int kd = nodes[jd].right;
1213 1213
        if (nodes[jd].size == 1) {
1214 1214
          if (nodes[jd].parent < 0) {
1215 1215
            classes[id].parent = ~kd;
1216 1216
            classes[id].depth -= 1;
1217 1217
            nodes[kd].parent = ~id;
1218 1218
            deleteNode(jd);
1219 1219
            jd = kd;
1220 1220
          } else {
1221 1221
            int pd = nodes[jd].parent;
1222 1222
            if (nodes[nodes[jd].prev].size < cmax) {
1223 1223
              pushRight(nodes[jd].prev, nodes[jd].right);
1224 1224
              if (less(jd, nodes[jd].prev) ||
1225 1225
                  nodes[jd].item == nodes[pd].item) {
1226 1226
                nodes[nodes[jd].prev].prio = nodes[jd].prio;
1227 1227
                nodes[nodes[jd].prev].item = nodes[jd].item;
1228 1228
              }
1229 1229
              popRight(pd);
1230 1230
              deleteNode(jd);
1231 1231
              jd = pd;
1232 1232
            } else {
1233 1233
              int ld = nodes[nodes[jd].prev].right;
1234 1234
              popRight(nodes[jd].prev);
1235 1235
              pushLeft(jd, ld);
1236 1236
              if (less(ld, nodes[jd].right) ||
1237 1237
                  nodes[ld].item == nodes[pd].item) {
1238 1238
                nodes[jd].item = nodes[ld].item;
1239 1239
                nodes[jd].prio = nodes[ld].prio;
1240 1240
              }
1241 1241
              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
1242 1242
                setPrio(nodes[jd].prev);
1243 1243
              }
1244 1244
              jd = nodes[jd].right;
1245 1245
            }
1246 1246
          }
1247 1247
        } else {
1248 1248
          jd = nodes[jd].right;
1249 1249
        }
1250 1250
      }
1251 1251
    }
1252 1252

	
1253 1253

	
1254 1254
    bool less(int id, int jd) const {
1255 1255
      return comp(nodes[id].prio, nodes[jd].prio);
1256 1256
    }
1257 1257

	
1258 1258
  public:
1259 1259

	
1260 1260
    /// \brief Returns true when the given class is alive.
1261 1261
    ///
1262 1262
    /// Returns true when the given class is alive, ie. the class is
1263 1263
    /// not nested into other class.
1264 1264
    bool alive(int cls) const {
1265 1265
      return classes[cls].parent < 0;
1266 1266
    }
1267 1267

	
1268 1268
    /// \brief Returns true when the given class is trivial.
1269 1269
    ///
1270 1270
    /// Returns true when the given class is trivial, ie. the class
1271 1271
    /// contains just one item directly.
1272 1272
    bool trivial(int cls) const {
1273 1273
      return classes[cls].left == -1;
1274 1274
    }
1275 1275

	
1276 1276
    /// \brief Constructs the union-find.
1277 1277
    ///
1278 1278
    /// Constructs the union-find.
1279 1279
    /// \brief _index The index map of the union-find. The data
1280 1280
    /// structure uses internally for store references.
1281 1281
    HeapUnionFind(ItemIntMap& _index)
1282 1282
      : index(_index), first_class(-1),
1283 1283
        first_free_class(-1), first_free_node(-1) {}
1284 1284

	
1285 1285
    /// \brief Insert a new node into a new component.
1286 1286
    ///
1287 1287
    /// Insert a new node into a new component.
1288 1288
    /// \param item The item of the new node.
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
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dfs.h>
24 24
#include <lemon/path.h>
25 25

	
26 26
#include "graph_test.h"
27 27
#include "test_tools.h"
28 28

	
29 29
using namespace lemon;
30 30

	
31 31
char test_lgf[] =
32 32
  "@nodes\n"
33 33
  "label\n"
34 34
  "0\n"
35 35
  "1\n"
36 36
  "2\n"
37 37
  "3\n"
38 38
  "4\n"
39 39
  "5\n"
40 40
  "6\n"
41 41
  "@arcs\n"
42 42
  "     label\n"
43 43
  "0 1  0\n"
44 44
  "1 2  1\n"
45 45
  "2 3  2\n"
46 46
  "1 4  3\n"
47 47
  "4 2  4\n"
48 48
  "4 5  5\n"
49 49
  "5 0  6\n"
50 50
  "6 3  7\n"
51 51
  "@attributes\n"
52 52
  "source 0\n"
53 53
  "target 5\n"
54 54
  "source1 6\n"
55 55
  "target1 3\n";
56 56

	
57 57

	
58 58
void checkDfsCompile()
59 59
{
60 60
  typedef concepts::Digraph Digraph;
61 61
  typedef Dfs<Digraph> DType;
62 62
  typedef Digraph::Node Node;
63 63
  typedef Digraph::Arc Arc;
64 64

	
65 65
  Digraph G;
66 66
  Node s, t;
67 67
  Arc e;
68 68
  int l;
69 69
  bool b;
70 70
  DType::DistMap d(G);
71 71
  DType::PredMap p(G);
72 72
  Path<Digraph> pp;
73 73

	
74 74
  {
75 75
    DType dfs_test(G);
76 76

	
77 77
    dfs_test.run(s);
78 78
    dfs_test.run(s,t);
79 79
    dfs_test.run();
80 80

	
81 81
    l  = dfs_test.dist(t);
82 82
    e  = dfs_test.predArc(t);
83 83
    s  = dfs_test.predNode(t);
84 84
    b  = dfs_test.reached(t);
85 85
    d  = dfs_test.distMap();
86 86
    p  = dfs_test.predMap();
87 87
    pp = dfs_test.path(t);
88 88
  }
89 89
  {
90 90
    DType
91 91
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
92 92
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
93 93
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
94 94
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
95 95
      ::SetStandardProcessedMap
96 96
      ::Create dfs_test(G);
97 97

	
98 98
    dfs_test.run(s);
99 99
    dfs_test.run(s,t);
100 100
    dfs_test.run();
101 101

	
102 102
    l  = dfs_test.dist(t);
103 103
    e  = dfs_test.predArc(t);
104 104
    s  = dfs_test.predNode(t);
105 105
    b  = dfs_test.reached(t);
106 106
    pp = dfs_test.path(t);
107 107
  }
108 108
}
109 109

	
110 110
void checkDfsFunctionCompile()
111 111
{
112 112
  typedef int VType;
113 113
  typedef concepts::Digraph Digraph;
114 114
  typedef Digraph::Arc Arc;
115 115
  typedef Digraph::Node Node;
116 116

	
117 117
  Digraph g;
118 118
  bool b;
119 119
  dfs(g).run(Node());
120 120
  b=dfs(g).run(Node(),Node());
121 121
  dfs(g).run();
122 122
  dfs(g)
123 123
    .predMap(concepts::ReadWriteMap<Node,Arc>())
124 124
    .distMap(concepts::ReadWriteMap<Node,VType>())
125 125
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
126 126
    .processedMap(concepts::WriteMap<Node,bool>())
127 127
    .run(Node());
128 128
  b=dfs(g)
129 129
    .predMap(concepts::ReadWriteMap<Node,Arc>())
130 130
    .distMap(concepts::ReadWriteMap<Node,VType>())
131 131
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
132 132
    .processedMap(concepts::WriteMap<Node,bool>())
133 133
    .path(concepts::Path<Digraph>())
134 134
    .dist(VType())
135 135
    .run(Node(),Node());
136 136
  dfs(g)
137 137
    .predMap(concepts::ReadWriteMap<Node,Arc>())
138 138
    .distMap(concepts::ReadWriteMap<Node,VType>())
139 139
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
140 140
    .processedMap(concepts::WriteMap<Node,bool>())
141 141
    .run();
142 142
}
143 143

	
144 144
template <class Digraph>
145 145
void checkDfs() {
146 146
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
147 147

	
148 148
  Digraph G;
149 149
  Node s, t;
150 150
  Node s1, t1;
151 151

	
152 152
  std::istringstream input(test_lgf);
153 153
  digraphReader(G, input).
154 154
    node("source", s).
155 155
    node("target", t).
156 156
    node("source1", s1).
157 157
    node("target1", t1).
158 158
    run();
159 159

	
160 160
  Dfs<Digraph> dfs_test(G);
161 161
  dfs_test.run(s);
162 162

	
163 163
  Path<Digraph> p = dfs_test.path(t);
164 164
  check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
165 165
  check(checkPath(G, p),"path() found a wrong path.");
166 166
  check(pathSource(G, p) == s,"path() found a wrong path.");
167 167
  check(pathTarget(G, p) == t,"path() found a wrong path.");
168 168

	
169 169
  for(NodeIt v(G); v!=INVALID; ++v) {
170 170
    if (dfs_test.reached(v)) {
171 171
      check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
172 172
      if (dfs_test.predArc(v)!=INVALID ) {
173 173
        Arc e=dfs_test.predArc(v);
174 174
        Node u=G.source(e);
175 175
        check(u==dfs_test.predNode(v),"Wrong tree.");
176 176
        check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
177 177
              "Wrong distance. (" << dfs_test.dist(u) << "->"
178 178
              << dfs_test.dist(v) << ")");
179 179
      }
180 180
    }
181 181
  }
182 182

	
183 183
  {
184 184
  Dfs<Digraph> dfs(G);
185 185
  check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
186 186
  }
187
  
187

	
188 188
  {
189 189
    NullMap<Node,Arc> myPredMap;
190 190
    dfs(G).predMap(myPredMap).run(s);
191 191
  }
192 192
}
193 193

	
194 194
int main()
195 195
{
196 196
  checkDfs<ListDigraph>();
197 197
  checkDfs<SmartDigraph>();
198 198
  return 0;
199 199
}
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
#include <lemon/smart_graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/lgf_reader.h>
22 22
#include <lemon/error.h>
23 23

	
24 24
#include "test_tools.h"
25 25

	
26 26
using namespace std;
27 27
using namespace lemon;
28 28

	
29 29
void digraph_copy_test() {
30 30
  const int nn = 10;
31 31

	
32 32
  // Build a digraph
33 33
  SmartDigraph from;
34 34
  SmartDigraph::NodeMap<int> fnm(from);
35 35
  SmartDigraph::ArcMap<int> fam(from);
36 36
  SmartDigraph::Node fn = INVALID;
37 37
  SmartDigraph::Arc fa = INVALID;
38 38

	
39 39
  std::vector<SmartDigraph::Node> fnv;
40 40
  for (int i = 0; i < nn; ++i) {
41 41
    SmartDigraph::Node node = from.addNode();
42 42
    fnv.push_back(node);
43 43
    fnm[node] = i * i;
44 44
    if (i == 0) fn = node;
45 45
  }
46 46

	
47 47
  for (int i = 0; i < nn; ++i) {
48 48
    for (int j = 0; j < nn; ++j) {
49 49
      SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]);
50 50
      fam[arc] = i + j * j;
51 51
      if (i == 0 && j == 0) fa = arc;
52 52
    }
53 53
  }
54 54

	
55 55
  // Test digraph copy
56 56
  ListDigraph to;
57 57
  ListDigraph::NodeMap<int> tnm(to);
58 58
  ListDigraph::ArcMap<int> tam(to);
59 59
  ListDigraph::Node tn;
60 60
  ListDigraph::Arc ta;
61 61

	
62 62
  SmartDigraph::NodeMap<ListDigraph::Node> nr(from);
63 63
  SmartDigraph::ArcMap<ListDigraph::Arc> er(from);
64 64

	
65 65
  ListDigraph::NodeMap<SmartDigraph::Node> ncr(to);
66 66
  ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to);
67 67

	
68 68
  digraphCopy(from, to).
69 69
    nodeMap(fnm, tnm).arcMap(fam, tam).
70 70
    nodeRef(nr).arcRef(er).
71 71
    nodeCrossRef(ncr).arcCrossRef(ecr).
72 72
    node(fn, tn).arc(fa, ta).run();
73
  
73

	
74 74
  check(countNodes(from) == countNodes(to), "Wrong copy.");
75 75
  check(countArcs(from) == countArcs(to), "Wrong copy.");
76 76

	
77 77
  for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
78 78
    check(ncr[nr[it]] == it, "Wrong copy.");
79 79
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
80 80
  }
81 81

	
82 82
  for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) {
83 83
    check(ecr[er[it]] == it, "Wrong copy.");
84 84
    check(fam[it] == tam[er[it]], "Wrong copy.");
85 85
    check(nr[from.source(it)] == to.source(er[it]), "Wrong copy.");
86 86
    check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
87 87
  }
88 88

	
89 89
  for (ListDigraph::NodeIt it(to); it != INVALID; ++it) {
90 90
    check(nr[ncr[it]] == it, "Wrong copy.");
91 91
  }
92 92

	
93 93
  for (ListDigraph::ArcIt it(to); it != INVALID; ++it) {
94 94
    check(er[ecr[it]] == it, "Wrong copy.");
95 95
  }
96 96
  check(tn == nr[fn], "Wrong copy.");
97 97
  check(ta == er[fa], "Wrong copy.");
98 98

	
99 99
  // Test repeated copy
100 100
  digraphCopy(from, to).run();
101
  
101

	
102 102
  check(countNodes(from) == countNodes(to), "Wrong copy.");
103 103
  check(countArcs(from) == countArcs(to), "Wrong copy.");
104 104
}
105 105

	
106 106
void graph_copy_test() {
107 107
  const int nn = 10;
108 108

	
109 109
  // Build a graph
110 110
  SmartGraph from;
111 111
  SmartGraph::NodeMap<int> fnm(from);
112 112
  SmartGraph::ArcMap<int> fam(from);
113 113
  SmartGraph::EdgeMap<int> fem(from);
114 114
  SmartGraph::Node fn = INVALID;
115 115
  SmartGraph::Arc fa = INVALID;
116 116
  SmartGraph::Edge fe = INVALID;
117 117

	
118 118
  std::vector<SmartGraph::Node> fnv;
119 119
  for (int i = 0; i < nn; ++i) {
120 120
    SmartGraph::Node node = from.addNode();
121 121
    fnv.push_back(node);
122 122
    fnm[node] = i * i;
123 123
    if (i == 0) fn = node;
124 124
  }
125 125

	
126 126
  for (int i = 0; i < nn; ++i) {
127 127
    for (int j = 0; j < nn; ++j) {
128 128
      SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]);
129 129
      fem[edge] = i * i + j * j;
130 130
      fam[from.direct(edge, true)] = i + j * j;
131 131
      fam[from.direct(edge, false)] = i * i + j;
132 132
      if (i == 0 && j == 0) fa = from.direct(edge, true);
133 133
      if (i == 0 && j == 0) fe = edge;
134 134
    }
135 135
  }
136 136

	
137 137
  // Test graph copy
138 138
  ListGraph to;
139 139
  ListGraph::NodeMap<int> tnm(to);
140 140
  ListGraph::ArcMap<int> tam(to);
141 141
  ListGraph::EdgeMap<int> tem(to);
142 142
  ListGraph::Node tn;
143 143
  ListGraph::Arc ta;
144 144
  ListGraph::Edge te;
145 145

	
146 146
  SmartGraph::NodeMap<ListGraph::Node> nr(from);
147 147
  SmartGraph::ArcMap<ListGraph::Arc> ar(from);
148 148
  SmartGraph::EdgeMap<ListGraph::Edge> er(from);
149 149

	
150 150
  ListGraph::NodeMap<SmartGraph::Node> ncr(to);
151 151
  ListGraph::ArcMap<SmartGraph::Arc> acr(to);
152 152
  ListGraph::EdgeMap<SmartGraph::Edge> ecr(to);
153 153

	
154 154
  graphCopy(from, to).
155 155
    nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
156 156
    nodeRef(nr).arcRef(ar).edgeRef(er).
157 157
    nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
158 158
    node(fn, tn).arc(fa, ta).edge(fe, te).run();
159 159

	
160 160
  check(countNodes(from) == countNodes(to), "Wrong copy.");
161 161
  check(countEdges(from) == countEdges(to), "Wrong copy.");
162 162
  check(countArcs(from) == countArcs(to), "Wrong copy.");
163 163

	
164 164
  for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
165 165
    check(ncr[nr[it]] == it, "Wrong copy.");
166 166
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
167 167
  }
168 168

	
169 169
  for (SmartGraph::ArcIt it(from); it != INVALID; ++it) {
170 170
    check(acr[ar[it]] == it, "Wrong copy.");
171 171
    check(fam[it] == tam[ar[it]], "Wrong copy.");
172 172
    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
173 173
    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
174 174
  }
175 175

	
176 176
  for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) {
177 177
    check(ecr[er[it]] == it, "Wrong copy.");
178 178
    check(fem[it] == tem[er[it]], "Wrong copy.");
179 179
    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
180 180
          "Wrong copy.");
181 181
    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
182 182
          "Wrong copy.");
183 183
    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
184 184
          "Wrong copy.");
185 185
  }
186 186

	
187 187
  for (ListGraph::NodeIt it(to); it != INVALID; ++it) {
188 188
    check(nr[ncr[it]] == it, "Wrong copy.");
189 189
  }
190 190

	
191 191
  for (ListGraph::ArcIt it(to); it != INVALID; ++it) {
192 192
    check(ar[acr[it]] == it, "Wrong copy.");
193 193
  }
194 194
  for (ListGraph::EdgeIt it(to); it != INVALID; ++it) {
195 195
    check(er[ecr[it]] == it, "Wrong copy.");
196 196
  }
197 197
  check(tn == nr[fn], "Wrong copy.");
198 198
  check(ta == ar[fa], "Wrong copy.");
199 199
  check(te == er[fe], "Wrong copy.");
200 200

	
201 201
  // Test repeated copy
202 202
  graphCopy(from, to).run();
203
  
203

	
204 204
  check(countNodes(from) == countNodes(to), "Wrong copy.");
205 205
  check(countEdges(from) == countEdges(to), "Wrong copy.");
206 206
  check(countArcs(from) == countArcs(to), "Wrong copy.");
207 207
}
208 208

	
209 209

	
210 210
int main() {
211 211
  digraph_copy_test();
212 212
  graph_copy_test();
213 213

	
214 214
  return 0;
215 215
}
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
#include <lemon/list_graph.h>
20 20
#include <lemon/lgf_reader.h>
21 21
#include "test_tools.h"
22 22

	
23 23
using namespace lemon;
24 24

	
25 25
char test_lgf[] =
26 26
  "@nodes\n"
27 27
  "label\n"
28 28
  "0\n"
29 29
  "1\n"
30 30
  "@arcs\n"
31 31
  "     label\n"
32 32
  "0 1  0\n"
33 33
  "1 0  1\n"
34 34
  "@attributes\n"
35 35
  "source 0\n"
36 36
  "target 1\n";
37 37

	
38 38
char test_lgf_nomap[] =
39 39
  "@nodes\n"
40 40
  "label\n"
41 41
  "0\n"
42 42
  "1\n"
43 43
  "@arcs\n"
44 44
  "     -\n"
45 45
  "0 1\n";
46 46

	
47 47
char test_lgf_bad1[] =
48 48
  "@nodes\n"
49 49
  "label\n"
50 50
  "0\n"
51 51
  "1\n"
52 52
  "@arcs\n"
53 53
  "     - another\n"
54 54
  "0 1\n";
55 55

	
56 56
char test_lgf_bad2[] =
57 57
  "@nodes\n"
58 58
  "label\n"
59 59
  "0\n"
60 60
  "1\n"
61 61
  "@arcs\n"
62 62
  "     label -\n"
63 63
  "0 1\n";
64 64

	
65 65

	
66
int main() 
66
int main()
67 67
{
68 68
  {
69
    ListDigraph d; 
69
    ListDigraph d;
70 70
    ListDigraph::Node s,t;
71 71
    ListDigraph::ArcMap<int> label(d);
72 72
    std::istringstream input(test_lgf);
73 73
    digraphReader(d, input).
74 74
      node("source", s).
75 75
      node("target", t).
76 76
      arcMap("label", label).
77 77
      run();
78 78
    check(countNodes(d) == 2,"There should be 2 nodes");
79 79
    check(countArcs(d) == 2,"There should be 2 arcs");
80 80
  }
81 81
  {
82 82
    ListGraph g;
83 83
    ListGraph::Node s,t;
84 84
    ListGraph::EdgeMap<int> label(g);
85 85
    std::istringstream input(test_lgf);
86 86
    graphReader(g, input).
87 87
      node("source", s).
88 88
      node("target", t).
89 89
      edgeMap("label", label).
90 90
      run();
91 91
    check(countNodes(g) == 2,"There should be 2 nodes");
92 92
    check(countEdges(g) == 2,"There should be 2 arcs");
93 93
  }
94 94

	
95 95
  {
96
    ListDigraph d; 
96
    ListDigraph d;
97 97
    std::istringstream input(test_lgf_nomap);
98 98
    digraphReader(d, input).
99 99
      run();
100 100
    check(countNodes(d) == 2,"There should be 2 nodes");
101 101
    check(countArcs(d) == 1,"There should be 1 arc");
102 102
  }
103 103
  {
104 104
    ListGraph g;
105 105
    std::istringstream input(test_lgf_nomap);
106 106
    graphReader(g, input).
107 107
      run();
108 108
    check(countNodes(g) == 2,"There should be 2 nodes");
109 109
    check(countEdges(g) == 1,"There should be 1 edge");
110 110
  }
111 111

	
112 112
  {
113
    ListDigraph d; 
113
    ListDigraph d;
114 114
    std::istringstream input(test_lgf_bad1);
115 115
    bool ok=false;
116 116
    try {
117 117
      digraphReader(d, input).
118 118
        run();
119 119
    }
120
    catch (FormatError& error) 
120
    catch (FormatError& error)
121 121
      {
122 122
        ok = true;
123 123
      }
124 124
    check(ok,"FormatError exception should have occured");
125 125
  }
126 126
  {
127 127
    ListGraph g;
128 128
    std::istringstream input(test_lgf_bad1);
129 129
    bool ok=false;
130 130
    try {
131 131
      graphReader(g, input).
132 132
        run();
133 133
    }
134 134
    catch (FormatError& error)
135 135
      {
136 136
        ok = true;
137 137
      }
138 138
    check(ok,"FormatError exception should have occured");
139 139
  }
140 140

	
141 141
  {
142
    ListDigraph d; 
142
    ListDigraph d;
143 143
    std::istringstream input(test_lgf_bad2);
144 144
    bool ok=false;
145 145
    try {
146 146
      digraphReader(d, input).
147 147
        run();
148 148
    }
149 149
    catch (FormatError& error)
150 150
      {
151 151
        ok = true;
152 152
      }
153 153
    check(ok,"FormatError exception should have occured");
154 154
  }
155 155
  {
156 156
    ListGraph g;
157 157
    std::istringstream input(test_lgf_bad2);
158 158
    bool ok=false;
159 159
    try {
160 160
      graphReader(g, input).
161 161
        run();
162 162
    }
163 163
    catch (FormatError& error)
164 164
      {
165 165
        ok = true;
166 166
      }
167 167
    check(ok,"FormatError exception should have occured");
168 168
  }
169 169
}
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
#include <deque>
20 20
#include <set>
21 21

	
22 22
#include <lemon/concept_check.h>
23 23
#include <lemon/concepts/maps.h>
24 24
#include <lemon/maps.h>
25 25

	
26 26
#include "test_tools.h"
27 27

	
28 28
using namespace lemon;
29 29
using namespace lemon::concepts;
30 30

	
31 31
struct A {};
32 32
inline bool operator<(A, A) { return true; }
33 33
struct B {};
34 34

	
35 35
class C {
36 36
  int x;
37 37
public:
38 38
  C(int _x) : x(_x) {}
39 39
};
40 40

	
41 41
class F {
42 42
public:
43 43
  typedef A argument_type;
44 44
  typedef B result_type;
45 45

	
46 46
  B operator()(const A&) const { return B(); }
47 47
private:
48 48
  F& operator=(const F&);
49 49
};
50 50

	
51 51
int func(A) { return 3; }
52 52

	
53 53
int binc(int a, B) { return a+1; }
54 54

	
55 55
typedef ReadMap<A, double> DoubleMap;
56 56
typedef ReadWriteMap<A, double> DoubleWriteMap;
57 57
typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
58 58

	
59 59
typedef ReadMap<A, bool> BoolMap;
60 60
typedef ReadWriteMap<A, bool> BoolWriteMap;
61 61
typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
62 62

	
63 63
int main()
64 64
{
65 65
  // Map concepts
66 66
  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
67 67
  checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
68 68
  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
69 69
  checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
70 70
  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
71 71
  checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
72
  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
73
  checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
72
  checkConcept<ReferenceMap<A,B,B&,const B&>,
73
               ReferenceMap<A,B,B&,const B&> >();
74
  checkConcept<ReferenceMap<A,C,C&,const C&>,
75
               ReferenceMap<A,C,C&,const C&> >();
74 76

	
75 77
  // NullMap
76 78
  {
77 79
    checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
78 80
    NullMap<A,B> map1;
79 81
    NullMap<A,B> map2 = map1;
80 82
    map1 = nullMap<A,B>();
81 83
  }
82 84

	
83 85
  // ConstMap
84 86
  {
85 87
    checkConcept<ReadWriteMap<A,B>, ConstMap<A,B> >();
86 88
    checkConcept<ReadWriteMap<A,C>, ConstMap<A,C> >();
87 89
    ConstMap<A,B> map1;
88 90
    ConstMap<A,B> map2 = B();
89 91
    ConstMap<A,B> map3 = map1;
90 92
    map1 = constMap<A>(B());
91 93
    map1 = constMap<A,B>();
92 94
    map1.setAll(B());
93 95
    ConstMap<A,C> map4(C(1));
94 96
    ConstMap<A,C> map5 = map4;
95 97
    map4 = constMap<A>(C(2));
96 98
    map4.setAll(C(3));
97 99

	
98 100
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,int> >();
99 101
    check(constMap<A>(10)[A()] == 10, "Something is wrong with ConstMap");
100 102

	
101 103
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,Const<int,10> > >();
102 104
    ConstMap<A,Const<int,10> > map6;
103 105
    ConstMap<A,Const<int,10> > map7 = map6;
104 106
    map6 = constMap<A,int,10>();
105 107
    map7 = constMap<A,Const<int,10> >();
106 108
    check(map6[A()] == 10 && map7[A()] == 10,
107 109
          "Something is wrong with ConstMap");
108 110
  }
109 111

	
110 112
  // IdentityMap
111 113
  {
112 114
    checkConcept<ReadMap<A,A>, IdentityMap<A> >();
113 115
    IdentityMap<A> map1;
114 116
    IdentityMap<A> map2 = map1;
115 117
    map1 = identityMap<A>();
116 118

	
117 119
    checkConcept<ReadMap<double,double>, IdentityMap<double> >();
118 120
    check(identityMap<double>()[1.0] == 1.0 &&
119 121
          identityMap<double>()[3.14] == 3.14,
120 122
          "Something is wrong with IdentityMap");
121 123
  }
122 124

	
123 125
  // RangeMap
124 126
  {
125 127
    checkConcept<ReferenceMap<int,B,B&,const B&>, RangeMap<B> >();
126 128
    RangeMap<B> map1;
127 129
    RangeMap<B> map2(10);
128 130
    RangeMap<B> map3(10,B());
129 131
    RangeMap<B> map4 = map1;
130 132
    RangeMap<B> map5 = rangeMap<B>();
131 133
    RangeMap<B> map6 = rangeMap<B>(10);
132 134
    RangeMap<B> map7 = rangeMap(10,B());
133 135

	
134 136
    checkConcept< ReferenceMap<int, double, double&, const double&>,
135 137
                  RangeMap<double> >();
136 138
    std::vector<double> v(10, 0);
137 139
    v[5] = 100;
138 140
    RangeMap<double> map8(v);
139 141
    RangeMap<double> map9 = rangeMap(v);
140 142
    check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100,
141 143
          "Something is wrong with RangeMap");
142 144
  }
143 145

	
144 146
  // SparseMap
145 147
  {
146 148
    checkConcept<ReferenceMap<A,B,B&,const B&>, SparseMap<A,B> >();
147 149
    SparseMap<A,B> map1;
148 150
    SparseMap<A,B> map2 = B();
149 151
    SparseMap<A,B> map3 = sparseMap<A,B>();
150 152
    SparseMap<A,B> map4 = sparseMap<A>(B());
151 153

	
152 154
    checkConcept< ReferenceMap<double, int, int&, const int&>,
153 155
                  SparseMap<double, int> >();
154 156
    std::map<double, int> m;
155 157
    SparseMap<double, int> map5(m);
156 158
    SparseMap<double, int> map6(m,10);
157 159
    SparseMap<double, int> map7 = sparseMap(m);
158 160
    SparseMap<double, int> map8 = sparseMap(m,10);
159 161

	
160 162
    check(map5[1.0] == 0 && map5[3.14] == 0 &&
161 163
          map6[1.0] == 10 && map6[3.14] == 10,
162 164
          "Something is wrong with SparseMap");
163 165
    map5[1.0] = map6[3.14] = 100;
164 166
    check(map5[1.0] == 100 && map5[3.14] == 0 &&
165 167
          map6[1.0] == 10 && map6[3.14] == 100,
166 168
          "Something is wrong with SparseMap");
167 169
  }
168 170

	
169 171
  // ComposeMap
170 172
  {
171 173
    typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
172 174
    checkConcept<ReadMap<B,double>, CompMap>();
173 175
    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
174 176
    CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
175 177

	
176 178
    SparseMap<double, bool> m1(false); m1[3.14] = true;
177 179
    RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
178 180
    check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1],
179 181
          "Something is wrong with ComposeMap")
180 182
  }
181 183

	
182 184
  // CombineMap
183 185
  {
184 186
    typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
185 187
    checkConcept<ReadMap<A,double>, CombMap>();
186 188
    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
187 189
    CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
188 190

	
189 191
    check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
190 192
          "Something is wrong with CombineMap");
191 193
  }
192 194

	
193 195
  // FunctorToMap, MapToFunctor
194 196
  {
195 197
    checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
196 198
    checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
197 199
    FunctorToMap<F> map1;
198 200
    FunctorToMap<F> map2 = FunctorToMap<F>(F());
199 201
    B b = functorToMap(F())[A()];
200 202

	
201 203
    checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
202
    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
204
    MapToFunctor<ReadMap<A,B> > map =
205
      MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
203 206

	
204 207
    check(functorToMap(&func)[A()] == 3,
205 208
          "Something is wrong with FunctorToMap");
206 209
    check(mapToFunctor(constMap<A,int>(2))(A()) == 2,
207 210
          "Something is wrong with MapToFunctor");
208 211
    check(mapToFunctor(functorToMap(&func))(A()) == 3 &&
209 212
          mapToFunctor(functorToMap(&func))[A()] == 3,
210 213
          "Something is wrong with FunctorToMap or MapToFunctor");
211 214
    check(functorToMap(mapToFunctor(constMap<A,int>(2)))[A()] == 2,
212 215
          "Something is wrong with FunctorToMap or MapToFunctor");
213 216
  }
214 217

	
215 218
  // ConvertMap
216 219
  {
217 220
    checkConcept<ReadMap<double,double>,
218 221
      ConvertMap<ReadMap<double, int>, double> >();
219 222
    ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
220 223
    ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
221 224
  }
222 225

	
223 226
  // ForkMap
224 227
  {
225 228
    checkConcept<DoubleWriteMap, ForkMap<DoubleWriteMap, DoubleWriteMap> >();
226 229

	
227 230
    typedef RangeMap<double> RM;
228 231
    typedef SparseMap<int, double> SM;
229 232
    RM m1(10, -1);
230 233
    SM m2(-1);
231 234
    checkConcept<ReadWriteMap<int, double>, ForkMap<RM, SM> >();
232 235
    checkConcept<ReadWriteMap<int, double>, ForkMap<SM, RM> >();
233 236
    ForkMap<RM, SM> map1(m1,m2);
234 237
    ForkMap<SM, RM> map2 = forkMap(m2,m1);
235 238
    map2.set(5, 10);
236 239
    check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 &&
237 240
          m2[5] == 10 && map2[1] == -1 && map2[5] == 10,
238 241
          "Something is wrong with ForkMap");
239 242
  }
240 243

	
241 244
  // Arithmetic maps:
242 245
  // - AddMap, SubMap, MulMap, DivMap
243 246
  // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap
244 247
  // - NegMap, NegWriteMap, AbsMap
245 248
  {
246 249
    checkConcept<DoubleMap, AddMap<DoubleMap,DoubleMap> >();
247 250
    checkConcept<DoubleMap, SubMap<DoubleMap,DoubleMap> >();
248 251
    checkConcept<DoubleMap, MulMap<DoubleMap,DoubleMap> >();
249 252
    checkConcept<DoubleMap, DivMap<DoubleMap,DoubleMap> >();
250 253

	
251 254
    ConstMap<int, double> c1(1.0), c2(3.14);
252 255
    IdentityMap<int> im;
253 256
    ConvertMap<IdentityMap<int>, double> id(im);
254 257
    check(addMap(c1,id)[0] == 1.0  && addMap(c1,id)[10] == 11.0,
255 258
          "Something is wrong with AddMap");
256 259
    check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0,
257 260
          "Something is wrong with SubMap");
258 261
    check(mulMap(id,c2)[0] == 0    && mulMap(id,c2)[2]  == 6.28,
259 262
          "Something is wrong with MulMap");
260 263
    check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2]  == 1.57,
261 264
          "Something is wrong with DivMap");
262 265

	
263 266
    checkConcept<DoubleMap, ShiftMap<DoubleMap> >();
264 267
    checkConcept<DoubleWriteMap, ShiftWriteMap<DoubleWriteMap> >();
265 268
    checkConcept<DoubleMap, ScaleMap<DoubleMap> >();
266 269
    checkConcept<DoubleWriteMap, ScaleWriteMap<DoubleWriteMap> >();
267 270
    checkConcept<DoubleMap, NegMap<DoubleMap> >();
268 271
    checkConcept<DoubleWriteMap, NegWriteMap<DoubleWriteMap> >();
269 272
    checkConcept<DoubleMap, AbsMap<DoubleMap> >();
270 273

	
271 274
    check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0,
272 275
          "Something is wrong with ShiftMap");
273 276
    check(shiftWriteMap(id, 2.0)[1] == 3.0 &&
274 277
          shiftWriteMap(id, 2.0)[10] == 12.0,
275 278
          "Something is wrong with ShiftWriteMap");
276 279
    check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0,
277 280
          "Something is wrong with ScaleMap");
278 281
    check(scaleWriteMap(id, 2.0)[1] == 2.0 &&
279 282
          scaleWriteMap(id, 2.0)[10] == 20.0,
280 283
          "Something is wrong with ScaleWriteMap");
281 284
    check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0,
282 285
          "Something is wrong with NegMap");
283 286
    check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0,
284 287
          "Something is wrong with NegWriteMap");
285 288
    check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0,
286 289
          "Something is wrong with AbsMap");
287 290
  }
288 291

	
289 292
  // Logical maps:
290 293
  // - TrueMap, FalseMap
291 294
  // - AndMap, OrMap
292 295
  // - NotMap, NotWriteMap
293 296
  // - EqualMap, LessMap
294 297
  {
295 298
    checkConcept<BoolMap, TrueMap<A> >();
296 299
    checkConcept<BoolMap, FalseMap<A> >();
297 300
    checkConcept<BoolMap, AndMap<BoolMap,BoolMap> >();
298 301
    checkConcept<BoolMap, OrMap<BoolMap,BoolMap> >();
0 comments (0 inline)