↑ Collapse diff ↑
Ignore white space 1536 line context
1 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2 2

	
3 3
#EXECUTE_PROCESS(
4 4
#  COMMAND hg id -i
5 5
#  OUTPUT_VARIABLE HG_REVISION
6 6
#  OUTPUT_STRIP_TRAILING_WHITESPACE)
7 7

	
8
SET(PROJECT_NAME "Lemon")
8
SET(PROJECT_NAME "LEMON")
9 9
SET(PROJECT_VERSION_MAJOR "0")
10 10
SET(PROJECT_VERSION_MINOR "99")
11 11
SET(PROJECT_VERSION_PATCH "0")
12 12
SET(PROJECT_VERSION
13 13
  "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
14 14

	
15 15
PROJECT(${PROJECT_NAME})
16 16

	
17 17
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
18 18

	
19 19
INCLUDE(FindDoxygen)
20 20
INCLUDE(FindGhostscript)
21 21

	
22 22
ENABLE_TESTING()
23 23

	
24 24
ADD_SUBDIRECTORY(lemon)
25 25
ADD_SUBDIRECTORY(demo)
26 26
ADD_SUBDIRECTORY(doc)
27 27
ADD_SUBDIRECTORY(test)
28 28

	
29 29
IF(WIN32)
30 30
  INSTALL(FILES ${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico
31 31
    DESTINATION bin)
32 32
ENDIF(WIN32)
33 33

	
34 34
IF(WIN32)
35 35
  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
36 36
  SET(CPACK_PACKAGE_VENDOR
37 37
    "EGRES - Egervary Research Group on Combinatorial Optimization")
38 38
  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
39
    "Lemon - Library of Efficient Models and Optimization in Networks")
39
    "LEMON - Library of Efficient Models and Optimization in Networks")
40 40
  SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
41 41

	
42 42
  SET(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
43 43
  SET(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
44 44
  SET(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
45 45
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
46 46

	
47 47
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
48 48
    "${PROJECT_NAME} ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
49 49
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
50 50
    "${PROJECT_NAME} ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
51 51

	
52 52
  # Variables to generate a component-based installer.
53 53
  #SET(CPACK_COMPONENTS_ALL headers library html_documentation)
54 54

	
55 55
  #SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
56 56
  #SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Static library")
57 57
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
58 58

	
59 59
  #SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
60
  #  "C++ header files for use with the Lemon library")
60
  #  "C++ header files for use with the LEMON library")
61 61
  #SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
62
  #  "Static library used to build programs with Lemon")
62
  #  "Static library used to build programs with LEMON")
63 63
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
64 64
  #  "Doxygen generated documentation")
65 65

	
66 66
  #SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
67 67

	
68 68
  #SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
69 69
  #SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
70 70
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
71 71

	
72 72
  #SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
73
  #  "Components needed to develop software using Lemon")
73
  #  "Components needed to develop software using LEMON")
74 74
  #SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
75
  #  "Documentation of Lemon")
75
  #  "Documentation of LEMON")
76 76

	
77 77
  #SET(CPACK_ALL_INSTALL_TYPES Full Developer)
78 78

	
79 79
  #SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
80 80
  #SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
81 81
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
82 82

	
83 83
  SET(CPACK_GENERATOR "NSIS")
84 84
  SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico")
85 85
  SET(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/cmake/nsis/uninstall.ico")
86 86
  #SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
87 87
  SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
88 88
  SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
89 89
  SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
90 90
  SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
91 91
  SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
92 92
  SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
93 93
    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\doc\\\\index.html\\\"
94 94
    ")
95 95
  SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
96 96
    !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
97 97
    Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
98 98
    ")
99 99

	
100 100
  INCLUDE(CPack)
101 101
ENDIF(WIN32)
Ignore white space 1536 line context
1 1
dnl Process this file with autoconf to produce a configure script.
2 2

	
3 3
dnl Version information.
4 4
m4_define([lemon_version_number], [])
5 5
m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
6 6
m4_define([lemon_version], [ifelse(lemon_version_number(), [], [lemon_hg_revision()], [lemon_version_number()])])
7 7

	
8 8
AC_PREREQ([2.59])
9
AC_INIT([Lemon], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
9
AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
10 10
AC_CONFIG_AUX_DIR([build-aux])
11 11
AC_CONFIG_MACRO_DIR([m4])
12 12
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
13 13
AC_CONFIG_SRCDIR([lemon/list_graph.h])
14 14
AC_CONFIG_HEADERS([config.h lemon/config.h])
15 15

	
16 16
lx_cmdline_cxxflags_set=${CXXFLAGS+set}
17 17

	
18 18
dnl Checks for programs.
19 19
AC_PROG_CXX
20 20
AC_PROG_CXXCPP
21 21
AC_PROG_INSTALL
22 22
AC_DISABLE_SHARED
23 23
AC_PROG_LIBTOOL
24 24

	
25 25
AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
26 26
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
27 27

	
28 28
dnl Set custom compiler flags when using g++.
29 29
if test x"$lx_cmdline_cxxflags_set" != x"set" -a "$GXX" = yes; then
30 30
  CXXFLAGS="$CXXFLAGS -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
31 31
fi
32 32

	
33 33
dnl Checks for libraries.
34 34
LX_CHECK_GLPK
35 35
LX_CHECK_CPLEX
36 36
LX_CHECK_SOPLEX
37 37

	
38 38
dnl Disable/enable building the demo programs.
39 39
AC_ARG_ENABLE([demo],
40 40
AS_HELP_STRING([--enable-demo], [build the demo programs])
41 41
AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
42 42
              [], [enable_demo=no])
43 43
AC_MSG_CHECKING([whether to build the demo programs])
44 44
if test x"$enable_demo" != x"no"; then
45 45
  AC_MSG_RESULT([yes])
46 46
else
47 47
  AC_MSG_RESULT([no])
48 48
fi
49 49
AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
50 50

	
51 51
dnl Disable/enable building the binary tools.
52 52
AC_ARG_ENABLE([tools],
53 53
AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
54 54
AS_HELP_STRING([--disable-tools], [do not build additional tools]),
55 55
              [], [enable_tools=yes])
56 56
AC_MSG_CHECKING([whether to build the additional tools])
57 57
if test x"$enable_tools" != x"no"; then
58 58
  AC_MSG_RESULT([yes])
59 59
else
60 60
  AC_MSG_RESULT([no])
61 61
fi
62 62
AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
63 63

	
64 64
dnl Disable/enable building the benchmarks.
65 65
AC_ARG_ENABLE([benchmark],
66 66
AS_HELP_STRING([--enable-benchmark], [build the benchmarks])
67 67
AS_HELP_STRING([--disable-benchmark], [do not build the benchmarks @<:@default@:>@]),
68 68
              [], [enable_benchmark=no])
69 69
AC_MSG_CHECKING([whether to build the benchmarks])
70 70
if test x"$enable_benchmark" != x"no"; then
71 71
  AC_MSG_RESULT([yes])
72 72
else
73 73
  AC_MSG_RESULT([no])
74 74
fi
75 75
AM_CONDITIONAL([WANT_BENCHMARK], [test x"$enable_benchmark" != x"no"])
76 76

	
77 77
dnl Checks for header files.
78 78
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
79 79

	
80 80
dnl Checks for typedefs, structures, and compiler characteristics.
81 81
AC_C_CONST
82 82
AC_C_INLINE
83 83
AC_TYPE_SIZE_T
84 84
AC_HEADER_TIME
85 85
AC_STRUCT_TM
86 86

	
87 87
dnl Checks for library functions.
88 88
AC_HEADER_STDC
89 89
AC_CHECK_FUNCS(gettimeofday times ctime_r)
90 90

	
91 91
dnl Add dependencies on files generated by configure.
92 92
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
93 93
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in'])
94 94

	
95 95
AC_CONFIG_FILES([
96 96
Makefile
97 97
doc/Doxyfile
98 98
lemon/lemon.pc
99 99
])
100 100

	
101 101
AC_OUTPUT
102 102

	
103 103
echo
104 104
echo '****************************** SUMMARY ******************************'
105 105
echo
106 106
echo Package version............... : $PACKAGE-$VERSION
107 107
echo
108 108
echo C++ compiler.................. : $CXX
109 109
echo C++ compiles flags............ : $CXXFLAGS
110 110
echo
111 111
echo GLPK support.................. : $lx_glpk_found
112 112
echo CPLEX support................. : $lx_cplex_found
113 113
echo SOPLEX support................ : $lx_soplex_found
114 114
echo
115 115
echo Build benchmarks.............. : $enable_benchmark
116 116
echo Build demo programs........... : $enable_demo
117 117
echo Build additional tools........ : $enable_tools
118 118
echo
119 119
echo The packace will be installed in
120 120
echo -n '  '
121 121
echo $prefix.
122 122
echo
123 123
echo '*********************************************************************'
124 124

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

	
19 19
/**
20 20
@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
Alteration of standard containers need a very limited number of
44 44
operations, these together satisfy the everyday requirements.
45 45
In the case of graph structures, different operations are needed which do
46 46
not alter the physical graph, but gives another view. If some nodes or
47 47
arcs have to be hidden or the reverse oriented graph have to be used, then
48 48
this is the case. It also may happen that in a flow implementation
49 49
the residual graph can be accessed by another algorithm, or a node-set
50 50
is to be shrunk for another algorithm.
51 51
LEMON also provides a variety of graphs for these requirements called
52 52
\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only
53 53
in conjunction with other graph representations.
54 54

	
55 55
You are free to use the graph structure that fit your requirements
56 56
the best, most graph algorithms and auxiliary data structures can be used
57 57
with any graph structures.
58 58
*/
59 59

	
60 60
/**
61 61
@defgroup semi_adaptors Semi-Adaptor Classes for Graphs
62 62
@ingroup graphs
63 63
\brief Graph types between real graphs and graph adaptors.
64 64

	
65 65
This group describes some graph types between real graphs and graph adaptors.
66 66
These classes wrap graphs to give new functionality as the adaptors do it.
67 67
On the other hand they are not light-weight structures as the adaptors.
68 68
*/
69 69

	
70 70
/**
71 71
@defgroup maps Maps
72 72
@ingroup datas
73 73
\brief Map structures implemented in LEMON.
74 74

	
75 75
This group describes the map structures implemented in LEMON.
76 76

	
77 77
LEMON provides several special purpose maps that e.g. combine
78 78
new maps from existing ones.
79 79
*/
80 80

	
81 81
/**
82 82
@defgroup graph_maps Graph Maps
83 83
@ingroup maps
84 84
\brief Special graph-related maps.
85 85

	
86 86
This group describes maps that are specifically designed to assign
87 87
values to the nodes and arcs of graphs.
88 88
*/
89 89

	
90 90

	
91 91
/**
92 92
\defgroup map_adaptors Map Adaptors
93 93
\ingroup maps
94 94
\brief Tools to create new maps from existing ones
95 95

	
96 96
This group describes map adaptors that are used to create "implicit"
97 97
maps from other maps.
98 98

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

	
104 104
The typical usage of this classes is passing implicit maps to
105 105
algorithms.  If a function type algorithm is called then the function
106 106
type map adaptors can be used comfortable. For example let's see the
107 107
usage of map adaptors with the \c digraphToEps() function.
108 108
\code
109 109
  Color nodeColor(int deg) {
110 110
    if (deg >= 2) {
111 111
      return Color(0.5, 0.0, 0.5);
112 112
    } else if (deg == 1) {
113 113
      return Color(1.0, 0.5, 1.0);
114 114
    } else {
115 115
      return Color(0.0, 0.0, 0.0);
116 116
    }
117 117
  }
118 118

	
119 119
  Digraph::NodeMap<int> degree_map(graph);
120 120

	
121 121
  digraphToEps(graph, "graph.eps")
122 122
    .coords(coords).scaleToA4().undirected()
123 123
    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
124 124
    .run();
125 125
\endcode
126 126
The \c functorToMap() function makes an \c int to \c Color map from the
127 127
\e nodeColor() function. The \c composeMap() compose the \e degree_map
128 128
and the previously created map. The composed map is a proper function to
129 129
get the color of each node.
130 130

	
131 131
The usage with class type algorithms is little bit harder. In this
132 132
case the function type map adaptors can not be used, because the
133 133
function map adaptors give back temporary objects.
134 134
\code
135 135
  Digraph graph;
136 136

	
137 137
  typedef Digraph::ArcMap<double> DoubleArcMap;
138 138
  DoubleArcMap length(graph);
139 139
  DoubleArcMap speed(graph);
140 140

	
141 141
  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
142 142
  TimeMap time(length, speed);
143 143

	
144 144
  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
145 145
  dijkstra.run(source, target);
146 146
\endcode
147 147
We have a length map and a maximum speed map on the arcs of a digraph.
148 148
The minimum time to pass the arc can be calculated as the division of
149 149
the two maps which can be done implicitly with the \c DivMap template
150 150
class. We use the implicit minimum time map as the length map of the
151 151
\c Dijkstra algorithm.
152 152
*/
153 153

	
154 154
/**
155 155
@defgroup matrices Matrices
156 156
@ingroup datas
157 157
\brief Two dimensional data storages implemented in LEMON.
158 158

	
159 159
This group describes two dimensional data storages implemented in LEMON.
160 160
*/
161 161

	
162 162
/**
163 163
@defgroup paths Path Structures
164 164
@ingroup datas
165 165
\brief Path structures implemented in LEMON.
166 166

	
167 167
This group describes the path structures implemented in LEMON.
168 168

	
169 169
LEMON provides flexible data structures to work with paths.
170 170
All of them have similar interfaces and they can be copied easily with
171 171
assignment operators and copy constructors. This makes it easy and
172 172
efficient to have e.g. the Dijkstra algorithm to store its result in
173 173
any kind of path structure.
174 174

	
175 175
\sa lemon::concepts::Path
176 176

	
177 177
*/
178 178

	
179 179
/**
180 180
@defgroup auxdat Auxiliary Data Structures
181 181
@ingroup datas
182 182
\brief Auxiliary data structures implemented in LEMON.
183 183

	
184 184
This group describes some data structures implemented in LEMON in
185 185
order to make it easier to implement combinatorial algorithms.
186 186
*/
187 187

	
188 188

	
189 189
/**
190 190
@defgroup algs Algorithms
191 191
\brief This group describes the several algorithms
192 192
implemented in LEMON.
193 193

	
194 194
This group describes the several algorithms
195 195
implemented in LEMON.
196 196
*/
197 197

	
198 198
/**
199 199
@defgroup search Graph Search
200 200
@ingroup algs
201 201
\brief Common graph search algorithms.
202 202

	
203 203
This group describes the common graph search algorithms like
204 204
Breadth-first search (Bfs) and Depth-first search (Dfs).
205 205
*/
206 206

	
207 207
/**
208 208
@defgroup shortest_path Shortest Path algorithms
209 209
@ingroup algs
210 210
\brief Algorithms for finding shortest paths.
211 211

	
212 212
This group describes the algorithms for finding shortest paths in graphs.
213 213
*/
214 214

	
215 215
/**
216 216
@defgroup max_flow Maximum Flow algorithms
217 217
@ingroup algs
218 218
\brief Algorithms for finding maximum flows.
219 219

	
220 220
This group describes the algorithms for finding maximum flows and
221 221
feasible circulations.
222 222

	
223 223
The maximum flow problem is to find a flow between a single source and
224 224
a single target that is maximum. Formally, there is a \f$G=(V,A)\f$
225 225
directed graph, an \f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity
226 226
function and given \f$s, t \in V\f$ source and target node. The
227 227
maximum flow is the \f$f_a\f$ solution of the next optimization problem:
228 228

	
229 229
\f[ 0 \le f_a \le c_a \f]
230 230
\f[ \sum_{v\in\delta^{-}(u)}f_{vu}=\sum_{v\in\delta^{+}(u)}f_{uv}
231 231
\qquad \forall u \in V \setminus \{s,t\}\f]
232 232
\f[ \max \sum_{v\in\delta^{+}(s)}f_{uv} - \sum_{v\in\delta^{-}(s)}f_{vu}\f]
233 233

	
234 234
LEMON contains several algorithms for solving maximum flow problems:
235 235
- \ref lemon::EdmondsKarp "Edmonds-Karp"
236 236
- \ref lemon::Preflow "Goldberg's Preflow algorithm"
237 237
- \ref lemon::DinitzSleatorTarjan "Dinitz's blocking flow algorithm with dynamic trees"
238 238
- \ref lemon::GoldbergTarjan "Preflow algorithm with dynamic trees"
239 239

	
240 240
In most cases the \ref lemon::Preflow "Preflow" algorithm provides the
241 241
fastest method to compute the maximum flow. All impelementations
242 242
provides functions to query the minimum cut, which is the dual linear
243 243
programming problem of the maximum flow.
244 244

	
245 245
*/
246 246

	
247 247
/**
248 248
@defgroup min_cost_flow Minimum Cost Flow algorithms
249 249
@ingroup algs
250 250

	
251 251
\brief Algorithms for finding minimum cost flows and circulations.
252 252

	
253 253
This group describes the algorithms for finding minimum cost flows and
254 254
circulations.
255 255
*/
256 256

	
257 257
/**
258 258
@defgroup min_cut Minimum Cut algorithms
259 259
@ingroup algs
260 260

	
261 261
\brief Algorithms for finding minimum cut in graphs.
262 262

	
263 263
This group describes the algorithms for finding minimum cut in graphs.
264 264

	
265 265
The minimum cut problem is to find a non-empty and non-complete
266 266
\f$X\f$ subset of the vertices with minimum overall capacity on
267 267
outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
268 268
\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
269 269
cut is the \f$X\f$ solution of the next optimization problem:
270 270

	
271 271
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
272 272
\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
273 273

	
274 274
LEMON contains several algorithms related to minimum cut problems:
275 275

	
276 276
- \ref lemon::HaoOrlin "Hao-Orlin algorithm" to calculate minimum cut
277 277
  in directed graphs
278 278
- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" to
279 279
  calculate minimum cut in undirected graphs
280 280
- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" to calculate all
281 281
  pairs minimum cut in undirected graphs
282 282

	
283 283
If you want to find minimum cut just between two distinict nodes,
284 284
please see the \ref max_flow "Maximum Flow page".
285 285

	
286 286
*/
287 287

	
288 288
/**
289 289
@defgroup graph_prop Connectivity and other graph properties
290 290
@ingroup algs
291 291
\brief Algorithms for discovering the graph properties
292 292

	
293 293
This group describes the algorithms for discovering the graph properties
294 294
like connectivity, bipartiteness, euler property, simplicity etc.
295 295

	
296 296
\image html edge_biconnected_components.png
297 297
\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
298 298
*/
299 299

	
300 300
/**
301 301
@defgroup planar Planarity embedding and drawing
302 302
@ingroup algs
303 303
\brief Algorithms for planarity checking, embedding and drawing
304 304

	
305 305
This group describes the algorithms for planarity checking,
306 306
embedding and drawing.
307 307

	
308 308
\image html planar.png
309 309
\image latex planar.eps "Plane graph" width=\textwidth
310 310
*/
311 311

	
312 312
/**
313 313
@defgroup matching Matching algorithms
314 314
@ingroup algs
315 315
\brief Algorithms for finding matchings in graphs and bipartite graphs.
316 316

	
317 317
This group contains algorithm objects and functions to calculate
318 318
matchings in graphs and bipartite graphs. The general matching problem is
319 319
finding a subset of the arcs which does not shares common endpoints.
320 320

	
321 321
There are several different algorithms for calculate matchings in
322 322
graphs.  The matching problems in bipartite graphs are generally
323 323
easier than in general graphs. The goal of the matching optimization
324 324
can be the finding maximum cardinality, maximum weight or minimum cost
325 325
matching. The search can be constrained to find perfect or
326 326
maximum cardinality matching.
327 327

	
328
Lemon contains the next algorithms:
328
LEMON contains the next algorithms:
329 329
- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp
330 330
  augmenting path algorithm for calculate maximum cardinality matching in
331 331
  bipartite graphs
332 332
- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel
333 333
  algorithm for calculate maximum cardinality matching in bipartite graphs
334 334
- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching"
335 335
  Successive shortest path algorithm for calculate maximum weighted matching
336 336
  and maximum weighted bipartite matching in bipartite graph
337 337
- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching"
338 338
  Successive shortest path algorithm for calculate minimum cost maximum
339 339
  matching in bipartite graph
340 340
- \ref lemon::MaxMatching "MaxMatching" Edmond's blossom shrinking algorithm
341 341
  for calculate maximum cardinality matching in general graph
342 342
- \ref lemon::MaxWeightedMatching "MaxWeightedMatching" Edmond's blossom
343 343
  shrinking algorithm for calculate maximum weighted matching in general
344 344
  graph
345 345
- \ref lemon::MaxWeightedPerfectMatching "MaxWeightedPerfectMatching"
346 346
  Edmond's blossom shrinking algorithm for calculate maximum weighted
347 347
  perfect matching in general graph
348 348

	
349 349
\image html bipartite_matching.png
350 350
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
351 351

	
352 352
*/
353 353

	
354 354
/**
355 355
@defgroup spantree Minimum Spanning Tree algorithms
356 356
@ingroup algs
357 357
\brief Algorithms for finding a minimum cost spanning tree in a graph.
358 358

	
359 359
This group describes the algorithms for finding a minimum cost spanning
360 360
tree in a graph
361 361
*/
362 362

	
363 363

	
364 364
/**
365 365
@defgroup auxalg Auxiliary algorithms
366 366
@ingroup algs
367 367
\brief Auxiliary algorithms implemented in LEMON.
368 368

	
369 369
This group describes some algorithms implemented in LEMON
370 370
in order to make it easier to implement complex algorithms.
371 371
*/
372 372

	
373 373
/**
374 374
@defgroup approx Approximation algorithms
375 375
\brief Approximation algorithms.
376 376

	
377 377
This group describes the approximation and heuristic algorithms
378 378
implemented in LEMON.
379 379
*/
380 380

	
381 381
/**
382 382
@defgroup gen_opt_group General Optimization Tools
383 383
\brief This group describes some general optimization frameworks
384 384
implemented in LEMON.
385 385

	
386 386
This group describes some general optimization frameworks
387 387
implemented in LEMON.
388 388

	
389 389
*/
390 390

	
391 391
/**
392 392
@defgroup lp_group Lp and Mip solvers
393 393
@ingroup gen_opt_group
394 394
\brief Lp and Mip solver interfaces for LEMON.
395 395

	
396 396
This group describes Lp and Mip solver interfaces for LEMON. The
397 397
various LP solvers could be used in the same manner with this
398 398
interface.
399 399

	
400 400
*/
401 401

	
402 402
/**
403 403
@defgroup lp_utils Tools for Lp and Mip solvers
404 404
@ingroup lp_group
405 405
\brief Helper tools to the Lp and Mip solvers.
406 406

	
407 407
This group adds some helper tools to general optimization framework
408 408
implemented in LEMON.
409 409
*/
410 410

	
411 411
/**
412 412
@defgroup metah Metaheuristics
413 413
@ingroup gen_opt_group
414 414
\brief Metaheuristics for LEMON library.
415 415

	
416 416
This group describes some metaheuristic optimization tools.
417 417
*/
418 418

	
419 419
/**
420 420
@defgroup utils Tools and Utilities
421 421
\brief Tools and utilities for programming in LEMON
422 422

	
423 423
Tools and utilities for programming in LEMON.
424 424
*/
425 425

	
426 426
/**
427 427
@defgroup gutils Basic Graph Utilities
428 428
@ingroup utils
429 429
\brief Simple basic graph utilities.
430 430

	
431 431
This group describes some simple basic graph utilities.
432 432
*/
433 433

	
434 434
/**
435 435
@defgroup misc Miscellaneous Tools
436 436
@ingroup utils
437 437
\brief Tools for development, debugging and testing.
438 438

	
439 439
This group describes several useful tools for development,
440 440
debugging and testing.
441 441
*/
442 442

	
443 443
/**
444 444
@defgroup timecount Time measuring and Counting
445 445
@ingroup misc
446 446
\brief Simple tools for measuring the performance of algorithms.
447 447

	
448 448
This group describes simple tools for measuring the performance
449 449
of algorithms.
450 450
*/
451 451

	
452 452
/**
453 453
@defgroup graphbits Tools for Graph Implementation
454 454
@ingroup utils
455 455
\brief Tools to make it easier to create graphs.
456 456

	
457 457
This group describes the tools that makes it easier to create graphs and
458 458
the maps that dynamically update with the graph changes.
459 459
*/
460 460

	
461 461
/**
462 462
@defgroup exceptions Exceptions
463 463
@ingroup utils
464 464
\brief Exceptions defined in LEMON.
465 465

	
466 466
This group describes the exceptions defined in LEMON.
467 467
*/
468 468

	
469 469
/**
470 470
@defgroup io_group Input-Output
471 471
\brief Graph Input-Output methods
472 472

	
473 473
This group describes the tools for importing and exporting graphs
474 474
and graph related data. Now it supports the LEMON format, the
475 475
\c DIMACS format and the encapsulated postscript (EPS) format.
476 476
*/
477 477

	
478 478
/**
479
@defgroup lemon_io Lemon Input-Output
479
@defgroup lemon_io LEMON Input-Output
480 480
@ingroup io_group
481
\brief Reading and writing \ref lgf-format "Lemon Graph Format".
481
\brief Reading and writing \ref lgf-format "LEMON Graph Format".
482 482

	
483 483
This group describes methods for reading and writing
484
\ref lgf-format "Lemon Graph Format".
484
\ref lgf-format "LEMON Graph Format".
485 485
*/
486 486

	
487 487
/**
488 488
@defgroup eps_io Postscript exporting
489 489
@ingroup io_group
490 490
\brief General \c EPS drawer and graph exporter
491 491

	
492 492
This group describes general \c EPS drawing methods and special
493 493
graph exporting tools.
494 494
*/
495 495

	
496 496

	
497 497
/**
498 498
@defgroup concept Concepts
499 499
\brief Skeleton classes and concept checking classes
500 500

	
501 501
This group describes the data/algorithm skeletons and concept checking
502 502
classes implemented in LEMON.
503 503

	
504 504
The purpose of the classes in this group is fourfold.
505 505

	
506 506
- These classes contain the documentations of the concepts. In order
507 507
  to avoid document multiplications, an implementation of a concept
508 508
  simply refers to the corresponding concept class.
509 509

	
510 510
- These classes declare every functions, <tt>typedef</tt>s etc. an
511 511
  implementation of the concepts should provide, however completely
512 512
  without implementations and real data structures behind the
513 513
  interface. On the other hand they should provide nothing else. All
514 514
  the algorithms working on a data structure meeting a certain concept
515 515
  should compile with these classes. (Though it will not run properly,
516 516
  of course.) In this way it is easily to check if an algorithm
517 517
  doesn't use any extra feature of a certain implementation.
518 518

	
519 519
- The concept descriptor classes also provide a <em>checker class</em>
520 520
  that makes it possible to check whether a certain implementation of a
521 521
  concept indeed provides all the required features.
522 522

	
523 523
- Finally, They can serve as a skeleton of a new implementation of a concept.
524 524

	
525 525
*/
526 526

	
527 527

	
528 528
/**
529 529
@defgroup graph_concepts Graph Structure Concepts
530 530
@ingroup concept
531 531
\brief Skeleton and concept checking classes for graph structures
532 532

	
533 533
This group describes the skeletons and concept checking classes of LEMON's
534 534
graph structures and helper classes used to implement these.
535 535
*/
536 536

	
537 537
/* --- Unused group
538 538
@defgroup experimental Experimental Structures and Algorithms
539 539
This group describes some Experimental structures and algorithms.
540 540
The stuff here is subject to change.
541 541
*/
542 542

	
543 543
/**
544 544
\anchor demoprograms
545 545

	
546 546
@defgroup demos Demo programs
547 547

	
548 548
Some demo programs are listed here. Their full source codes can be found in
549 549
the \c demo subdirectory of the source tree.
550 550

	
551 551
It order to compile them, use <tt>--enable-demo</tt> configure option when
552 552
build the library.
553 553
*/
554 554

	
555 555
/**
556 556
@defgroup tools Standalone utility applications
557 557

	
558 558
Some utility applications are listed here.
559 559

	
560 560
The standard compilation procedure (<tt>./configure;make</tt>) will compile
561 561
them, as well.
562 562
*/
563 563

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

	
19 19
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24
\page lgf-format Lemon Graph Format (LGF)
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,
67 67
it again starts with a header line describing the names of the maps,
68 68
but the \c "label" map is not obligatory here. The following lines
69 69
describe the arcs. The first two tokens of each line are
70 70
the source 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
The \c \@edges is just a synonym of \c \@arcs. The @arcs section can
82 82
also store the edge set of an undirected graph. In such case there is
83 83
a conventional method for store arc maps in the file, if two columns
84 84
has the same caption with \c '+' and \c '-' prefix, then these columns
85 85
can be regarded as the values of an arc map.
86 86

	
87 87
The \c \@attributes section contains key-value pairs, each line
88 88
consists of two tokens, an attribute name, and then an attribute
89 89
value. The value of the attribute could be also a label value of a
90 90
node or an edge, or even an edge label prefixed with \c '+' or \c '-',
91 91
which regards to the forward or backward directed arc of the
92 92
corresponding edge.
93 93

	
94 94
\code
95 95
 @attributes
96 96
 source 1
97 97
 target 3
98 98
 caption "LEMON test digraph"
99 99
\endcode
100 100

	
101 101
The \e LGF can contain extra sections, but there is no restriction on
102 102
the format of such sections.
103 103

	
104 104
*/
105 105
}
106 106

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

	
19 19
#ifndef LEMON_BITS_ALTERATION_NOTIFIER_H
20 20
#define LEMON_BITS_ALTERATION_NOTIFIER_H
21 21

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

	
25 25
#include <lemon/core.h>
26 26

	
27 27
///\ingroup graphbits
28 28
///\file
29 29
///\brief Observer notifier for graph alteration observers.
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  /// \ingroup graphbits
34 34
  ///
35 35
  /// \brief Notifier class to notify observes about alterations in
36 36
  /// a container.
37 37
  ///
38 38
  /// The simple graph's can be refered as two containers, one node container
39 39
  /// and one edge container. But they are not standard containers they
40 40
  /// does not store values directly they are just key continars for more
41 41
  /// value containers which are the node and edge maps.
42 42
  ///
43 43
  /// The graph's node and edge sets can be changed as we add or erase
44
  /// nodes and edges in the graph. Lemon would like to handle easily
44
  /// nodes and edges in the graph. LEMON would like to handle easily
45 45
  /// that the node and edge maps should contain values for all nodes or
46 46
  /// edges. If we want to check on every indicing if the map contains
47 47
  /// the current indicing key that cause a drawback in the performance
48 48
  /// in the library. We use another solution we notify all maps about
49 49
  /// an alteration in the graph, which cause only drawback on the
50 50
  /// alteration of the graph.
51 51
  ///
52 52
  /// This class provides an interface to the container. The \e first() and \e
53 53
  /// next() member functions make possible to iterate on the keys of the
54 54
  /// container. The \e id() function returns an integer id for each key.
55 55
  /// The \e maxId() function gives back an upper bound of the ids.
56 56
  ///
57 57
  /// For the proper functonality of this class, we should notify it
58 58
  /// about each alteration in the container. The alterations have four type
59 59
  /// as \e add(), \e erase(), \e build() and \e clear(). The \e add() and
60 60
  /// \e erase() signals that only one or few items added or erased to or
61 61
  /// from the graph. If all items are erased from the graph or from an empty
62 62
  /// graph a new graph is builded then it can be signaled with the
63 63
  /// clear() and build() members. Important rule that if we erase items
64 64
  /// from graph we should first signal the alteration and after that erase
65 65
  /// them from the container, on the other way on item addition we should
66 66
  /// first extend the container and just after that signal the alteration.
67 67
  ///
68 68
  /// The alteration can be observed with a class inherited from the
69 69
  /// \e ObserverBase nested class. The signals can be handled with
70 70
  /// overriding the virtual functions defined in the base class.  The
71 71
  /// observer base can be attached to the notifier with the
72 72
  /// \e attach() member and can be detached with detach() function. The
73 73
  /// alteration handlers should not call any function which signals
74 74
  /// an other alteration in the same notifier and should not
75 75
  /// detach any observer from the notifier.
76 76
  ///
77 77
  /// Alteration observers try to be exception safe. If an \e add() or
78 78
  /// a \e clear() function throws an exception then the remaining
79 79
  /// observeres will not be notified and the fulfilled additions will
80 80
  /// be rolled back by calling the \e erase() or \e clear()
81 81
  /// functions. Thence the \e erase() and \e clear() should not throw
82 82
  /// exception. Actullay, it can be throw only
83 83
  /// \ref AlterationObserver::ImmediateDetach ImmediateDetach
84 84
  /// exception which detach the observer from the notifier.
85 85
  ///
86 86
  /// There are some place when the alteration observing is not completly
87 87
  /// reliable. If we want to carry out the node degree in the graph
88 88
  /// as in the \ref InDegMap and we use the reverseEdge that cause
89 89
  /// unreliable functionality. Because the alteration observing signals
90 90
  /// only erasing and adding but not the reversing it will stores bad
91 91
  /// degrees. The sub graph adaptors cannot signal the alterations because
92 92
  /// just a setting in the filter map can modify the graph and this cannot
93 93
  /// be watched in any way.
94 94
  ///
95 95
  /// \param _Container The container which is observed.
96 96
  /// \param _Item The item type which is obserbved.
97 97

	
98 98
  template <typename _Container, typename _Item>
99 99
  class AlterationNotifier {
100 100
  public:
101 101

	
102 102
    typedef True Notifier;
103 103

	
104 104
    typedef _Container Container;
105 105
    typedef _Item Item;
106 106

	
107 107
    /// \brief Exception which can be called from \e clear() and
108 108
    /// \e erase().
109 109
    ///
110 110
    /// From the \e clear() and \e erase() function only this
111 111
    /// exception is allowed to throw. The exception immediatly
112 112
    /// detaches the current observer from the notifier. Because the
113 113
    /// \e clear() and \e erase() should not throw other exceptions
114 114
    /// it can be used to invalidate the observer.
115 115
    struct ImmediateDetach {};
116 116

	
117 117
    /// \brief ObserverBase is the base class for the observers.
118 118
    ///
119 119
    /// ObserverBase is the abstract base class for the observers.
120 120
    /// It will be notified about an item was inserted into or
121 121
    /// erased from the graph.
122 122
    ///
123 123
    /// The observer interface contains some pure virtual functions
124 124
    /// to override. The add() and erase() functions are
125 125
    /// to notify the oberver when one item is added or
126 126
    /// erased.
127 127
    ///
128 128
    /// The build() and clear() members are to notify the observer
129 129
    /// about the container is built from an empty container or
130 130
    /// is cleared to an empty container.
131 131

	
132 132
    class ObserverBase {
133 133
    protected:
134 134
      typedef AlterationNotifier Notifier;
135 135

	
136 136
      friend class AlterationNotifier;
137 137

	
138 138
      /// \brief Default constructor.
139 139
      ///
140 140
      /// Default constructor for ObserverBase.
141 141
      ///
142 142
      ObserverBase() : _notifier(0) {}
143 143

	
144 144
      /// \brief Constructor which attach the observer into notifier.
145 145
      ///
146 146
      /// Constructor which attach the observer into notifier.
147 147
      ObserverBase(AlterationNotifier& nf) {
148 148
        attach(nf);
149 149
      }
150 150

	
151 151
      /// \brief Constructor which attach the obserever to the same notifier.
152 152
      ///
153 153
      /// Constructor which attach the obserever to the same notifier as
154 154
      /// the other observer is attached to.
155 155
      ObserverBase(const ObserverBase& copy) {
156 156
        if (copy.attached()) {
157 157
          attach(*copy.notifier());
158 158
        }
159 159
      }
160 160

	
161 161
      /// \brief Destructor
162 162
      virtual ~ObserverBase() {
163 163
        if (attached()) {
164 164
          detach();
165 165
        }
166 166
      }
167 167

	
168 168
      /// \brief Attaches the observer into an AlterationNotifier.
169 169
      ///
170 170
      /// This member attaches the observer into an AlterationNotifier.
171 171
      ///
172 172
      void attach(AlterationNotifier& nf) {
173 173
        nf.attach(*this);
174 174
      }
175 175

	
176 176
      /// \brief Detaches the observer into an AlterationNotifier.
177 177
      ///
178 178
      /// This member detaches the observer from an AlterationNotifier.
179 179
      ///
180 180
      void detach() {
181 181
        _notifier->detach(*this);
182 182
      }
183 183

	
184 184
      /// \brief Gives back a pointer to the notifier which the map
185 185
      /// attached into.
186 186
      ///
187 187
      /// This function gives back a pointer to the notifier which the map
188 188
      /// attached into.
189 189
      ///
190 190
      Notifier* notifier() const { return const_cast<Notifier*>(_notifier); }
191 191

	
192 192
      /// Gives back true when the observer is attached into a notifier.
193 193
      bool attached() const { return _notifier != 0; }
194 194

	
195 195
    private:
196 196

	
197 197
      ObserverBase& operator=(const ObserverBase& copy);
198 198

	
199 199
    protected:
200 200

	
201 201
      Notifier* _notifier;
202 202
      typename std::list<ObserverBase*>::iterator _index;
203 203

	
204 204
      /// \brief The member function to notificate the observer about an
205 205
      /// item is added to the container.
206 206
      ///
207 207
      /// The add() member function notificates the observer about an item
208 208
      /// is added to the container. It have to be overrided in the
209 209
      /// subclasses.
210 210
      virtual void add(const Item&) = 0;
211 211

	
212 212
      /// \brief The member function to notificate the observer about
213 213
      /// more item is added to the container.
214 214
      ///
215 215
      /// The add() member function notificates the observer about more item
216 216
      /// is added to the container. It have to be overrided in the
217 217
      /// subclasses.
218 218
      virtual void add(const std::vector<Item>& items) = 0;
219 219

	
220 220
      /// \brief The member function to notificate the observer about an
221 221
      /// item is erased from the container.
222 222
      ///
223 223
      /// The erase() member function notificates the observer about an
224 224
      /// item is erased from the container. It have to be overrided in
225 225
      /// the subclasses.
226 226
      virtual void erase(const Item&) = 0;
227 227

	
228 228
      /// \brief The member function to notificate the observer about
229 229
      /// more item is erased from the container.
230 230
      ///
231 231
      /// The erase() member function notificates the observer about more item
232 232
      /// is erased from the container. It have to be overrided in the
233 233
      /// subclasses.
234 234
      virtual void erase(const std::vector<Item>& items) = 0;
235 235

	
236 236
      /// \brief The member function to notificate the observer about the
237 237
      /// container is built.
238 238
      ///
239 239
      /// The build() member function notificates the observer about the
240 240
      /// container is built from an empty container. It have to be
241 241
      /// overrided in the subclasses.
242 242

	
243 243
      virtual void build() = 0;
244 244

	
245 245
      /// \brief The member function to notificate the observer about all
246 246
      /// items are erased from the container.
247 247
      ///
248 248
      /// The clear() member function notificates the observer about all
249 249
      /// items are erased from the container. It have to be overrided in
250 250
      /// the subclasses.
251 251
      virtual void clear() = 0;
252 252

	
253 253
    };
254 254

	
255 255
  protected:
256 256

	
257 257
    const Container* container;
258 258

	
259 259
    typedef std::list<ObserverBase*> Observers;
260 260
    Observers _observers;
261 261

	
262 262

	
263 263
  public:
264 264

	
265 265
    /// \brief Default constructor.
266 266
    ///
267 267
    /// The default constructor of the AlterationNotifier.
268 268
    /// It creates an empty notifier.
269 269
    AlterationNotifier()
270 270
      : container(0) {}
271 271

	
272 272
    /// \brief Constructor.
273 273
    ///
274 274
    /// Constructor with the observed container parameter.
275 275
    AlterationNotifier(const Container& _container)
276 276
      : container(&_container) {}
277 277

	
278 278
    /// \brief Copy Constructor of the AlterationNotifier.
279 279
    ///
280 280
    /// Copy constructor of the AlterationNotifier.
281 281
    /// It creates only an empty notifier because the copiable
282 282
    /// notifier's observers have to be registered still into that notifier.
283 283
    AlterationNotifier(const AlterationNotifier& _notifier)
284 284
      : container(_notifier.container) {}
285 285

	
286 286
    /// \brief Destructor.
287 287
    ///
288 288
    /// Destructor of the AlterationNotifier.
289 289
    ///
290 290
    ~AlterationNotifier() {
291 291
      typename Observers::iterator it;
292 292
      for (it = _observers.begin(); it != _observers.end(); ++it) {
293 293
        (*it)->_notifier = 0;
294 294
      }
295 295
    }
296 296

	
297 297
    /// \brief Sets the container.
298 298
    ///
299 299
    /// Sets the container.
300 300
    void setContainer(const Container& _container) {
301 301
      container = &_container;
302 302
    }
303 303

	
304 304
  protected:
305 305

	
306 306
    AlterationNotifier& operator=(const AlterationNotifier&);
307 307

	
308 308
  public:
309 309

	
310 310

	
311 311

	
312 312
    /// \brief First item in the container.
313 313
    ///
314 314
    /// Returns the first item in the container. It is
315 315
    /// for start the iteration on the container.
316 316
    void first(Item& item) const {
317 317
      container->first(item);
318 318
    }
319 319

	
320 320
    /// \brief Next item in the container.
321 321
    ///
322 322
    /// Returns the next item in the container. It is
323 323
    /// for iterate on the container.
324 324
    void next(Item& item) const {
325 325
      container->next(item);
326 326
    }
327 327

	
328 328
    /// \brief Returns the id of the item.
329 329
    ///
330 330
    /// Returns the id of the item provided by the container.
331 331
    int id(const Item& item) const {
332 332
      return container->id(item);
333 333
    }
334 334

	
335 335
    /// \brief Returns the maximum id of the container.
336 336
    ///
337 337
    /// Returns the maximum id of the container.
338 338
    int maxId() const {
339 339
      return container->maxId(Item());
340 340
    }
341 341

	
342 342
  protected:
343 343

	
344 344
    void attach(ObserverBase& observer) {
345 345
      observer._index = _observers.insert(_observers.begin(), &observer);
346 346
      observer._notifier = this;
347 347
    }
348 348

	
349 349
    void detach(ObserverBase& observer) {
350 350
      _observers.erase(observer._index);
351 351
      observer._index = _observers.end();
352 352
      observer._notifier = 0;
353 353
    }
354 354

	
355 355
  public:
356 356

	
357 357
    /// \brief Notifies all the registed observers about an item added to
358 358
    /// the container.
359 359
    ///
360 360
    /// It notifies all the registed observers about an item added to
361 361
    /// the container.
362 362
    ///
363 363
    void add(const Item& item) {
364 364
      typename Observers::reverse_iterator it;
365 365
      try {
366 366
        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
367 367
          (*it)->add(item);
368 368
        }
369 369
      } catch (...) {
370 370
        typename Observers::iterator jt;
371 371
        for (jt = it.base(); jt != _observers.end(); ++jt) {
372 372
          (*jt)->erase(item);
373 373
        }
374 374
        throw;
375 375
      }
376 376
    }
377 377

	
378 378
    /// \brief Notifies all the registed observers about more item added to
379 379
    /// the container.
380 380
    ///
381 381
    /// It notifies all the registed observers about more item added to
382 382
    /// the container.
383 383
    ///
384 384
    void add(const std::vector<Item>& items) {
385 385
      typename Observers::reverse_iterator it;
386 386
      try {
387 387
        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
388 388
          (*it)->add(items);
389 389
        }
390 390
      } catch (...) {
391 391
        typename Observers::iterator jt;
392 392
        for (jt = it.base(); jt != _observers.end(); ++jt) {
393 393
          (*jt)->erase(items);
394 394
        }
395 395
        throw;
396 396
      }
397 397
    }
398 398

	
399 399
    /// \brief Notifies all the registed observers about an item erased from
400 400
    /// the container.
401 401
    ///
402 402
    /// It notifies all the registed observers about an item erased from
403 403
    /// the container.
404 404
    ///
405 405
    void erase(const Item& item) throw() {
406 406
      typename Observers::iterator it = _observers.begin();
407 407
      while (it != _observers.end()) {
408 408
        try {
409 409
          (*it)->erase(item);
410 410
          ++it;
411 411
        } catch (const ImmediateDetach&) {
412 412
          (*it)->_index = _observers.end();
413 413
          (*it)->_notifier = 0;
414 414
          it = _observers.erase(it);
415 415
        }
416 416
      }
417 417
    }
418 418

	
419 419
    /// \brief Notifies all the registed observers about more item erased
420 420
    /// from the container.
421 421
    ///
422 422
    /// It notifies all the registed observers about more item erased from
423 423
    /// the container.
424 424
    ///
425 425
    void erase(const std::vector<Item>& items) {
426 426
      typename Observers::iterator it = _observers.begin();
427 427
      while (it != _observers.end()) {
428 428
        try {
429 429
          (*it)->erase(items);
430 430
          ++it;
431 431
        } catch (const ImmediateDetach&) {
432 432
          (*it)->_index = _observers.end();
433 433
          (*it)->_notifier = 0;
434 434
          it = _observers.erase(it);
435 435
        }
436 436
      }
437 437
    }
438 438

	
439 439
    /// \brief Notifies all the registed observers about the container is
440 440
    /// built.
441 441
    ///
442 442
    /// Notifies all the registed observers about the container is built
443 443
    /// from an empty container.
444 444
    void build() {
445 445
      typename Observers::reverse_iterator it;
446 446
      try {
447 447
        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
448 448
          (*it)->build();
449 449
        }
450 450
      } catch (...) {
451 451
        typename Observers::iterator jt;
452 452
        for (jt = it.base(); jt != _observers.end(); ++jt) {
453 453
          (*jt)->clear();
454 454
        }
455 455
        throw;
456 456
      }
457 457
    }
458 458

	
459 459
    /// \brief Notifies all the registed observers about all items are
460 460
    /// erased.
461 461
    ///
462 462
    /// Notifies all the registed observers about all items are erased
463 463
    /// from the container.
464 464
    void clear() {
465 465
      typename Observers::iterator it = _observers.begin();
466 466
      while (it != _observers.end()) {
467 467
        try {
468 468
          (*it)->clear();
469 469
          ++it;
470 470
        } catch (const ImmediateDetach&) {
471 471
          (*it)->_index = _observers.end();
472 472
          (*it)->_notifier = 0;
473 473
          it = _observers.erase(it);
474 474
        }
475 475
      }
476 476
    }
477 477
  };
478 478

	
479 479
}
480 480

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

	
19 19
///\ingroup concept
20 20
///\file
21 21
///\brief Classes for representing paths in digraphs.
22 22
///
23 23
///\todo Iterators have obsolete style
24 24

	
25 25
#ifndef LEMON_CONCEPT_PATH_H
26 26
#define LEMON_CONCEPT_PATH_H
27 27

	
28 28
#include <lemon/core.h>
29 29
#include <lemon/concept_check.h>
30 30

	
31 31
namespace lemon {
32 32
  namespace concepts {
33 33

	
34 34
    /// \addtogroup concept
35 35
    /// @{
36 36

	
37 37
    /// \brief A skeleton structure for representing directed paths in
38 38
    /// a digraph.
39 39
    ///
40 40
    /// A skeleton structure for representing directed paths in a
41 41
    /// digraph.
42 42
    /// \tparam _Digraph The digraph type in which the path is.
43 43
    ///
44 44
    /// In a sense, the path can be treated as a list of arcs. The
45 45
    /// lemon path type stores just this list. As a consequence it
46 46
    /// cannot enumerate the nodes in the path and the zero length
47 47
    /// paths cannot store the source.
48 48
    ///
49 49
    template <typename _Digraph>
50 50
    class Path {
51 51
    public:
52 52

	
53 53
      /// Type of the underlying digraph.
54 54
      typedef _Digraph Digraph;
55 55
      /// Arc type of the underlying digraph.
56 56
      typedef typename Digraph::Arc Arc;
57 57

	
58 58
      class ArcIt;
59 59

	
60 60
      /// \brief Default constructor
61 61
      Path() {}
62 62

	
63 63
      /// \brief Template constructor
64 64
      template <typename CPath>
65 65
      Path(const CPath& cpath) {}
66 66

	
67 67
      /// \brief Template assigment
68 68
      template <typename CPath>
69 69
      Path& operator=(const CPath& cpath) {}
70 70

	
71 71
      /// Length of the path ie. the number of arcs in the path.
72 72
      int length() const { return 0;}
73 73

	
74 74
      /// Returns whether the path is empty.
75 75
      bool empty() const { return true;}
76 76

	
77 77
      /// Resets the path to an empty path.
78 78
      void clear() {}
79 79

	
80
      /// \brief Lemon style iterator for path arcs
80
      /// \brief LEMON style iterator for path arcs
81 81
      ///
82 82
      /// This class is used to iterate on the arcs of the paths.
83 83
      class ArcIt {
84 84
      public:
85 85
        /// Default constructor
86 86
        ArcIt() {}
87 87
        /// Invalid constructor
88 88
        ArcIt(Invalid) {}
89 89
        /// Constructor for first arc
90 90
        ArcIt(const Path &) {}
91 91

	
92 92
        /// Conversion to Arc
93 93
        operator Arc() const { return INVALID; }
94 94

	
95 95
        /// Next arc
96 96
        ArcIt& operator++() {return *this;}
97 97

	
98 98
        /// Comparison operator
99 99
        bool operator==(const ArcIt&) const {return true;}
100 100
        /// Comparison operator
101 101
        bool operator!=(const ArcIt&) const {return true;}
102 102
        /// Comparison operator
103 103
        bool operator<(const ArcIt&) const {return false;}
104 104

	
105 105
      };
106 106

	
107 107
      template <typename _Path>
108 108
      struct Constraints {
109 109
        void constraints() {
110 110
          Path<Digraph> pc;
111 111
          _Path p, pp(pc);
112 112
          int l = p.length();
113 113
          int e = p.empty();
114 114
          p.clear();
115 115

	
116 116
          p = pc;
117 117

	
118 118
          typename _Path::ArcIt id, ii(INVALID), i(p);
119 119

	
120 120
          ++i;
121 121
          typename Digraph::Arc ed = i;
122 122

	
123 123
          e = (i == ii);
124 124
          e = (i != ii);
125 125
          e = (i < ii);
126 126

	
127 127
          ignore_unused_variable_warning(l);
128 128
          ignore_unused_variable_warning(pp);
129 129
          ignore_unused_variable_warning(e);
130 130
          ignore_unused_variable_warning(id);
131 131
          ignore_unused_variable_warning(ii);
132 132
          ignore_unused_variable_warning(ed);
133 133
        }
134 134
      };
135 135

	
136 136
    };
137 137

	
138 138
    namespace _path_bits {
139 139

	
140 140
      template <typename _Digraph, typename _Path, typename RevPathTag = void>
141 141
      struct PathDumperConstraints {
142 142
        void constraints() {
143 143
          int l = p.length();
144 144
          int e = p.empty();
145 145

	
146 146
          typename _Path::ArcIt id, i(p);
147 147

	
148 148
          ++i;
149 149
          typename _Digraph::Arc ed = i;
150 150

	
151 151
          e = (i == INVALID);
152 152
          e = (i != INVALID);
153 153

	
154 154
          ignore_unused_variable_warning(l);
155 155
          ignore_unused_variable_warning(e);
156 156
          ignore_unused_variable_warning(id);
157 157
          ignore_unused_variable_warning(ed);
158 158
        }
159 159
        _Path& p;
160 160
      };
161 161

	
162 162
      template <typename _Digraph, typename _Path>
163 163
      struct PathDumperConstraints<
164 164
        _Digraph, _Path,
165 165
        typename enable_if<typename _Path::RevPathTag, void>::type
166 166
      > {
167 167
        void constraints() {
168 168
          int l = p.length();
169 169
          int e = p.empty();
170 170

	
171 171
          typename _Path::RevArcIt id, i(p);
172 172

	
173 173
          ++i;
174 174
          typename _Digraph::Arc ed = i;
175 175

	
176 176
          e = (i == INVALID);
177 177
          e = (i != INVALID);
178 178

	
179 179
          ignore_unused_variable_warning(l);
180 180
          ignore_unused_variable_warning(e);
181 181
          ignore_unused_variable_warning(id);
182 182
          ignore_unused_variable_warning(ed);
183 183
        }
184 184
        _Path& p;
185 185
      };
186 186

	
187 187
    }
188 188

	
189 189

	
190 190
    /// \brief A skeleton structure for path dumpers.
191 191
    ///
192 192
    /// A skeleton structure for path dumpers. The path dumpers are
193 193
    /// the generalization of the paths. The path dumpers can
194 194
    /// enumerate the arcs of the path wheter in forward or in
195 195
    /// backward order.  In most time these classes are not used
196 196
    /// directly rather it used to assign a dumped class to a real
197 197
    /// path type.
198 198
    ///
199 199
    /// The main purpose of this concept is that the shortest path
200 200
    /// algorithms can enumerate easily the arcs in reverse order.
201 201
    /// If we would like to give back a real path from these
202 202
    /// algorithms then we should create a temporarly path object. In
203
    /// Lemon such algorithms gives back a path dumper what can
203
    /// LEMON such algorithms gives back a path dumper what can
204 204
    /// assigned to a real path and the dumpers can be implemented as
205 205
    /// an adaptor class to the predecessor map.
206 206

	
207 207
    /// \tparam _Digraph  The digraph type in which the path is.
208 208
    ///
209 209
    /// The paths can be constructed from any path type by a
210 210
    /// template constructor or a template assignment operator.
211 211
    ///
212 212
    template <typename _Digraph>
213 213
    class PathDumper {
214 214
    public:
215 215

	
216 216
      /// Type of the underlying digraph.
217 217
      typedef _Digraph Digraph;
218 218
      /// Arc type of the underlying digraph.
219 219
      typedef typename Digraph::Arc Arc;
220 220

	
221 221
      /// Length of the path ie. the number of arcs in the path.
222 222
      int length() const { return 0;}
223 223

	
224 224
      /// Returns whether the path is empty.
225 225
      bool empty() const { return true;}
226 226

	
227 227
      /// \brief Forward or reverse dumping
228 228
      ///
229 229
      /// If the RevPathTag is defined and true then reverse dumping
230 230
      /// is provided in the path dumper. In this case instead of the
231 231
      /// ArcIt the RevArcIt iterator should be implemented in the
232 232
      /// dumper.
233 233
      typedef False RevPathTag;
234 234

	
235
      /// \brief Lemon style iterator for path arcs
235
      /// \brief LEMON style iterator for path arcs
236 236
      ///
237 237
      /// This class is used to iterate on the arcs of the paths.
238 238
      class ArcIt {
239 239
      public:
240 240
        /// Default constructor
241 241
        ArcIt() {}
242 242
        /// Invalid constructor
243 243
        ArcIt(Invalid) {}
244 244
        /// Constructor for first arc
245 245
        ArcIt(const PathDumper&) {}
246 246

	
247 247
        /// Conversion to Arc
248 248
        operator Arc() const { return INVALID; }
249 249

	
250 250
        /// Next arc
251 251
        ArcIt& operator++() {return *this;}
252 252

	
253 253
        /// Comparison operator
254 254
        bool operator==(const ArcIt&) const {return true;}
255 255
        /// Comparison operator
256 256
        bool operator!=(const ArcIt&) const {return true;}
257 257
        /// Comparison operator
258 258
        bool operator<(const ArcIt&) const {return false;}
259 259

	
260 260
      };
261 261

	
262
      /// \brief Lemon style iterator for path arcs
262
      /// \brief LEMON style iterator for path arcs
263 263
      ///
264 264
      /// This class is used to iterate on the arcs of the paths in
265 265
      /// reverse direction.
266 266
      class RevArcIt {
267 267
      public:
268 268
        /// Default constructor
269 269
        RevArcIt() {}
270 270
        /// Invalid constructor
271 271
        RevArcIt(Invalid) {}
272 272
        /// Constructor for first arc
273 273
        RevArcIt(const PathDumper &) {}
274 274

	
275 275
        /// Conversion to Arc
276 276
        operator Arc() const { return INVALID; }
277 277

	
278 278
        /// Next arc
279 279
        RevArcIt& operator++() {return *this;}
280 280

	
281 281
        /// Comparison operator
282 282
        bool operator==(const RevArcIt&) const {return true;}
283 283
        /// Comparison operator
284 284
        bool operator!=(const RevArcIt&) const {return true;}
285 285
        /// Comparison operator
286 286
        bool operator<(const RevArcIt&) const {return false;}
287 287

	
288 288
      };
289 289

	
290 290
      template <typename _Path>
291 291
      struct Constraints {
292 292
        void constraints() {
293 293
          function_requires<_path_bits::
294 294
            PathDumperConstraints<Digraph, _Path> >();
295 295
        }
296 296
      };
297 297

	
298 298
    };
299 299

	
300 300

	
301 301
    ///@}
302 302
  }
303 303

	
304 304
} // namespace lemon
305 305

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

	
19 19
///\ingroup lemon_io
20 20
///\file
21
///\brief \ref lgf-format "Lemon Graph Format" reader.
21
///\brief \ref lgf-format "LEMON Graph Format" reader.
22 22

	
23 23

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

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

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

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

	
37 37
#include <lemon/lgf_writer.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 _reader_bits {
45 45

	
46 46
    template <typename Value>
47 47
    struct DefaultConverter {
48 48
      Value operator()(const std::string& str) {
49 49
        std::istringstream is(str);
50 50
        Value value;
51 51
        is >> value;
52 52

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

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

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

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

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

	
79 79
    };
80 80

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
331 331
      Functor _functor;
332 332

	
333 333
    public:
334 334

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

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

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

	
363 363
      Functor _functor;
364 364

	
365 365
    public:
366 366

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

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

	
387 387
  }
388 388

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

	
392 392
  template <typename Digraph>
393 393
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph);
394 394

	
395 395
  template <typename Digraph>
396 396
  DigraphReader<Digraph> digraphReader(const std::string& fn, Digraph& digraph);
397 397

	
398 398
  template <typename Digraph>
399 399
  DigraphReader<Digraph> digraphReader(const char *fn, Digraph& digraph);
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>(std::cin, digraph).
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

	
464 464
    Digraph& _digraph;
465 465

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

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

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

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

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

	
487 487
    bool _use_nodes;
488 488
    bool _use_arcs;
489 489

	
490 490
    bool _skip_nodes;
491 491
    bool _skip_arcs;
492 492

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

	
496 496
  public:
497 497

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

	
507 507
    /// \brief Constructor
508 508
    ///
509 509
    /// Construct a directed graph reader, which reads from the given
510 510
    /// file.
511 511
    DigraphReader(const std::string& fn, Digraph& digraph)
512 512
      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
513 513
        _use_nodes(false), _use_arcs(false),
514 514
        _skip_nodes(false), _skip_arcs(false) {}
515 515

	
516 516
    /// \brief Constructor
517 517
    ///
518 518
    /// Construct a directed graph reader, which reads from the given
519 519
    /// file.
520 520
    DigraphReader(const char* fn, Digraph& digraph)
521 521
      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
522 522
        _use_nodes(false), _use_arcs(false),
523 523
        _skip_nodes(false), _skip_arcs(false) {}
524 524

	
525 525
    /// \brief Destructor
526 526
    ~DigraphReader() {
527 527
      for (typename NodeMaps::iterator it = _node_maps.begin();
528 528
           it != _node_maps.end(); ++it) {
529 529
        delete it->second;
530 530
      }
531 531

	
532 532
      for (typename ArcMaps::iterator it = _arc_maps.begin();
533 533
           it != _arc_maps.end(); ++it) {
534 534
        delete it->second;
535 535
      }
536 536

	
537 537
      for (typename Attributes::iterator it = _attributes.begin();
538 538
           it != _attributes.end(); ++it) {
539 539
        delete it->second;
540 540
      }
541 541

	
542 542
      if (local_is) {
543 543
        delete _is;
544 544
      }
545 545

	
546 546
    }
547 547

	
548 548
  private:
549 549

	
550 550
    friend DigraphReader<Digraph> digraphReader<>(std::istream& is,
551 551
                                                  Digraph& digraph);
552 552
    friend DigraphReader<Digraph> digraphReader<>(const std::string& fn,
553 553
                                                  Digraph& digraph);
554 554
    friend DigraphReader<Digraph> digraphReader<>(const char *fn,
555 555
                                                  Digraph& digraph);
556 556

	
557 557
    DigraphReader(DigraphReader& other)
558 558
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
559 559
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
560 560
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
561 561

	
562 562
      other._is = 0;
563 563
      other.local_is = false;
564 564

	
565 565
      _node_index.swap(other._node_index);
566 566
      _arc_index.swap(other._arc_index);
567 567

	
568 568
      _node_maps.swap(other._node_maps);
569 569
      _arc_maps.swap(other._arc_maps);
570 570
      _attributes.swap(other._attributes);
571 571

	
572 572
      _nodes_caption = other._nodes_caption;
573 573
      _arcs_caption = other._arcs_caption;
574 574
      _attributes_caption = other._attributes_caption;
575 575

	
576 576
    }
577 577

	
578 578
    DigraphReader& operator=(const DigraphReader&);
579 579

	
580 580
  public:
581 581

	
582 582
    /// \name Reading rules
583 583
    /// @{
584 584

	
585 585
    /// \brief Node map reading rule
586 586
    ///
587 587
    /// Add a node map reading rule to the reader.
588 588
    template <typename Map>
589 589
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
590 590
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
591 591
      _reader_bits::MapStorageBase<Node>* storage =
592 592
        new _reader_bits::MapStorage<Node, Map>(map);
593 593
      _node_maps.push_back(std::make_pair(caption, storage));
594 594
      return *this;
595 595
    }
596 596

	
597 597
    /// \brief Node map reading rule
598 598
    ///
599 599
    /// Add a node map reading rule with specialized converter to the
600 600
    /// reader.
601 601
    template <typename Map, typename Converter>
602 602
    DigraphReader& nodeMap(const std::string& caption, Map& map,
603 603
                           const Converter& converter = Converter()) {
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, Converter>(map, converter);
607 607
      _node_maps.push_back(std::make_pair(caption, storage));
608 608
      return *this;
609 609
    }
610 610

	
611 611
    /// \brief Arc map reading rule
612 612
    ///
613 613
    /// Add an arc map reading rule to the reader.
614 614
    template <typename Map>
615 615
    DigraphReader& arcMap(const std::string& caption, Map& map) {
616 616
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
617 617
      _reader_bits::MapStorageBase<Arc>* storage =
618 618
        new _reader_bits::MapStorage<Arc, Map>(map);
619 619
      _arc_maps.push_back(std::make_pair(caption, storage));
620 620
      return *this;
621 621
    }
622 622

	
623 623
    /// \brief Arc map reading rule
624 624
    ///
625 625
    /// Add an arc map reading rule with specialized converter to the
626 626
    /// reader.
627 627
    template <typename Map, typename Converter>
628 628
    DigraphReader& arcMap(const std::string& caption, Map& map,
629 629
                          const Converter& converter = Converter()) {
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, Converter>(map, converter);
633 633
      _arc_maps.push_back(std::make_pair(caption, storage));
634 634
      return *this;
635 635
    }
636 636

	
637 637
    /// \brief Attribute reading rule
638 638
    ///
639 639
    /// Add an attribute reading rule to the reader.
640 640
    template <typename Value>
641 641
    DigraphReader& attribute(const std::string& caption, Value& value) {
642 642
      _reader_bits::ValueStorageBase* storage =
643 643
        new _reader_bits::ValueStorage<Value>(value);
644 644
      _attributes.insert(std::make_pair(caption, storage));
645 645
      return *this;
646 646
    }
647 647

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

	
661 661
    /// \brief Node reading rule
662 662
    ///
663 663
    /// Add a node reading rule to reader.
664 664
    DigraphReader& node(const std::string& caption, Node& node) {
665 665
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
666 666
      Converter converter(_node_index);
667 667
      _reader_bits::ValueStorageBase* storage =
668 668
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
669 669
      _attributes.insert(std::make_pair(caption, storage));
670 670
      return *this;
671 671
    }
672 672

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

	
685 685
    /// @}
686 686

	
687 687
    /// \name Select section by name
688 688
    /// @{
689 689

	
690 690
    /// \brief Set \c \@nodes section to be read
691 691
    ///
692 692
    /// Set \c \@nodes section to be read
693 693
    DigraphReader& nodes(const std::string& caption) {
694 694
      _nodes_caption = caption;
695 695
      return *this;
696 696
    }
697 697

	
698 698
    /// \brief Set \c \@arcs section to be read
699 699
    ///
700 700
    /// Set \c \@arcs section to be read
701 701
    DigraphReader& arcs(const std::string& caption) {
702 702
      _arcs_caption = caption;
703 703
      return *this;
704 704
    }
705 705

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

	
714 714
    /// @}
715 715

	
716 716
    /// \name Using previously constructed node or arc set
717 717
    /// @{
718 718

	
719 719
    /// \brief Use previously constructed node set
720 720
    ///
721 721
    /// Use previously constructed node set, and specify the node
722 722
    /// label map.
723 723
    template <typename Map>
724 724
    DigraphReader& useNodes(const Map& map) {
725 725
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
726 726
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
727 727
      _use_nodes = true;
728 728
      _writer_bits::DefaultConverter<typename Map::Value> converter;
729 729
      for (NodeIt n(_digraph); n != INVALID; ++n) {
730 730
        _node_index.insert(std::make_pair(converter(map[n]), n));
731 731
      }
732 732
      return *this;
733 733
    }
734 734

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

	
752 752
    /// \brief Use previously constructed arc set
753 753
    ///
754 754
    /// Use previously constructed arc set, and specify the arc
755 755
    /// label map.
756 756
    template <typename Map>
757 757
    DigraphReader& useArcs(const Map& map) {
758 758
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
759 759
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
760 760
      _use_arcs = true;
761 761
      _writer_bits::DefaultConverter<typename Map::Value> converter;
762 762
      for (ArcIt a(_digraph); a != INVALID; ++a) {
763 763
        _arc_index.insert(std::make_pair(converter(map[a]), a));
764 764
      }
765 765
      return *this;
766 766
    }
767 767

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

	
785 785
    /// \brief Skips the reading of node section
786 786
    ///
787 787
    /// Omit the reading of the node section. This implies that each node
788 788
    /// map reading rule will be abandoned, and the nodes of the graph
789 789
    /// will not be constructed, which usually cause that the arc set
... ...
@@ -1536,1081 +1536,1081 @@
1536 1536
    GraphReader& attributes(const std::string& caption) {
1537 1537
      _attributes_caption = caption;
1538 1538
      return *this;
1539 1539
    }
1540 1540

	
1541 1541
    /// @}
1542 1542

	
1543 1543
    /// \name Using previously constructed node or edge set
1544 1544
    /// @{
1545 1545

	
1546 1546
    /// \brief Use previously constructed node set
1547 1547
    ///
1548 1548
    /// Use previously constructed node set, and specify the node
1549 1549
    /// label map.
1550 1550
    template <typename Map>
1551 1551
    GraphReader& useNodes(const Map& map) {
1552 1552
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1553 1553
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1554 1554
      _use_nodes = true;
1555 1555
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1556 1556
      for (NodeIt n(_graph); n != INVALID; ++n) {
1557 1557
        _node_index.insert(std::make_pair(converter(map[n]), n));
1558 1558
      }
1559 1559
      return *this;
1560 1560
    }
1561 1561

	
1562 1562
    /// \brief Use previously constructed node set
1563 1563
    ///
1564 1564
    /// Use previously constructed node set, and specify the node
1565 1565
    /// label map and a functor which converts the label map values to
1566 1566
    /// \c std::string.
1567 1567
    template <typename Map, typename Converter>
1568 1568
    GraphReader& useNodes(const Map& map,
1569 1569
                            const Converter& converter = Converter()) {
1570 1570
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1571 1571
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1572 1572
      _use_nodes = true;
1573 1573
      for (NodeIt n(_graph); n != INVALID; ++n) {
1574 1574
        _node_index.insert(std::make_pair(converter(map[n]), n));
1575 1575
      }
1576 1576
      return *this;
1577 1577
    }
1578 1578

	
1579 1579
    /// \brief Use previously constructed edge set
1580 1580
    ///
1581 1581
    /// Use previously constructed edge set, and specify the edge
1582 1582
    /// label map.
1583 1583
    template <typename Map>
1584 1584
    GraphReader& useEdges(const Map& map) {
1585 1585
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1586 1586
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1587 1587
      _use_edges = true;
1588 1588
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1589 1589
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1590 1590
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1591 1591
      }
1592 1592
      return *this;
1593 1593
    }
1594 1594

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

	
1612 1612
    /// \brief Skip the reading of node section
1613 1613
    ///
1614 1614
    /// Omit the reading of the node section. This implies that each node
1615 1615
    /// map reading rule will be abandoned, and the nodes of the graph
1616 1616
    /// will not be constructed, which usually cause that the edge set
1617 1617
    /// could not be read due to lack of node name
1618 1618
    /// could not be read due to lack of node name resolving.
1619 1619
    /// Therefore \c skipEdges() function should also be used, or
1620 1620
    /// \c useNodes() should be used to specify the label of the nodes.
1621 1621
    GraphReader& skipNodes() {
1622 1622
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1623 1623
      _skip_nodes = true;
1624 1624
      return *this;
1625 1625
    }
1626 1626

	
1627 1627
    /// \brief Skip the reading of edge section
1628 1628
    ///
1629 1629
    /// Omit the reading of the edge section. This implies that each edge
1630 1630
    /// map reading rule will be abandoned, and the edges of the graph
1631 1631
    /// will not be constructed.
1632 1632
    GraphReader& skipEdges() {
1633 1633
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1634 1634
      _skip_edges = true;
1635 1635
      return *this;
1636 1636
    }
1637 1637

	
1638 1638
    /// @}
1639 1639

	
1640 1640
  private:
1641 1641

	
1642 1642
    bool readLine() {
1643 1643
      std::string str;
1644 1644
      while(++line_num, std::getline(*_is, str)) {
1645 1645
        line.clear(); line.str(str);
1646 1646
        char c;
1647 1647
        if (line >> std::ws >> c && c != '#') {
1648 1648
          line.putback(c);
1649 1649
          return true;
1650 1650
        }
1651 1651
      }
1652 1652
      return false;
1653 1653
    }
1654 1654

	
1655 1655
    bool readSuccess() {
1656 1656
      return static_cast<bool>(*_is);
1657 1657
    }
1658 1658

	
1659 1659
    void skipSection() {
1660 1660
      char c;
1661 1661
      while (readSuccess() && line >> c && c != '@') {
1662 1662
        readLine();
1663 1663
      }
1664 1664
      line.putback(c);
1665 1665
    }
1666 1666

	
1667 1667
    void readNodes() {
1668 1668

	
1669 1669
      std::vector<int> map_index(_node_maps.size());
1670 1670
      int map_num, label_index;
1671 1671

	
1672 1672
      char c;
1673 1673
      if (!readLine() || !(line >> c) || c == '@') {
1674 1674
        if (readSuccess() && line) line.putback(c);
1675 1675
        if (!_node_maps.empty())
1676 1676
          throw DataFormatError("Cannot find map names");
1677 1677
        return;
1678 1678
      }
1679 1679
      line.putback(c);
1680 1680

	
1681 1681
      {
1682 1682
        std::map<std::string, int> maps;
1683 1683

	
1684 1684
        std::string map;
1685 1685
        int index = 0;
1686 1686
        while (_reader_bits::readToken(line, map)) {
1687 1687
          if (maps.find(map) != maps.end()) {
1688 1688
            std::ostringstream msg;
1689 1689
            msg << "Multiple occurence of node map: " << map;
1690 1690
            throw DataFormatError(msg.str().c_str());
1691 1691
          }
1692 1692
          maps.insert(std::make_pair(map, index));
1693 1693
          ++index;
1694 1694
        }
1695 1695

	
1696 1696
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1697 1697
          std::map<std::string, int>::iterator jt =
1698 1698
            maps.find(_node_maps[i].first);
1699 1699
          if (jt == maps.end()) {
1700 1700
            std::ostringstream msg;
1701 1701
            msg << "Map not found in file: " << _node_maps[i].first;
1702 1702
            throw DataFormatError(msg.str().c_str());
1703 1703
          }
1704 1704
          map_index[i] = jt->second;
1705 1705
        }
1706 1706

	
1707 1707
        {
1708 1708
          std::map<std::string, int>::iterator jt = maps.find("label");
1709 1709
          if (jt != maps.end()) {
1710 1710
            label_index = jt->second;
1711 1711
          } else {
1712 1712
            label_index = -1;
1713 1713
          }
1714 1714
        }
1715 1715
        map_num = maps.size();
1716 1716
      }
1717 1717

	
1718 1718
      while (readLine() && line >> c && c != '@') {
1719 1719
        line.putback(c);
1720 1720

	
1721 1721
        std::vector<std::string> tokens(map_num);
1722 1722
        for (int i = 0; i < map_num; ++i) {
1723 1723
          if (!_reader_bits::readToken(line, tokens[i])) {
1724 1724
            std::ostringstream msg;
1725 1725
            msg << "Column not found (" << i + 1 << ")";
1726 1726
            throw DataFormatError(msg.str().c_str());
1727 1727
          }
1728 1728
        }
1729 1729
        if (line >> std::ws >> c)
1730 1730
          throw DataFormatError("Extra character on the end of line");
1731 1731

	
1732 1732
        Node n;
1733 1733
        if (!_use_nodes) {
1734 1734
          n = _graph.addNode();
1735 1735
          if (label_index != -1)
1736 1736
            _node_index.insert(std::make_pair(tokens[label_index], n));
1737 1737
        } else {
1738 1738
          if (label_index == -1)
1739 1739
            throw DataFormatError("Label map not found in file");
1740 1740
          typename std::map<std::string, Node>::iterator it =
1741 1741
            _node_index.find(tokens[label_index]);
1742 1742
          if (it == _node_index.end()) {
1743 1743
            std::ostringstream msg;
1744 1744
            msg << "Node with label not found: " << tokens[label_index];
1745 1745
            throw DataFormatError(msg.str().c_str());
1746 1746
          }
1747 1747
          n = it->second;
1748 1748
        }
1749 1749

	
1750 1750
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1751 1751
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1752 1752
        }
1753 1753

	
1754 1754
      }
1755 1755
      if (readSuccess()) {
1756 1756
        line.putback(c);
1757 1757
      }
1758 1758
    }
1759 1759

	
1760 1760
    void readEdges() {
1761 1761

	
1762 1762
      std::vector<int> map_index(_edge_maps.size());
1763 1763
      int map_num, label_index;
1764 1764

	
1765 1765
      char c;
1766 1766
      if (!readLine() || !(line >> c) || c == '@') {
1767 1767
        if (readSuccess() && line) line.putback(c);
1768 1768
        if (!_edge_maps.empty())
1769 1769
          throw DataFormatError("Cannot find map names");
1770 1770
        return;
1771 1771
      }
1772 1772
      line.putback(c);
1773 1773

	
1774 1774
      {
1775 1775
        std::map<std::string, int> maps;
1776 1776

	
1777 1777
        std::string map;
1778 1778
        int index = 0;
1779 1779
        while (_reader_bits::readToken(line, map)) {
1780 1780
          if (maps.find(map) != maps.end()) {
1781 1781
            std::ostringstream msg;
1782 1782
            msg << "Multiple occurence of edge map: " << map;
1783 1783
            throw DataFormatError(msg.str().c_str());
1784 1784
          }
1785 1785
          maps.insert(std::make_pair(map, index));
1786 1786
          ++index;
1787 1787
        }
1788 1788

	
1789 1789
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1790 1790
          std::map<std::string, int>::iterator jt =
1791 1791
            maps.find(_edge_maps[i].first);
1792 1792
          if (jt == maps.end()) {
1793 1793
            std::ostringstream msg;
1794 1794
            msg << "Map not found in file: " << _edge_maps[i].first;
1795 1795
            throw DataFormatError(msg.str().c_str());
1796 1796
          }
1797 1797
          map_index[i] = jt->second;
1798 1798
        }
1799 1799

	
1800 1800
        {
1801 1801
          std::map<std::string, int>::iterator jt = maps.find("label");
1802 1802
          if (jt != maps.end()) {
1803 1803
            label_index = jt->second;
1804 1804
          } else {
1805 1805
            label_index = -1;
1806 1806
          }
1807 1807
        }
1808 1808
        map_num = maps.size();
1809 1809
      }
1810 1810

	
1811 1811
      while (readLine() && line >> c && c != '@') {
1812 1812
        line.putback(c);
1813 1813

	
1814 1814
        std::string source_token;
1815 1815
        std::string target_token;
1816 1816

	
1817 1817
        if (!_reader_bits::readToken(line, source_token))
1818 1818
          throw DataFormatError("Node u not found");
1819 1819

	
1820 1820
        if (!_reader_bits::readToken(line, target_token))
1821 1821
          throw DataFormatError("Node v not found");
1822 1822

	
1823 1823
        std::vector<std::string> tokens(map_num);
1824 1824
        for (int i = 0; i < map_num; ++i) {
1825 1825
          if (!_reader_bits::readToken(line, tokens[i])) {
1826 1826
            std::ostringstream msg;
1827 1827
            msg << "Column not found (" << i + 1 << ")";
1828 1828
            throw DataFormatError(msg.str().c_str());
1829 1829
          }
1830 1830
        }
1831 1831
        if (line >> std::ws >> c)
1832 1832
          throw DataFormatError("Extra character on the end of line");
1833 1833

	
1834 1834
        Edge e;
1835 1835
        if (!_use_edges) {
1836 1836

	
1837 1837
          typename NodeIndex::iterator it;
1838 1838

	
1839 1839
          it = _node_index.find(source_token);
1840 1840
          if (it == _node_index.end()) {
1841 1841
            std::ostringstream msg;
1842 1842
            msg << "Item not found: " << source_token;
1843 1843
            throw DataFormatError(msg.str().c_str());
1844 1844
          }
1845 1845
          Node source = it->second;
1846 1846

	
1847 1847
          it = _node_index.find(target_token);
1848 1848
          if (it == _node_index.end()) {
1849 1849
            std::ostringstream msg;
1850 1850
            msg << "Item not found: " << target_token;
1851 1851
            throw DataFormatError(msg.str().c_str());
1852 1852
          }
1853 1853
          Node target = it->second;
1854 1854

	
1855 1855
          e = _graph.addEdge(source, target);
1856 1856
          if (label_index != -1)
1857 1857
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1858 1858
        } else {
1859 1859
          if (label_index == -1)
1860 1860
            throw DataFormatError("Label map not found in file");
1861 1861
          typename std::map<std::string, Edge>::iterator it =
1862 1862
            _edge_index.find(tokens[label_index]);
1863 1863
          if (it == _edge_index.end()) {
1864 1864
            std::ostringstream msg;
1865 1865
            msg << "Edge with label not found: " << tokens[label_index];
1866 1866
            throw DataFormatError(msg.str().c_str());
1867 1867
          }
1868 1868
          e = it->second;
1869 1869
        }
1870 1870

	
1871 1871
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1872 1872
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1873 1873
        }
1874 1874

	
1875 1875
      }
1876 1876
      if (readSuccess()) {
1877 1877
        line.putback(c);
1878 1878
      }
1879 1879
    }
1880 1880

	
1881 1881
    void readAttributes() {
1882 1882

	
1883 1883
      std::set<std::string> read_attr;
1884 1884

	
1885 1885
      char c;
1886 1886
      while (readLine() && line >> c && c != '@') {
1887 1887
        line.putback(c);
1888 1888

	
1889 1889
        std::string attr, token;
1890 1890
        if (!_reader_bits::readToken(line, attr))
1891 1891
          throw DataFormatError("Attribute name not found");
1892 1892
        if (!_reader_bits::readToken(line, token))
1893 1893
          throw DataFormatError("Attribute value not found");
1894 1894
        if (line >> c)
1895 1895
          throw DataFormatError("Extra character on the end of line");
1896 1896

	
1897 1897
        {
1898 1898
          std::set<std::string>::iterator it = read_attr.find(attr);
1899 1899
          if (it != read_attr.end()) {
1900 1900
            std::ostringstream msg;
1901 1901
            msg << "Multiple occurence of attribute " << attr;
1902 1902
            throw DataFormatError(msg.str().c_str());
1903 1903
          }
1904 1904
          read_attr.insert(attr);
1905 1905
        }
1906 1906

	
1907 1907
        {
1908 1908
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1909 1909
          while (it != _attributes.end() && it->first == attr) {
1910 1910
            it->second->set(token);
1911 1911
            ++it;
1912 1912
          }
1913 1913
        }
1914 1914

	
1915 1915
      }
1916 1916
      if (readSuccess()) {
1917 1917
        line.putback(c);
1918 1918
      }
1919 1919
      for (typename Attributes::iterator it = _attributes.begin();
1920 1920
           it != _attributes.end(); ++it) {
1921 1921
        if (read_attr.find(it->first) == read_attr.end()) {
1922 1922
          std::ostringstream msg;
1923 1923
          msg << "Attribute not found in file: " << it->first;
1924 1924
          throw DataFormatError(msg.str().c_str());
1925 1925
        }
1926 1926
      }
1927 1927
    }
1928 1928

	
1929 1929
  public:
1930 1930

	
1931 1931
    /// \name Execution of the reader
1932 1932
    /// @{
1933 1933

	
1934 1934
    /// \brief Start the batch processing
1935 1935
    ///
1936 1936
    /// This function starts the batch processing
1937 1937
    void run() {
1938 1938

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

	
1941 1941
      bool nodes_done = _skip_nodes;
1942 1942
      bool edges_done = _skip_edges;
1943 1943
      bool attributes_done = false;
1944 1944

	
1945 1945
      line_num = 0;
1946 1946
      readLine();
1947 1947
      skipSection();
1948 1948

	
1949 1949
      while (readSuccess()) {
1950 1950
        try {
1951 1951
          char c;
1952 1952
          std::string section, caption;
1953 1953
          line >> c;
1954 1954
          _reader_bits::readToken(line, section);
1955 1955
          _reader_bits::readToken(line, caption);
1956 1956

	
1957 1957
          if (line >> c)
1958 1958
            throw DataFormatError("Extra character on the end of line");
1959 1959

	
1960 1960
          if (section == "nodes" && !nodes_done) {
1961 1961
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1962 1962
              readNodes();
1963 1963
              nodes_done = true;
1964 1964
            }
1965 1965
          } else if ((section == "edges" || section == "arcs") &&
1966 1966
                     !edges_done) {
1967 1967
            if (_edges_caption.empty() || _edges_caption == caption) {
1968 1968
              readEdges();
1969 1969
              edges_done = true;
1970 1970
            }
1971 1971
          } else if (section == "attributes" && !attributes_done) {
1972 1972
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1973 1973
              readAttributes();
1974 1974
              attributes_done = true;
1975 1975
            }
1976 1976
          } else {
1977 1977
            readLine();
1978 1978
            skipSection();
1979 1979
          }
1980 1980
        } catch (DataFormatError& error) {
1981 1981
          error.line(line_num);
1982 1982
          throw;
1983 1983
        }
1984 1984
      }
1985 1985

	
1986 1986
      if (!nodes_done) {
1987 1987
        throw DataFormatError("Section @nodes not found");
1988 1988
      }
1989 1989

	
1990 1990
      if (!edges_done) {
1991 1991
        throw DataFormatError("Section @edges not found");
1992 1992
      }
1993 1993

	
1994 1994
      if (!attributes_done && !_attributes.empty()) {
1995 1995
        throw DataFormatError("Section @attributes not found");
1996 1996
      }
1997 1997

	
1998 1998
    }
1999 1999

	
2000 2000
    /// @}
2001 2001

	
2002 2002
  };
2003 2003

	
2004 2004
  /// \brief Return a \ref GraphReader class
2005 2005
  ///
2006 2006
  /// This function just returns a \ref GraphReader class.
2007 2007
  /// \relates GraphReader
2008 2008
  template <typename Graph>
2009 2009
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
2010 2010
    GraphReader<Graph> tmp(is, graph);
2011 2011
    return tmp;
2012 2012
  }
2013 2013

	
2014 2014
  /// \brief Return a \ref GraphReader class
2015 2015
  ///
2016 2016
  /// This function just returns a \ref GraphReader class.
2017 2017
  /// \relates GraphReader
2018 2018
  template <typename Graph>
2019 2019
  GraphReader<Graph> graphReader(const std::string& fn,
2020 2020
                                       Graph& graph) {
2021 2021
    GraphReader<Graph> tmp(fn, graph);
2022 2022
    return tmp;
2023 2023
  }
2024 2024

	
2025 2025
  /// \brief Return a \ref GraphReader class
2026 2026
  ///
2027 2027
  /// This function just returns a \ref GraphReader class.
2028 2028
  /// \relates GraphReader
2029 2029
  template <typename Graph>
2030 2030
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
2031 2031
    GraphReader<Graph> tmp(fn, graph);
2032 2032
    return tmp;
2033 2033
  }
2034 2034

	
2035 2035
  class SectionReader;
2036 2036

	
2037 2037
  SectionReader sectionReader(std::istream& is);
2038 2038
  SectionReader sectionReader(const std::string& fn);
2039 2039
  SectionReader sectionReader(const char* fn);
2040 2040

	
2041 2041
  /// \ingroup lemon_io
2042 2042
  ///
2043 2043
  /// \brief Section reader class
2044 2044
  ///
2045 2045
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2046 2046
  /// which contain any data in arbitrary format. Such sections can be
2047 2047
  /// read with this class. A reading rule can be added to the class
2048 2048
  /// with two different functions. With the \c sectionLines() function a
2049 2049
  /// functor can process the section line-by-line, while with the \c
2050 2050
  /// sectionStream() member the section can be read from an input
2051 2051
  /// stream.
2052 2052
  class SectionReader {
2053 2053
  private:
2054 2054

	
2055 2055
    std::istream* _is;
2056 2056
    bool local_is;
2057 2057

	
2058 2058
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2059 2059
    Sections _sections;
2060 2060

	
2061 2061
    int line_num;
2062 2062
    std::istringstream line;
2063 2063

	
2064 2064
  public:
2065 2065

	
2066 2066
    /// \brief Constructor
2067 2067
    ///
2068 2068
    /// Construct a section reader, which reads from the given input
2069 2069
    /// stream.
2070 2070
    SectionReader(std::istream& is)
2071 2071
      : _is(&is), local_is(false) {}
2072 2072

	
2073 2073
    /// \brief Constructor
2074 2074
    ///
2075 2075
    /// Construct a section reader, which reads from the given file.
2076 2076
    SectionReader(const std::string& fn)
2077 2077
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2078 2078

	
2079 2079
    /// \brief Constructor
2080 2080
    ///
2081 2081
    /// Construct a section reader, which reads from the given file.
2082 2082
    SectionReader(const char* fn)
2083 2083
      : _is(new std::ifstream(fn)), local_is(true) {}
2084 2084

	
2085 2085
    /// \brief Destructor
2086 2086
    ~SectionReader() {
2087 2087
      for (Sections::iterator it = _sections.begin();
2088 2088
           it != _sections.end(); ++it) {
2089 2089
        delete it->second;
2090 2090
      }
2091 2091

	
2092 2092
      if (local_is) {
2093 2093
        delete _is;
2094 2094
      }
2095 2095

	
2096 2096
    }
2097 2097

	
2098 2098
  private:
2099 2099

	
2100 2100
    friend SectionReader sectionReader(std::istream& is);
2101 2101
    friend SectionReader sectionReader(const std::string& fn);
2102 2102
    friend SectionReader sectionReader(const char* fn);
2103 2103

	
2104 2104
    SectionReader(SectionReader& other)
2105 2105
      : _is(other._is), local_is(other.local_is) {
2106 2106

	
2107 2107
      other._is = 0;
2108 2108
      other.local_is = false;
2109 2109

	
2110 2110
      _sections.swap(other._sections);
2111 2111
    }
2112 2112

	
2113 2113
    SectionReader& operator=(const SectionReader&);
2114 2114

	
2115 2115
  public:
2116 2116

	
2117 2117
    /// \name Section readers
2118 2118
    /// @{
2119 2119

	
2120 2120
    /// \brief Add a section processor with line oriented reading
2121 2121
    ///
2122 2122
    /// The first parameter is the type descriptor of the section, the
2123 2123
    /// second is a functor, which takes just one \c std::string
2124 2124
    /// parameter. At the reading process, each line of the section
2125 2125
    /// will be given to the functor object. However, the empty lines
2126 2126
    /// and the comment lines are filtered out, and the leading
2127 2127
    /// whitespaces are trimmed from each processed string.
2128 2128
    ///
2129 2129
    /// For example let's see a section, which contain several
2130 2130
    /// integers, which should be inserted into a vector.
2131 2131
    ///\code
2132 2132
    ///  @numbers
2133 2133
    ///  12 45 23
2134 2134
    ///  4
2135 2135
    ///  23 6
2136 2136
    ///\endcode
2137 2137
    ///
2138 2138
    /// The functor is implemented as a struct:
2139 2139
    ///\code
2140 2140
    ///  struct NumberSection {
2141 2141
    ///    std::vector<int>& _data;
2142 2142
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2143 2143
    ///    void operator()(const std::string& line) {
2144 2144
    ///      std::istringstream ls(line);
2145 2145
    ///      int value;
2146 2146
    ///      while (ls >> value) _data.push_back(value);
2147 2147
    ///    }
2148 2148
    ///  };
2149 2149
    ///
2150 2150
    ///  // ...
2151 2151
    ///
2152 2152
    ///  reader.sectionLines("numbers", NumberSection(vec));
2153 2153
    ///\endcode
2154 2154
    template <typename Functor>
2155 2155
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2156 2156
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2157 2157
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2158 2158
                   "Multiple reading of section.");
2159 2159
      _sections.insert(std::make_pair(type,
2160 2160
        new _reader_bits::LineSection<Functor>(functor)));
2161 2161
      return *this;
2162 2162
    }
2163 2163

	
2164 2164

	
2165 2165
    /// \brief Add a section processor with stream oriented reading
2166 2166
    ///
2167 2167
    /// The first parameter is the type of the section, the second is
2168 2168
    /// a functor, which takes an \c std::istream& and an \c int&
2169 2169
    /// parameter, the latter regard to the line number of stream. The
2170 2170
    /// functor can read the input while the section go on, and the
2171 2171
    /// line number should be modified accordingly.
2172 2172
    template <typename Functor>
2173 2173
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2174 2174
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2175 2175
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2176 2176
                   "Multiple reading of section.");
2177 2177
      _sections.insert(std::make_pair(type,
2178 2178
         new _reader_bits::StreamSection<Functor>(functor)));
2179 2179
      return *this;
2180 2180
    }
2181 2181

	
2182 2182
    /// @}
2183 2183

	
2184 2184
  private:
2185 2185

	
2186 2186
    bool readLine() {
2187 2187
      std::string str;
2188 2188
      while(++line_num, std::getline(*_is, str)) {
2189 2189
        line.clear(); line.str(str);
2190 2190
        char c;
2191 2191
        if (line >> std::ws >> c && c != '#') {
2192 2192
          line.putback(c);
2193 2193
          return true;
2194 2194
        }
2195 2195
      }
2196 2196
      return false;
2197 2197
    }
2198 2198

	
2199 2199
    bool readSuccess() {
2200 2200
      return static_cast<bool>(*_is);
2201 2201
    }
2202 2202

	
2203 2203
    void skipSection() {
2204 2204
      char c;
2205 2205
      while (readSuccess() && line >> c && c != '@') {
2206 2206
        readLine();
2207 2207
      }
2208 2208
      line.putback(c);
2209 2209
    }
2210 2210

	
2211 2211
  public:
2212 2212

	
2213 2213

	
2214 2214
    /// \name Execution of the reader
2215 2215
    /// @{
2216 2216

	
2217 2217
    /// \brief Start the batch processing
2218 2218
    ///
2219 2219
    /// This function starts the batch processing.
2220 2220
    void run() {
2221 2221

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

	
2224 2224
      std::set<std::string> extra_sections;
2225 2225

	
2226 2226
      line_num = 0;
2227 2227
      readLine();
2228 2228
      skipSection();
2229 2229

	
2230 2230
      while (readSuccess()) {
2231 2231
        try {
2232 2232
          char c;
2233 2233
          std::string section, caption;
2234 2234
          line >> c;
2235 2235
          _reader_bits::readToken(line, section);
2236 2236
          _reader_bits::readToken(line, caption);
2237 2237

	
2238 2238
          if (line >> c)
2239 2239
            throw DataFormatError("Extra character on the end of line");
2240 2240

	
2241 2241
          if (extra_sections.find(section) != extra_sections.end()) {
2242 2242
            std::ostringstream msg;
2243 2243
            msg << "Multiple occurence of section " << section;
2244 2244
            throw DataFormatError(msg.str().c_str());
2245 2245
          }
2246 2246
          Sections::iterator it = _sections.find(section);
2247 2247
          if (it != _sections.end()) {
2248 2248
            extra_sections.insert(section);
2249 2249
            it->second->process(*_is, line_num);
2250 2250
          }
2251 2251
          readLine();
2252 2252
          skipSection();
2253 2253
        } catch (DataFormatError& error) {
2254 2254
          error.line(line_num);
2255 2255
          throw;
2256 2256
        }
2257 2257
      }
2258 2258
      for (Sections::iterator it = _sections.begin();
2259 2259
           it != _sections.end(); ++it) {
2260 2260
        if (extra_sections.find(it->first) == extra_sections.end()) {
2261 2261
          std::ostringstream os;
2262 2262
          os << "Cannot find section: " << it->first;
2263 2263
          throw DataFormatError(os.str().c_str());
2264 2264
        }
2265 2265
      }
2266 2266
    }
2267 2267

	
2268 2268
    /// @}
2269 2269

	
2270 2270
  };
2271 2271

	
2272 2272
  /// \brief Return a \ref SectionReader class
2273 2273
  ///
2274 2274
  /// This function just returns a \ref SectionReader class.
2275 2275
  /// \relates SectionReader
2276 2276
  inline SectionReader sectionReader(std::istream& is) {
2277 2277
    SectionReader tmp(is);
2278 2278
    return tmp;
2279 2279
  }
2280 2280

	
2281 2281
  /// \brief Return a \ref SectionReader class
2282 2282
  ///
2283 2283
  /// This function just returns a \ref SectionReader class.
2284 2284
  /// \relates SectionReader
2285 2285
  inline SectionReader sectionReader(const std::string& fn) {
2286 2286
    SectionReader tmp(fn);
2287 2287
    return tmp;
2288 2288
  }
2289 2289

	
2290 2290
  /// \brief Return a \ref SectionReader class
2291 2291
  ///
2292 2292
  /// This function just returns a \ref SectionReader class.
2293 2293
  /// \relates SectionReader
2294 2294
  inline SectionReader sectionReader(const char* fn) {
2295 2295
    SectionReader tmp(fn);
2296 2296
    return tmp;
2297 2297
  }
2298 2298

	
2299 2299
  /// \ingroup lemon_io
2300 2300
  ///
2301 2301
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2302 2302
  ///
2303 2303
  /// This class can be used to read the sections, the map names and
2304
  /// the attributes from a file. Usually, the Lemon programs know
2304
  /// the attributes from a file. Usually, the LEMON programs know
2305 2305
  /// that, which type of graph, which maps and which attributes
2306 2306
  /// should be read from a file, but in general tools (like glemon)
2307 2307
  /// the contents of an LGF file should be guessed somehow. This class
2308 2308
  /// reads the graph and stores the appropriate information for
2309 2309
  /// reading the graph.
2310 2310
  ///
2311 2311
  ///\code
2312 2312
  /// LgfContents contents("graph.lgf");
2313 2313
  /// contents.run();
2314 2314
  ///
2315 2315
  /// // Does it contain any node section and arc section?
2316 2316
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2317 2317
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2318 2318
  ///   return -1;
2319 2319
  /// }
2320 2320
  /// std::cout << "The name of the default node section: "
2321 2321
  ///           << contents.nodeSection(0) << std::endl;
2322 2322
  /// std::cout << "The number of the arc maps: "
2323 2323
  ///           << contents.arcMaps(0).size() << std::endl;
2324 2324
  /// std::cout << "The name of second arc map: "
2325 2325
  ///           << contents.arcMaps(0)[1] << std::endl;
2326 2326
  ///\endcode
2327 2327
  class LgfContents {
2328 2328
  private:
2329 2329

	
2330 2330
    std::istream* _is;
2331 2331
    bool local_is;
2332 2332

	
2333 2333
    std::vector<std::string> _node_sections;
2334 2334
    std::vector<std::string> _edge_sections;
2335 2335
    std::vector<std::string> _attribute_sections;
2336 2336
    std::vector<std::string> _extra_sections;
2337 2337

	
2338 2338
    std::vector<bool> _arc_sections;
2339 2339

	
2340 2340
    std::vector<std::vector<std::string> > _node_maps;
2341 2341
    std::vector<std::vector<std::string> > _edge_maps;
2342 2342

	
2343 2343
    std::vector<std::vector<std::string> > _attributes;
2344 2344

	
2345 2345

	
2346 2346
    int line_num;
2347 2347
    std::istringstream line;
2348 2348

	
2349 2349
  public:
2350 2350

	
2351 2351
    /// \brief Constructor
2352 2352
    ///
2353 2353
    /// Construct an \e LGF contents reader, which reads from the given
2354 2354
    /// input stream.
2355 2355
    LgfContents(std::istream& is)
2356 2356
      : _is(&is), local_is(false) {}
2357 2357

	
2358 2358
    /// \brief Constructor
2359 2359
    ///
2360 2360
    /// Construct an \e LGF contents reader, which reads from the given
2361 2361
    /// file.
2362 2362
    LgfContents(const std::string& fn)
2363 2363
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2364 2364

	
2365 2365
    /// \brief Constructor
2366 2366
    ///
2367 2367
    /// Construct an \e LGF contents reader, which reads from the given
2368 2368
    /// file.
2369 2369
    LgfContents(const char* fn)
2370 2370
      : _is(new std::ifstream(fn)), local_is(true) {}
2371 2371

	
2372 2372
    /// \brief Destructor
2373 2373
    ~LgfContents() {
2374 2374
      if (local_is) delete _is;
2375 2375
    }
2376 2376

	
2377 2377
  private:
2378 2378

	
2379 2379
    LgfContents(const LgfContents&);
2380 2380
    LgfContents& operator=(const LgfContents&);
2381 2381

	
2382 2382
  public:
2383 2383

	
2384 2384

	
2385 2385
    /// \name Node sections
2386 2386
    /// @{
2387 2387

	
2388 2388
    /// \brief Gives back the number of node sections in the file.
2389 2389
    ///
2390 2390
    /// Gives back the number of node sections in the file.
2391 2391
    int nodeSectionNum() const {
2392 2392
      return _node_sections.size();
2393 2393
    }
2394 2394

	
2395 2395
    /// \brief Returns the node section name at the given position.
2396 2396
    ///
2397 2397
    /// Returns the node section name at the given position.
2398 2398
    const std::string& nodeSection(int i) const {
2399 2399
      return _node_sections[i];
2400 2400
    }
2401 2401

	
2402 2402
    /// \brief Gives back the node maps for the given section.
2403 2403
    ///
2404 2404
    /// Gives back the node maps for the given section.
2405 2405
    const std::vector<std::string>& nodeMapNames(int i) const {
2406 2406
      return _node_maps[i];
2407 2407
    }
2408 2408

	
2409 2409
    /// @}
2410 2410

	
2411 2411
    /// \name Arc/Edge sections
2412 2412
    /// @{
2413 2413

	
2414 2414
    /// \brief Gives back the number of arc/edge sections in the file.
2415 2415
    ///
2416 2416
    /// Gives back the number of arc/edge sections in the file.
2417 2417
    /// \note It is synonym of \c edgeSectionNum().
2418 2418
    int arcSectionNum() const {
2419 2419
      return _edge_sections.size();
2420 2420
    }
2421 2421

	
2422 2422
    /// \brief Returns the arc/edge section name at the given position.
2423 2423
    ///
2424 2424
    /// Returns the arc/edge section name at the given position.
2425 2425
    /// \note It is synonym of \c edgeSection().
2426 2426
    const std::string& arcSection(int i) const {
2427 2427
      return _edge_sections[i];
2428 2428
    }
2429 2429

	
2430 2430
    /// \brief Gives back the arc/edge maps for the given section.
2431 2431
    ///
2432 2432
    /// Gives back the arc/edge maps for the given section.
2433 2433
    /// \note It is synonym of \c edgeMapNames().
2434 2434
    const std::vector<std::string>& arcMapNames(int i) const {
2435 2435
      return _edge_maps[i];
2436 2436
    }
2437 2437

	
2438 2438
    /// @}
2439 2439

	
2440 2440
    /// \name Synonyms
2441 2441
    /// @{
2442 2442

	
2443 2443
    /// \brief Gives back the number of arc/edge sections in the file.
2444 2444
    ///
2445 2445
    /// Gives back the number of arc/edge sections in the file.
2446 2446
    /// \note It is synonym of \c arcSectionNum().
2447 2447
    int edgeSectionNum() const {
2448 2448
      return _edge_sections.size();
2449 2449
    }
2450 2450

	
2451 2451
    /// \brief Returns the section name at the given position.
2452 2452
    ///
2453 2453
    /// Returns the section name at the given position.
2454 2454
    /// \note It is synonym of \c arcSection().
2455 2455
    const std::string& edgeSection(int i) const {
2456 2456
      return _edge_sections[i];
2457 2457
    }
2458 2458

	
2459 2459
    /// \brief Gives back the edge maps for the given section.
2460 2460
    ///
2461 2461
    /// Gives back the edge maps for the given section.
2462 2462
    /// \note It is synonym of \c arcMapNames().
2463 2463
    const std::vector<std::string>& edgeMapNames(int i) const {
2464 2464
      return _edge_maps[i];
2465 2465
    }
2466 2466

	
2467 2467
    /// @}
2468 2468

	
2469 2469
    /// \name Attribute sections
2470 2470
    /// @{
2471 2471

	
2472 2472
    /// \brief Gives back the number of attribute sections in the file.
2473 2473
    ///
2474 2474
    /// Gives back the number of attribute sections in the file.
2475 2475
    int attributeSectionNum() const {
2476 2476
      return _attribute_sections.size();
2477 2477
    }
2478 2478

	
2479 2479
    /// \brief Returns the attribute section name at the given position.
2480 2480
    ///
2481 2481
    /// Returns the attribute section name at the given position.
2482 2482
    const std::string& attributeSectionNames(int i) const {
2483 2483
      return _attribute_sections[i];
2484 2484
    }
2485 2485

	
2486 2486
    /// \brief Gives back the attributes for the given section.
2487 2487
    ///
2488 2488
    /// Gives back the attributes for the given section.
2489 2489
    const std::vector<std::string>& attributes(int i) const {
2490 2490
      return _attributes[i];
2491 2491
    }
2492 2492

	
2493 2493
    /// @}
2494 2494

	
2495 2495
    /// \name Extra sections
2496 2496
    /// @{
2497 2497

	
2498 2498
    /// \brief Gives back the number of extra sections in the file.
2499 2499
    ///
2500 2500
    /// Gives back the number of extra sections in the file.
2501 2501
    int extraSectionNum() const {
2502 2502
      return _extra_sections.size();
2503 2503
    }
2504 2504

	
2505 2505
    /// \brief Returns the extra section type at the given position.
2506 2506
    ///
2507 2507
    /// Returns the section type at the given position.
2508 2508
    const std::string& extraSection(int i) const {
2509 2509
      return _extra_sections[i];
2510 2510
    }
2511 2511

	
2512 2512
    /// @}
2513 2513

	
2514 2514
  private:
2515 2515

	
2516 2516
    bool readLine() {
2517 2517
      std::string str;
2518 2518
      while(++line_num, std::getline(*_is, str)) {
2519 2519
        line.clear(); line.str(str);
2520 2520
        char c;
2521 2521
        if (line >> std::ws >> c && c != '#') {
2522 2522
          line.putback(c);
2523 2523
          return true;
2524 2524
        }
2525 2525
      }
2526 2526
      return false;
2527 2527
    }
2528 2528

	
2529 2529
    bool readSuccess() {
2530 2530
      return static_cast<bool>(*_is);
2531 2531
    }
2532 2532

	
2533 2533
    void skipSection() {
2534 2534
      char c;
2535 2535
      while (readSuccess() && line >> c && c != '@') {
2536 2536
        readLine();
2537 2537
      }
2538 2538
      line.putback(c);
2539 2539
    }
2540 2540

	
2541 2541
    void readMaps(std::vector<std::string>& maps) {
2542 2542
      char c;
2543 2543
      if (!readLine() || !(line >> c) || c == '@') {
2544 2544
        if (readSuccess() && line) line.putback(c);
2545 2545
        return;
2546 2546
      }
2547 2547
      line.putback(c);
2548 2548
      std::string map;
2549 2549
      while (_reader_bits::readToken(line, map)) {
2550 2550
        maps.push_back(map);
2551 2551
      }
2552 2552
    }
2553 2553

	
2554 2554
    void readAttributes(std::vector<std::string>& attrs) {
2555 2555
      readLine();
2556 2556
      char c;
2557 2557
      while (readSuccess() && line >> c && c != '@') {
2558 2558
        line.putback(c);
2559 2559
        std::string attr;
2560 2560
        _reader_bits::readToken(line, attr);
2561 2561
        attrs.push_back(attr);
2562 2562
        readLine();
2563 2563
      }
2564 2564
      line.putback(c);
2565 2565
    }
2566 2566

	
2567 2567
  public:
2568 2568

	
2569 2569
    /// \name Execution of the contents reader
2570 2570
    /// @{
2571 2571

	
2572 2572
    /// \brief Starts the reading
2573 2573
    ///
2574 2574
    /// This function starts the reading.
2575 2575
    void run() {
2576 2576

	
2577 2577
      readLine();
2578 2578
      skipSection();
2579 2579

	
2580 2580
      while (readSuccess()) {
2581 2581

	
2582 2582
        char c;
2583 2583
        line >> c;
2584 2584

	
2585 2585
        std::string section, caption;
2586 2586
        _reader_bits::readToken(line, section);
2587 2587
        _reader_bits::readToken(line, caption);
2588 2588

	
2589 2589
        if (section == "nodes") {
2590 2590
          _node_sections.push_back(caption);
2591 2591
          _node_maps.push_back(std::vector<std::string>());
2592 2592
          readMaps(_node_maps.back());
2593 2593
          readLine(); skipSection();
2594 2594
        } else if (section == "arcs" || section == "edges") {
2595 2595
          _edge_sections.push_back(caption);
2596 2596
          _arc_sections.push_back(section == "arcs");
2597 2597
          _edge_maps.push_back(std::vector<std::string>());
2598 2598
          readMaps(_edge_maps.back());
2599 2599
          readLine(); skipSection();
2600 2600
        } else if (section == "attributes") {
2601 2601
          _attribute_sections.push_back(caption);
2602 2602
          _attributes.push_back(std::vector<std::string>());
2603 2603
          readAttributes(_attributes.back());
2604 2604
        } else {
2605 2605
          _extra_sections.push_back(section);
2606 2606
          readLine(); skipSection();
2607 2607
        }
2608 2608
      }
2609 2609
    }
2610 2610

	
2611 2611
    /// @}
2612 2612

	
2613 2613
  };
2614 2614
}
2615 2615

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

	
19 19
///\ingroup lemon_io
20 20
///\file
21
///\brief \ref lgf-format "Lemon Graph Format" writer.
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/assert.h>
37 37
#include <lemon/core.h>
38 38
#include <lemon/maps.h>
39 39

	
40 40
namespace lemon {
41 41

	
42 42
  namespace _writer_bits {
43 43

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

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

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

	
64 64
    private:
65 65
      const Map& _map;
66 66

	
67 67
    public:
68 68
      MapLess(const Map& map) : _map(map) {}
69 69

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

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

	
82 82
    private:
83 83
      const Graph& _graph;
84 84
      const Map& _map;
85 85

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

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

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

	
101 101
    public:
102 102
      MapStorageBase() {}
103 103
      virtual ~MapStorageBase() {}
104 104

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

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

	
117 117
    private:
118 118
      const Map& _map;
119 119
      Converter _converter;
120 120

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

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

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

	
145 145
    private:
146 146
      const Graph& _graph;
147 147
      const Map& _map;
148 148
      Converter _converter;
149 149

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

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

	
165 165
    class ValueStorageBase {
166 166
    public:
167 167
      ValueStorageBase() {}
168 168
      virtual ~ValueStorageBase() {}
169 169

	
170 170
      virtual std::string get() = 0;
171 171
    };
172 172

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

	
179 179
    private:
180 180
      const Value& _value;
181 181
      Converter _converter;
182 182

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

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

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

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

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

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

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

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

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

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

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

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

	
292 292
    inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
293 293

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

	
307 307
  }
308 308

	
309 309
  template <typename Digraph>
310 310
  class DigraphWriter;
311 311

	
312 312
  template <typename Digraph>
313 313
  DigraphWriter<Digraph> digraphWriter(std::ostream& os,
314 314
                                       const Digraph& digraph);
315 315

	
316 316
  template <typename Digraph>
317 317
  DigraphWriter<Digraph> digraphWriter(const std::string& fn,
318 318
                                       const Digraph& digraph);
319 319

	
320 320
  template <typename Digraph>
321 321
  DigraphWriter<Digraph> digraphWriter(const char *fn,
322 322
                                       const Digraph& digraph);
323 323

	
324 324
  /// \ingroup lemon_io
325 325
  ///
326 326
  /// \brief \ref lgf-format "LGF" writer for directed graphs
327 327
  ///
328 328
  /// This utility writes an \ref lgf-format "LGF" file.
329 329
  ///
330 330
  /// The writing method does a batch processing. The user creates a
331 331
  /// writer object, then various writing rules can be added to the
332 332
  /// writer, and eventually the writing is executed with the \c run()
333 333
  /// member function. A map writing rule can be added to the writer
334 334
  /// with the \c nodeMap() or \c arcMap() members. An optional
335 335
  /// converter parameter can also be added as a standard functor
336 336
  /// converting from the value type of the map to \c std::string. If it
337 337
  /// is set, it will determine how the value type of the map is written to
338 338
  /// the output stream. If the functor is not set, then a default
339 339
  /// conversion will be used. The \c attribute(), \c node() and \c
340 340
  /// arc() functions are used to add attribute writing rules.
341 341
  ///
342 342
  ///\code
343 343
  /// DigraphWriter<Digraph>(std::cout, digraph).
344 344
  ///   nodeMap("coordinates", coord_map).
345 345
  ///   nodeMap("size", size).
346 346
  ///   nodeMap("title", title).
347 347
  ///   arcMap("capacity", cap_map).
348 348
  ///   node("source", src).
349 349
  ///   node("target", trg).
350 350
  ///   attribute("caption", caption).
351 351
  ///   run();
352 352
  ///\endcode
353 353
  ///
354 354
  ///
355 355
  /// By default, the writer does not write additional captions to the
356 356
  /// sections, but they can be give as an optional parameter of
357 357
  /// the \c nodes(), \c arcs() or \c
358 358
  /// attributes() functions.
359 359
  ///
360 360
  /// The \c skipNodes() and \c skipArcs() functions forbid the
361 361
  /// writing of the sections. If two arc sections should be written
362 362
  /// to the output, it can be done in two passes, the first pass
363 363
  /// writes the node section and the first arc section, then the
364 364
  /// second pass skips the node section and writes just the arc
365 365
  /// section to the stream. The output stream can be retrieved with
366 366
  /// the \c ostream() function, hence the second pass can append its
367 367
  /// output to the output of the first pass.
368 368
  template <typename _Digraph>
369 369
  class DigraphWriter {
370 370
  public:
371 371

	
372 372
    typedef _Digraph Digraph;
373 373
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
374 374

	
375 375
  private:
376 376

	
377 377

	
378 378
    std::ostream* _os;
379 379
    bool local_os;
380 380

	
381 381
    const Digraph& _digraph;
382 382

	
383 383
    std::string _nodes_caption;
384 384
    std::string _arcs_caption;
385 385
    std::string _attributes_caption;
386 386

	
387 387
    typedef std::map<Node, std::string> NodeIndex;
388 388
    NodeIndex _node_index;
389 389
    typedef std::map<Arc, std::string> ArcIndex;
390 390
    ArcIndex _arc_index;
391 391

	
392 392
    typedef std::vector<std::pair<std::string,
393 393
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
394 394
    NodeMaps _node_maps;
395 395

	
396 396
    typedef std::vector<std::pair<std::string,
397 397
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
398 398
    ArcMaps _arc_maps;
399 399

	
400 400
    typedef std::vector<std::pair<std::string,
401 401
      _writer_bits::ValueStorageBase*> > Attributes;
402 402
    Attributes _attributes;
403 403

	
404 404
    bool _skip_nodes;
405 405
    bool _skip_arcs;
406 406

	
407 407
  public:
408 408

	
409 409
    /// \brief Constructor
410 410
    ///
411 411
    /// Construct a directed graph writer, which writes to the given
412 412
    /// output stream.
413 413
    DigraphWriter(std::ostream& is, const Digraph& digraph)
414 414
      : _os(&is), local_os(false), _digraph(digraph),
415 415
        _skip_nodes(false), _skip_arcs(false) {}
416 416

	
417 417
    /// \brief Constructor
418 418
    ///
419 419
    /// Construct a directed graph writer, which writes to the given
420 420
    /// output file.
421 421
    DigraphWriter(const std::string& fn, const Digraph& digraph)
422 422
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
423 423
        _skip_nodes(false), _skip_arcs(false) {}
424 424

	
425 425
    /// \brief Constructor
426 426
    ///
427 427
    /// Construct a directed graph writer, which writes to the given
428 428
    /// output file.
429 429
    DigraphWriter(const char* fn, const Digraph& digraph)
430 430
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
431 431
        _skip_nodes(false), _skip_arcs(false) {}
432 432

	
433 433
    /// \brief Destructor
434 434
    ~DigraphWriter() {
435 435
      for (typename NodeMaps::iterator it = _node_maps.begin();
436 436
           it != _node_maps.end(); ++it) {
437 437
        delete it->second;
438 438
      }
439 439

	
440 440
      for (typename ArcMaps::iterator it = _arc_maps.begin();
441 441
           it != _arc_maps.end(); ++it) {
442 442
        delete it->second;
443 443
      }
444 444

	
445 445
      for (typename Attributes::iterator it = _attributes.begin();
446 446
           it != _attributes.end(); ++it) {
447 447
        delete it->second;
448 448
      }
449 449

	
450 450
      if (local_os) {
451 451
        delete _os;
452 452
      }
453 453
    }
454 454

	
455 455
  private:
456 456

	
457 457
    friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os,
458 458
                                                  const Digraph& digraph);
459 459
    friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn,
460 460
                                                  const Digraph& digraph);
461 461
    friend DigraphWriter<Digraph> digraphWriter<>(const char *fn,
462 462
                                                  const Digraph& digraph);
463 463

	
464 464
    DigraphWriter(DigraphWriter& other)
465 465
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
466 466
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
467 467

	
468 468
      other._os = 0;
469 469
      other.local_os = false;
470 470

	
471 471
      _node_index.swap(other._node_index);
472 472
      _arc_index.swap(other._arc_index);
473 473

	
474 474
      _node_maps.swap(other._node_maps);
475 475
      _arc_maps.swap(other._arc_maps);
476 476
      _attributes.swap(other._attributes);
477 477

	
478 478
      _nodes_caption = other._nodes_caption;
479 479
      _arcs_caption = other._arcs_caption;
480 480
      _attributes_caption = other._attributes_caption;
481 481
    }
482 482

	
483 483
    DigraphWriter& operator=(const DigraphWriter&);
484 484

	
485 485
  public:
486 486

	
487 487
    /// \name Writing rules
488 488
    /// @{
489 489

	
490 490
    /// \brief Node map writing rule
491 491
    ///
492 492
    /// Add a node map writing rule to the writer.
493 493
    template <typename Map>
494 494
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
495 495
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
496 496
      _writer_bits::MapStorageBase<Node>* storage =
497 497
        new _writer_bits::MapStorage<Node, Map>(map);
498 498
      _node_maps.push_back(std::make_pair(caption, storage));
499 499
      return *this;
500 500
    }
501 501

	
502 502
    /// \brief Node map writing rule
503 503
    ///
504 504
    /// Add a node map writing rule with specialized converter to the
505 505
    /// writer.
506 506
    template <typename Map, typename Converter>
507 507
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
508 508
                           const Converter& converter = Converter()) {
509 509
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
510 510
      _writer_bits::MapStorageBase<Node>* storage =
511 511
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
512 512
      _node_maps.push_back(std::make_pair(caption, storage));
513 513
      return *this;
514 514
    }
515 515

	
516 516
    /// \brief Arc map writing rule
517 517
    ///
518 518
    /// Add an arc map writing rule to the writer.
519 519
    template <typename Map>
520 520
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
521 521
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
522 522
      _writer_bits::MapStorageBase<Arc>* storage =
523 523
        new _writer_bits::MapStorage<Arc, Map>(map);
524 524
      _arc_maps.push_back(std::make_pair(caption, storage));
525 525
      return *this;
526 526
    }
527 527

	
528 528
    /// \brief Arc map writing rule
529 529
    ///
530 530
    /// Add an arc map writing rule with specialized converter to the
531 531
    /// writer.
532 532
    template <typename Map, typename Converter>
533 533
    DigraphWriter& arcMap(const std::string& caption, const Map& map,
534 534
                          const Converter& converter = Converter()) {
535 535
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
536 536
      _writer_bits::MapStorageBase<Arc>* storage =
537 537
        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
538 538
      _arc_maps.push_back(std::make_pair(caption, storage));
539 539
      return *this;
540 540
    }
541 541

	
542 542
    /// \brief Attribute writing rule
543 543
    ///
544 544
    /// Add an attribute writing rule to the writer.
545 545
    template <typename Value>
546 546
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
547 547
      _writer_bits::ValueStorageBase* storage =
548 548
        new _writer_bits::ValueStorage<Value>(value);
549 549
      _attributes.push_back(std::make_pair(caption, storage));
550 550
      return *this;
551 551
    }
552 552

	
553 553
    /// \brief Attribute writing rule
554 554
    ///
555 555
    /// Add an attribute writing rule with specialized converter to the
556 556
    /// writer.
557 557
    template <typename Value, typename Converter>
558 558
    DigraphWriter& attribute(const std::string& caption, const Value& value,
559 559
                             const Converter& converter = Converter()) {
560 560
      _writer_bits::ValueStorageBase* storage =
561 561
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
562 562
      _attributes.push_back(std::make_pair(caption, storage));
563 563
      return *this;
564 564
    }
565 565

	
566 566
    /// \brief Node writing rule
567 567
    ///
568 568
    /// Add a node writing rule to the writer.
569 569
    DigraphWriter& node(const std::string& caption, const Node& node) {
570 570
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
571 571
      Converter converter(_node_index);
572 572
      _writer_bits::ValueStorageBase* storage =
573 573
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
574 574
      _attributes.push_back(std::make_pair(caption, storage));
575 575
      return *this;
576 576
    }
577 577

	
578 578
    /// \brief Arc writing rule
579 579
    ///
580 580
    /// Add an arc writing rule to writer.
581 581
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
582 582
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
583 583
      Converter converter(_arc_index);
584 584
      _writer_bits::ValueStorageBase* storage =
585 585
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
586 586
      _attributes.push_back(std::make_pair(caption, storage));
587 587
      return *this;
588 588
    }
589 589

	
590 590
    /// \name Section captions
591 591
    /// @{
592 592

	
593 593
    /// \brief Add an additional caption to the \c \@nodes section
594 594
    ///
595 595
    /// Add an additional caption to the \c \@nodes section.
596 596
    DigraphWriter& nodes(const std::string& caption) {
597 597
      _nodes_caption = caption;
598 598
      return *this;
599 599
    }
600 600

	
601 601
    /// \brief Add an additional caption to the \c \@arcs section
602 602
    ///
603 603
    /// Add an additional caption to the \c \@arcs section.
604 604
    DigraphWriter& arcs(const std::string& caption) {
605 605
      _arcs_caption = caption;
606 606
      return *this;
607 607
    }
608 608

	
609 609
    /// \brief Add an additional caption to the \c \@attributes section
610 610
    ///
611 611
    /// Add an additional caption to the \c \@attributes section.
612 612
    DigraphWriter& attributes(const std::string& caption) {
613 613
      _attributes_caption = caption;
614 614
      return *this;
615 615
    }
616 616

	
617 617
    /// \name Skipping section
618 618
    /// @{
619 619

	
620 620
    /// \brief Skip writing the node set
621 621
    ///
622 622
    /// The \c \@nodes section will not be written to the stream.
623 623
    DigraphWriter& skipNodes() {
624 624
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
625 625
      _skip_nodes = true;
626 626
      return *this;
627 627
    }
628 628

	
629 629
    /// \brief Skip writing arc set
630 630
    ///
631 631
    /// The \c \@arcs section will not be written to the stream.
632 632
    DigraphWriter& skipArcs() {
633 633
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
634 634
      _skip_arcs = true;
635 635
      return *this;
636 636
    }
637 637

	
638 638
    /// @}
639 639

	
640 640
  private:
641 641

	
642 642
    void writeNodes() {
643 643
      _writer_bits::MapStorageBase<Node>* label = 0;
644 644
      for (typename NodeMaps::iterator it = _node_maps.begin();
645 645
           it != _node_maps.end(); ++it) {
646 646
        if (it->first == "label") {
647 647
          label = it->second;
648 648
          break;
649 649
        }
650 650
      }
651 651

	
652 652
      *_os << "@nodes";
653 653
      if (!_nodes_caption.empty()) {
654 654
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
655 655
      }
656 656
      *_os << std::endl;
657 657

	
658 658
      if (label == 0) {
659 659
        *_os << "label" << '\t';
660 660
      }
661 661
      for (typename NodeMaps::iterator it = _node_maps.begin();
662 662
           it != _node_maps.end(); ++it) {
663 663
        _writer_bits::writeToken(*_os, it->first) << '\t';
664 664
      }
665 665
      *_os << std::endl;
666 666

	
667 667
      std::vector<Node> nodes;
668 668
      for (NodeIt n(_digraph); n != INVALID; ++n) {
669 669
        nodes.push_back(n);
670 670
      }
671 671

	
672 672
      if (label == 0) {
673 673
        IdMap<Digraph, Node> id_map(_digraph);
674 674
        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
675 675
        std::sort(nodes.begin(), nodes.end(), id_less);
676 676
      } else {
677 677
        label->sort(nodes);
678 678
      }
679 679

	
680 680
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
681 681
        Node n = nodes[i];
682 682
        if (label == 0) {
683 683
          std::ostringstream os;
684 684
          os << _digraph.id(n);
685 685
          _writer_bits::writeToken(*_os, os.str());
686 686
          *_os << '\t';
687 687
          _node_index.insert(std::make_pair(n, os.str()));
688 688
        }
689 689
        for (typename NodeMaps::iterator it = _node_maps.begin();
690 690
             it != _node_maps.end(); ++it) {
691 691
          std::string value = it->second->get(n);
692 692
          _writer_bits::writeToken(*_os, value);
693 693
          if (it->first == "label") {
694 694
            _node_index.insert(std::make_pair(n, value));
695 695
          }
696 696
          *_os << '\t';
697 697
        }
698 698
        *_os << std::endl;
699 699
      }
700 700
    }
701 701

	
702 702
    void createNodeIndex() {
703 703
      _writer_bits::MapStorageBase<Node>* label = 0;
704 704
      for (typename NodeMaps::iterator it = _node_maps.begin();
705 705
           it != _node_maps.end(); ++it) {
706 706
        if (it->first == "label") {
707 707
          label = it->second;
708 708
          break;
709 709
        }
710 710
      }
711 711

	
712 712
      if (label == 0) {
713 713
        for (NodeIt n(_digraph); n != INVALID; ++n) {
714 714
          std::ostringstream os;
715 715
          os << _digraph.id(n);
716 716
          _node_index.insert(std::make_pair(n, os.str()));
717 717
        }
718 718
      } else {
719 719
        for (NodeIt n(_digraph); n != INVALID; ++n) {
720 720
          std::string value = label->get(n);
721 721
          _node_index.insert(std::make_pair(n, value));
722 722
        }
723 723
      }
724 724
    }
725 725

	
726 726
    void writeArcs() {
727 727
      _writer_bits::MapStorageBase<Arc>* label = 0;
728 728
      for (typename ArcMaps::iterator it = _arc_maps.begin();
729 729
           it != _arc_maps.end(); ++it) {
730 730
        if (it->first == "label") {
731 731
          label = it->second;
732 732
          break;
733 733
        }
734 734
      }
735 735

	
736 736
      *_os << "@arcs";
737 737
      if (!_arcs_caption.empty()) {
738 738
        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
739 739
      }
740 740
      *_os << std::endl;
741 741

	
742 742
      *_os << '\t' << '\t';
743 743
      if (label == 0) {
744 744
        *_os << "label" << '\t';
745 745
      }
746 746
      for (typename ArcMaps::iterator it = _arc_maps.begin();
747 747
           it != _arc_maps.end(); ++it) {
748 748
        _writer_bits::writeToken(*_os, it->first) << '\t';
749 749
      }
750 750
      *_os << std::endl;
751 751

	
752 752
      std::vector<Arc> arcs;
753 753
      for (ArcIt n(_digraph); n != INVALID; ++n) {
754 754
        arcs.push_back(n);
755 755
      }
756 756

	
757 757
      if (label == 0) {
758 758
        IdMap<Digraph, Arc> id_map(_digraph);
759 759
        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
760 760
        std::sort(arcs.begin(), arcs.end(), id_less);
761 761
      } else {
762 762
        label->sort(arcs);
763 763
      }
764 764

	
765 765
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
766 766
        Arc a = arcs[i];
767 767
        _writer_bits::writeToken(*_os, _node_index.
768 768
                                 find(_digraph.source(a))->second);
769 769
        *_os << '\t';
770 770
        _writer_bits::writeToken(*_os, _node_index.
771 771
                                 find(_digraph.target(a))->second);
772 772
        *_os << '\t';
773 773
        if (label == 0) {
774 774
          std::ostringstream os;
775 775
          os << _digraph.id(a);
776 776
          _writer_bits::writeToken(*_os, os.str());
777 777
          *_os << '\t';
778 778
          _arc_index.insert(std::make_pair(a, os.str()));
779 779
        }
780 780
        for (typename ArcMaps::iterator it = _arc_maps.begin();
781 781
             it != _arc_maps.end(); ++it) {
782 782
          std::string value = it->second->get(a);
783 783
          _writer_bits::writeToken(*_os, value);
784 784
          if (it->first == "label") {
785 785
            _arc_index.insert(std::make_pair(a, value));
786 786
          }
787 787
          *_os << '\t';
788 788
        }
789 789
        *_os << std::endl;
790 790
      }
791 791
    }
792 792

	
793 793
    void createArcIndex() {
794 794
      _writer_bits::MapStorageBase<Arc>* label = 0;
795 795
      for (typename ArcMaps::iterator it = _arc_maps.begin();
796 796
           it != _arc_maps.end(); ++it) {
797 797
        if (it->first == "label") {
798 798
          label = it->second;
799 799
          break;
800 800
        }
801 801
      }
802 802

	
803 803
      if (label == 0) {
804 804
        for (ArcIt a(_digraph); a != INVALID; ++a) {
805 805
          std::ostringstream os;
806 806
          os << _digraph.id(a);
807 807
          _arc_index.insert(std::make_pair(a, os.str()));
808 808
        }
809 809
      } else {
810 810
        for (ArcIt a(_digraph); a != INVALID; ++a) {
811 811
          std::string value = label->get(a);
812 812
          _arc_index.insert(std::make_pair(a, value));
813 813
        }
814 814
      }
815 815
    }
816 816

	
817 817
    void writeAttributes() {
818 818
      if (_attributes.empty()) return;
819 819
      *_os << "@attributes";
820 820
      if (!_attributes_caption.empty()) {
821 821
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
822 822
      }
823 823
      *_os << std::endl;
824 824
      for (typename Attributes::iterator it = _attributes.begin();
825 825
           it != _attributes.end(); ++it) {
826 826
        _writer_bits::writeToken(*_os, it->first) << ' ';
827 827
        _writer_bits::writeToken(*_os, it->second->get());
828 828
        *_os << std::endl;
829 829
      }
830 830
    }
831 831

	
832 832
  public:
833 833

	
834 834
    /// \name Execution of the writer
835 835
    /// @{
836 836

	
837 837
    /// \brief Start the batch processing
838 838
    ///
839 839
    /// This function starts the batch processing.
840 840
    void run() {
841 841
      if (!_skip_nodes) {
842 842
        writeNodes();
843 843
      } else {
844 844
        createNodeIndex();
845 845
      }
846 846
      if (!_skip_arcs) {
847 847
        writeArcs();
848 848
      } else {
849 849
        createArcIndex();
850 850
      }
851 851
      writeAttributes();
852 852
    }
853 853

	
854 854
    /// \brief Give back the stream of the writer
855 855
    ///
856 856
    /// Give back the stream of the writer.
857 857
    std::ostream& ostream() {
858 858
      return *_os;
859 859
    }
860 860

	
861 861
    /// @}
862 862
  };
863 863

	
864 864
  /// \brief Return a \ref DigraphWriter class
865 865
  ///
866 866
  /// This function just returns a \ref DigraphWriter class.
867 867
  /// \relates DigraphWriter
868 868
  template <typename Digraph>
869 869
  DigraphWriter<Digraph> digraphWriter(std::ostream& os,
870 870
                                       const Digraph& digraph) {
871 871
    DigraphWriter<Digraph> tmp(os, digraph);
872 872
    return tmp;
873 873
  }
874 874

	
875 875
  /// \brief Return a \ref DigraphWriter class
876 876
  ///
877 877
  /// This function just returns a \ref DigraphWriter class.
878 878
  /// \relates DigraphWriter
879 879
  template <typename Digraph>
880 880
  DigraphWriter<Digraph> digraphWriter(const std::string& fn,
881 881
                                       const Digraph& digraph) {
882 882
    DigraphWriter<Digraph> tmp(fn, digraph);
883 883
    return tmp;
884 884
  }
885 885

	
886 886
  /// \brief Return a \ref DigraphWriter class
887 887
  ///
888 888
  /// This function just returns a \ref DigraphWriter class.
889 889
  /// \relates DigraphWriter
890 890
  template <typename Digraph>
891 891
  DigraphWriter<Digraph> digraphWriter(const char* fn,
892 892
                                       const Digraph& digraph) {
893 893
    DigraphWriter<Digraph> tmp(fn, digraph);
894 894
    return tmp;
895 895
  }
896 896

	
897 897
  template <typename Graph>
898 898
  class GraphWriter;
899 899

	
900 900
  template <typename Graph>
901 901
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);
902 902

	
903 903
  template <typename Graph>
904 904
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);
905 905

	
906 906
  template <typename Graph>
907 907
  GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);
908 908

	
909 909
  /// \ingroup lemon_io
910 910
  ///
911 911
  /// \brief \ref lgf-format "LGF" writer for directed graphs
912 912
  ///
913 913
  /// This utility writes an \ref lgf-format "LGF" file.
914 914
  ///
915 915
  /// It can be used almost the same way as \c DigraphWriter.
916 916
  /// The only difference is that this class can handle edges and
917 917
  /// edge maps as well as arcs and arc maps.
918 918
  ///
919 919
  /// The arc maps are written into the file as two columns, the
920 920
  /// caption of the columns are the name of the map prefixed with \c
921 921
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
922 922
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
923 923
  /// of the arc) and the label of corresponding edge.
924 924
  template <typename _Graph>
925 925
  class GraphWriter {
926 926
  public:
927 927

	
928 928
    typedef _Graph Graph;
929 929
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
930 930

	
931 931
  private:
932 932

	
933 933

	
934 934
    std::ostream* _os;
935 935
    bool local_os;
936 936

	
937
    Graph& _graph;
937
    const Graph& _graph;
938 938

	
939 939
    std::string _nodes_caption;
940 940
    std::string _edges_caption;
941 941
    std::string _attributes_caption;
942 942

	
943 943
    typedef std::map<Node, std::string> NodeIndex;
944 944
    NodeIndex _node_index;
945 945
    typedef std::map<Edge, std::string> EdgeIndex;
946 946
    EdgeIndex _edge_index;
947 947

	
948 948
    typedef std::vector<std::pair<std::string,
949 949
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
950 950
    NodeMaps _node_maps;
951 951

	
952 952
    typedef std::vector<std::pair<std::string,
953 953
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
954 954
    EdgeMaps _edge_maps;
955 955

	
956 956
    typedef std::vector<std::pair<std::string,
957 957
      _writer_bits::ValueStorageBase*> > Attributes;
958 958
    Attributes _attributes;
959 959

	
960 960
    bool _skip_nodes;
961 961
    bool _skip_edges;
962 962

	
963 963
  public:
964 964

	
965 965
    /// \brief Constructor
966 966
    ///
967 967
    /// Construct a directed graph writer, which writes to the given
968 968
    /// output stream.
969 969
    GraphWriter(std::ostream& is, const Graph& graph)
970 970
      : _os(&is), local_os(false), _graph(graph),
971 971
        _skip_nodes(false), _skip_edges(false) {}
972 972

	
973 973
    /// \brief Constructor
974 974
    ///
975 975
    /// Construct a directed graph writer, which writes to the given
976 976
    /// output file.
977 977
    GraphWriter(const std::string& fn, const Graph& graph)
978 978
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
979 979
        _skip_nodes(false), _skip_edges(false) {}
980 980

	
981 981
    /// \brief Constructor
982 982
    ///
983 983
    /// Construct a directed graph writer, which writes to the given
984 984
    /// output file.
985 985
    GraphWriter(const char* fn, const Graph& graph)
986 986
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
987 987
        _skip_nodes(false), _skip_edges(false) {}
988 988

	
989 989
    /// \brief Destructor
990 990
    ~GraphWriter() {
991 991
      for (typename NodeMaps::iterator it = _node_maps.begin();
992 992
           it != _node_maps.end(); ++it) {
993 993
        delete it->second;
994 994
      }
995 995

	
996 996
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
997 997
           it != _edge_maps.end(); ++it) {
998 998
        delete it->second;
999 999
      }
1000 1000

	
1001 1001
      for (typename Attributes::iterator it = _attributes.begin();
1002 1002
           it != _attributes.end(); ++it) {
1003 1003
        delete it->second;
1004 1004
      }
1005 1005

	
1006 1006
      if (local_os) {
1007 1007
        delete _os;
1008 1008
      }
1009 1009
    }
1010 1010

	
1011 1011
  private:
1012 1012

	
1013 1013
    friend GraphWriter<Graph> graphWriter<>(std::ostream& os,
1014 1014
                                            const Graph& graph);
1015 1015
    friend GraphWriter<Graph> graphWriter<>(const std::string& fn,
1016 1016
                                            const Graph& graph);
1017 1017
    friend GraphWriter<Graph> graphWriter<>(const char *fn,
1018 1018
                                            const Graph& graph);
1019 1019

	
1020 1020
    GraphWriter(GraphWriter& other)
1021 1021
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1022 1022
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1023 1023

	
1024 1024
      other._os = 0;
1025 1025
      other.local_os = false;
1026 1026

	
1027 1027
      _node_index.swap(other._node_index);
1028 1028
      _edge_index.swap(other._edge_index);
1029 1029

	
1030 1030
      _node_maps.swap(other._node_maps);
1031 1031
      _edge_maps.swap(other._edge_maps);
1032 1032
      _attributes.swap(other._attributes);
1033 1033

	
1034 1034
      _nodes_caption = other._nodes_caption;
1035 1035
      _edges_caption = other._edges_caption;
1036 1036
      _attributes_caption = other._attributes_caption;
1037 1037
    }
1038 1038

	
1039 1039
    GraphWriter& operator=(const GraphWriter&);
1040 1040

	
1041 1041
  public:
1042 1042

	
1043 1043
    /// \name Writing rules
1044 1044
    /// @{
1045 1045

	
1046 1046
    /// \brief Node map writing rule
1047 1047
    ///
1048 1048
    /// Add a node map writing rule to the writer.
1049 1049
    template <typename Map>
1050 1050
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1051 1051
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1052 1052
      _writer_bits::MapStorageBase<Node>* storage =
1053 1053
        new _writer_bits::MapStorage<Node, Map>(map);
1054 1054
      _node_maps.push_back(std::make_pair(caption, storage));
1055 1055
      return *this;
1056 1056
    }
1057 1057

	
1058 1058
    /// \brief Node map writing rule
1059 1059
    ///
1060 1060
    /// Add a node map writing rule with specialized converter to the
1061 1061
    /// writer.
1062 1062
    template <typename Map, typename Converter>
1063 1063
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1064 1064
                           const Converter& converter = Converter()) {
1065 1065
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1066 1066
      _writer_bits::MapStorageBase<Node>* storage =
1067 1067
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1068 1068
      _node_maps.push_back(std::make_pair(caption, storage));
1069 1069
      return *this;
1070 1070
    }
1071 1071

	
1072 1072
    /// \brief Edge map writing rule
1073 1073
    ///
1074 1074
    /// Add an edge map writing rule to the writer.
1075 1075
    template <typename Map>
1076 1076
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1077 1077
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1078 1078
      _writer_bits::MapStorageBase<Edge>* storage =
1079 1079
        new _writer_bits::MapStorage<Edge, Map>(map);
1080 1080
      _edge_maps.push_back(std::make_pair(caption, storage));
1081 1081
      return *this;
1082 1082
    }
1083 1083

	
1084 1084
    /// \brief Edge map writing rule
1085 1085
    ///
1086 1086
    /// Add an edge map writing rule with specialized converter to the
1087 1087
    /// writer.
1088 1088
    template <typename Map, typename Converter>
1089 1089
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1090 1090
                          const Converter& converter = Converter()) {
1091 1091
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1092 1092
      _writer_bits::MapStorageBase<Edge>* storage =
1093 1093
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1094 1094
      _edge_maps.push_back(std::make_pair(caption, storage));
1095 1095
      return *this;
1096 1096
    }
1097 1097

	
1098 1098
    /// \brief Arc map writing rule
1099 1099
    ///
1100 1100
    /// Add an arc map writing rule to the writer.
1101 1101
    template <typename Map>
1102 1102
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1103 1103
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1104 1104
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1105 1105
        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1106 1106
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1107 1107
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1108 1108
        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1109 1109
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1110 1110
      return *this;
1111 1111
    }
1112 1112

	
1113 1113
    /// \brief Arc map writing rule
1114 1114
    ///
1115 1115
    /// Add an arc map writing rule with specialized converter to the
1116 1116
    /// writer.
1117 1117
    template <typename Map, typename Converter>
1118 1118
    GraphWriter& arcMap(const std::string& caption, const Map& map,
1119 1119
                          const Converter& converter = Converter()) {
1120 1120
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1121 1121
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1122 1122
        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1123 1123
        (_graph, map, converter);
1124 1124
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1125 1125
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1126 1126
        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1127 1127
        (_graph, map, converter);
1128 1128
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1129 1129
      return *this;
1130 1130
    }
1131 1131

	
1132 1132
    /// \brief Attribute writing rule
1133 1133
    ///
1134 1134
    /// Add an attribute writing rule to the writer.
1135 1135
    template <typename Value>
1136 1136
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1137 1137
      _writer_bits::ValueStorageBase* storage =
1138 1138
        new _writer_bits::ValueStorage<Value>(value);
1139 1139
      _attributes.push_back(std::make_pair(caption, storage));
1140 1140
      return *this;
1141 1141
    }
1142 1142

	
1143 1143
    /// \brief Attribute writing rule
1144 1144
    ///
1145 1145
    /// Add an attribute writing rule with specialized converter to the
1146 1146
    /// writer.
1147 1147
    template <typename Value, typename Converter>
1148 1148
    GraphWriter& attribute(const std::string& caption, const Value& value,
1149 1149
                             const Converter& converter = Converter()) {
1150 1150
      _writer_bits::ValueStorageBase* storage =
1151 1151
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1152 1152
      _attributes.push_back(std::make_pair(caption, storage));
1153 1153
      return *this;
1154 1154
    }
1155 1155

	
1156 1156
    /// \brief Node writing rule
1157 1157
    ///
1158 1158
    /// Add a node writing rule to the writer.
1159 1159
    GraphWriter& node(const std::string& caption, const Node& node) {
1160 1160
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1161 1161
      Converter converter(_node_index);
1162 1162
      _writer_bits::ValueStorageBase* storage =
1163 1163
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1164 1164
      _attributes.push_back(std::make_pair(caption, storage));
1165 1165
      return *this;
1166 1166
    }
1167 1167

	
1168 1168
    /// \brief Edge writing rule
1169 1169
    ///
1170 1170
    /// Add an edge writing rule to writer.
1171 1171
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1172 1172
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1173 1173
      Converter converter(_edge_index);
1174 1174
      _writer_bits::ValueStorageBase* storage =
1175 1175
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1176 1176
      _attributes.push_back(std::make_pair(caption, storage));
1177 1177
      return *this;
1178 1178
    }
1179 1179

	
1180 1180
    /// \brief Arc writing rule
1181 1181
    ///
1182 1182
    /// Add an arc writing rule to writer.
1183 1183
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1184 1184
      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1185 1185
      Converter converter(_graph, _edge_index);
1186 1186
      _writer_bits::ValueStorageBase* storage =
1187 1187
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1188 1188
      _attributes.push_back(std::make_pair(caption, storage));
1189 1189
      return *this;
1190 1190
    }
1191 1191

	
1192 1192
    /// \name Section captions
1193 1193
    /// @{
1194 1194

	
1195 1195
    /// \brief Add an additional caption to the \c \@nodes section
1196 1196
    ///
1197 1197
    /// Add an additional caption to the \c \@nodes section.
1198 1198
    GraphWriter& nodes(const std::string& caption) {
1199 1199
      _nodes_caption = caption;
1200 1200
      return *this;
1201 1201
    }
1202 1202

	
1203 1203
    /// \brief Add an additional caption to the \c \@arcs section
1204 1204
    ///
1205 1205
    /// Add an additional caption to the \c \@arcs section.
1206 1206
    GraphWriter& edges(const std::string& caption) {
1207 1207
      _edges_caption = caption;
1208 1208
      return *this;
1209 1209
    }
1210 1210

	
1211 1211
    /// \brief Add an additional caption to the \c \@attributes section
1212 1212
    ///
1213 1213
    /// Add an additional caption to the \c \@attributes section.
1214 1214
    GraphWriter& attributes(const std::string& caption) {
1215 1215
      _attributes_caption = caption;
1216 1216
      return *this;
1217 1217
    }
1218 1218

	
1219 1219
    /// \name Skipping section
1220 1220
    /// @{
1221 1221

	
1222 1222
    /// \brief Skip writing the node set
1223 1223
    ///
1224 1224
    /// The \c \@nodes section will not be written to the stream.
1225 1225
    GraphWriter& skipNodes() {
1226 1226
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1227 1227
      _skip_nodes = true;
1228 1228
      return *this;
1229 1229
    }
1230 1230

	
1231 1231
    /// \brief Skip writing edge set
1232 1232
    ///
1233 1233
    /// The \c \@edges section will not be written to the stream.
1234 1234
    GraphWriter& skipEdges() {
1235 1235
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1236 1236
      _skip_edges = true;
1237 1237
      return *this;
1238 1238
    }
1239 1239

	
1240 1240
    /// @}
1241 1241

	
1242 1242
  private:
1243 1243

	
1244 1244
    void writeNodes() {
1245 1245
      _writer_bits::MapStorageBase<Node>* label = 0;
1246 1246
      for (typename NodeMaps::iterator it = _node_maps.begin();
1247 1247
           it != _node_maps.end(); ++it) {
1248 1248
        if (it->first == "label") {
1249 1249
          label = it->second;
1250 1250
          break;
1251 1251
        }
1252 1252
      }
1253 1253

	
1254 1254
      *_os << "@nodes";
1255 1255
      if (!_nodes_caption.empty()) {
1256 1256
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1257 1257
      }
1258 1258
      *_os << std::endl;
1259 1259

	
1260 1260
      if (label == 0) {
1261 1261
        *_os << "label" << '\t';
1262 1262
      }
1263 1263
      for (typename NodeMaps::iterator it = _node_maps.begin();
1264 1264
           it != _node_maps.end(); ++it) {
1265 1265
        _writer_bits::writeToken(*_os, it->first) << '\t';
1266 1266
      }
1267 1267
      *_os << std::endl;
1268 1268

	
1269 1269
      std::vector<Node> nodes;
1270 1270
      for (NodeIt n(_graph); n != INVALID; ++n) {
1271 1271
        nodes.push_back(n);
1272 1272
      }
1273 1273

	
1274 1274
      if (label == 0) {
1275 1275
        IdMap<Graph, Node> id_map(_graph);
1276 1276
        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1277 1277
        std::sort(nodes.begin(), nodes.end(), id_less);
1278 1278
      } else {
1279 1279
        label->sort(nodes);
1280 1280
      }
1281 1281

	
1282 1282
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1283 1283
        Node n = nodes[i];
1284 1284
        if (label == 0) {
1285 1285
          std::ostringstream os;
1286 1286
          os << _graph.id(n);
1287 1287
          _writer_bits::writeToken(*_os, os.str());
1288 1288
          *_os << '\t';
1289 1289
          _node_index.insert(std::make_pair(n, os.str()));
1290 1290
        }
1291 1291
        for (typename NodeMaps::iterator it = _node_maps.begin();
1292 1292
             it != _node_maps.end(); ++it) {
1293 1293
          std::string value = it->second->get(n);
1294 1294
          _writer_bits::writeToken(*_os, value);
1295 1295
          if (it->first == "label") {
1296 1296
            _node_index.insert(std::make_pair(n, value));
1297 1297
          }
1298 1298
          *_os << '\t';
1299 1299
        }
1300 1300
        *_os << std::endl;
1301 1301
      }
1302 1302
    }
1303 1303

	
1304 1304
    void createNodeIndex() {
1305 1305
      _writer_bits::MapStorageBase<Node>* label = 0;
1306 1306
      for (typename NodeMaps::iterator it = _node_maps.begin();
1307 1307
           it != _node_maps.end(); ++it) {
1308 1308
        if (it->first == "label") {
1309 1309
          label = it->second;
1310 1310
          break;
1311 1311
        }
1312 1312
      }
1313 1313

	
1314 1314
      if (label == 0) {
1315 1315
        for (NodeIt n(_graph); n != INVALID; ++n) {
1316 1316
          std::ostringstream os;
1317 1317
          os << _graph.id(n);
1318 1318
          _node_index.insert(std::make_pair(n, os.str()));
1319 1319
        }
1320 1320
      } else {
1321 1321
        for (NodeIt n(_graph); n != INVALID; ++n) {
1322 1322
          std::string value = label->get(n);
1323 1323
          _node_index.insert(std::make_pair(n, value));
1324 1324
        }
1325 1325
      }
1326 1326
    }
1327 1327

	
1328 1328
    void writeEdges() {
1329 1329
      _writer_bits::MapStorageBase<Edge>* label = 0;
1330 1330
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1331 1331
           it != _edge_maps.end(); ++it) {
1332 1332
        if (it->first == "label") {
1333 1333
          label = it->second;
1334 1334
          break;
1335 1335
        }
1336 1336
      }
1337 1337

	
1338 1338
      *_os << "@edges";
1339 1339
      if (!_edges_caption.empty()) {
1340 1340
        _writer_bits::writeToken(*_os << ' ', _edges_caption);
1341 1341
      }
1342 1342
      *_os << std::endl;
1343 1343

	
1344 1344
      *_os << '\t' << '\t';
1345 1345
      if (label == 0) {
1346 1346
        *_os << "label" << '\t';
1347 1347
      }
1348 1348
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1349 1349
           it != _edge_maps.end(); ++it) {
1350 1350
        _writer_bits::writeToken(*_os, it->first) << '\t';
1351 1351
      }
1352 1352
      *_os << std::endl;
1353 1353

	
1354 1354
      std::vector<Edge> edges;
1355 1355
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1356 1356
        edges.push_back(n);
1357 1357
      }
1358 1358

	
1359 1359
      if (label == 0) {
1360 1360
        IdMap<Graph, Edge> id_map(_graph);
1361 1361
        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1362 1362
        std::sort(edges.begin(), edges.end(), id_less);
1363 1363
      } else {
1364 1364
        label->sort(edges);
1365 1365
      }
1366 1366

	
1367 1367
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1368 1368
        Edge e = edges[i];
1369 1369
        _writer_bits::writeToken(*_os, _node_index.
1370 1370
                                 find(_graph.u(e))->second);
1371 1371
        *_os << '\t';
1372 1372
        _writer_bits::writeToken(*_os, _node_index.
1373 1373
                                 find(_graph.v(e))->second);
1374 1374
        *_os << '\t';
1375 1375
        if (label == 0) {
1376 1376
          std::ostringstream os;
1377 1377
          os << _graph.id(e);
1378 1378
          _writer_bits::writeToken(*_os, os.str());
1379 1379
          *_os << '\t';
1380 1380
          _edge_index.insert(std::make_pair(e, os.str()));
1381 1381
        }
1382 1382
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1383 1383
             it != _edge_maps.end(); ++it) {
1384 1384
          std::string value = it->second->get(e);
1385 1385
          _writer_bits::writeToken(*_os, value);
1386 1386
          if (it->first == "label") {
1387 1387
            _edge_index.insert(std::make_pair(e, value));
1388 1388
          }
1389 1389
          *_os << '\t';
1390 1390
        }
1391 1391
        *_os << std::endl;
1392 1392
      }
1393 1393
    }
1394 1394

	
1395 1395
    void createEdgeIndex() {
1396 1396
      _writer_bits::MapStorageBase<Edge>* label = 0;
1397 1397
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1398 1398
           it != _edge_maps.end(); ++it) {
1399 1399
        if (it->first == "label") {
1400 1400
          label = it->second;
1401 1401
          break;
1402 1402
        }
1403 1403
      }
1404 1404

	
1405 1405
      if (label == 0) {
1406 1406
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1407 1407
          std::ostringstream os;
1408 1408
          os << _graph.id(e);
1409 1409
          _edge_index.insert(std::make_pair(e, os.str()));
1410 1410
        }
1411 1411
      } else {
1412 1412
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1413 1413
          std::string value = label->get(e);
1414 1414
          _edge_index.insert(std::make_pair(e, value));
1415 1415
        }
1416 1416
      }
1417 1417
    }
1418 1418

	
1419 1419
    void writeAttributes() {
1420 1420
      if (_attributes.empty()) return;
1421 1421
      *_os << "@attributes";
1422 1422
      if (!_attributes_caption.empty()) {
1423 1423
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1424 1424
      }
1425 1425
      *_os << std::endl;
1426 1426
      for (typename Attributes::iterator it = _attributes.begin();
1427 1427
           it != _attributes.end(); ++it) {
1428 1428
        _writer_bits::writeToken(*_os, it->first) << ' ';
1429 1429
        _writer_bits::writeToken(*_os, it->second->get());
1430 1430
        *_os << std::endl;
1431 1431
      }
1432 1432
    }
1433 1433

	
1434 1434
  public:
1435 1435

	
1436 1436
    /// \name Execution of the writer
1437 1437
    /// @{
1438 1438

	
1439 1439
    /// \brief Start the batch processing
1440 1440
    ///
1441 1441
    /// This function starts the batch processing.
1442 1442
    void run() {
1443 1443
      if (!_skip_nodes) {
1444 1444
        writeNodes();
1445 1445
      } else {
1446 1446
        createNodeIndex();
1447 1447
      }
1448 1448
      if (!_skip_edges) {
1449 1449
        writeEdges();
1450 1450
      } else {
1451 1451
        createEdgeIndex();
1452 1452
      }
1453 1453
      writeAttributes();
1454 1454
    }
1455 1455

	
1456 1456
    /// \brief Give back the stream of the writer
1457 1457
    ///
1458 1458
    /// Give back the stream of the writer
1459 1459
    std::ostream& ostream() {
1460 1460
      return *_os;
1461 1461
    }
1462 1462

	
1463 1463
    /// @}
1464 1464
  };
1465 1465

	
1466 1466
  /// \brief Return a \ref GraphWriter class
1467 1467
  ///
1468 1468
  /// This function just returns a \ref GraphWriter class.
1469 1469
  /// \relates GraphWriter
1470 1470
  template <typename Graph>
1471 1471
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1472 1472
    GraphWriter<Graph> tmp(os, graph);
1473 1473
    return tmp;
1474 1474
  }
1475 1475

	
1476 1476
  /// \brief Return a \ref GraphWriter class
1477 1477
  ///
1478 1478
  /// This function just returns a \ref GraphWriter class.
1479 1479
  /// \relates GraphWriter
1480 1480
  template <typename Graph>
1481 1481
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1482 1482
    GraphWriter<Graph> tmp(fn, graph);
1483 1483
    return tmp;
1484 1484
  }
1485 1485

	
1486 1486
  /// \brief Return a \ref GraphWriter class
1487 1487
  ///
1488 1488
  /// This function just returns a \ref GraphWriter class.
1489 1489
  /// \relates GraphWriter
1490 1490
  template <typename Graph>
1491 1491
  GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1492 1492
    GraphWriter<Graph> tmp(fn, graph);
1493 1493
    return tmp;
1494 1494
  }
1495 1495
}
1496 1496

	
1497 1497
#endif
Ignore white space 1536 line context
... ...
@@ -77,1480 +77,1482 @@
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; }
102 102

	
103 103
    Node source(Arc e) const { return Node(arcs[e.id].source); }
104 104
    Node target(Arc e) const { return Node(arcs[e.id].target); }
105 105

	
106 106

	
107 107
    void first(Node& node) const {
108 108
      node.id = first_node;
109 109
    }
110 110

	
111 111
    void next(Node& node) const {
112 112
      node.id = nodes[node.id].next;
113 113
    }
114 114

	
115 115

	
116 116
    void first(Arc& arc) const {
117 117
      int n;
118 118
      for(n = first_node;
119 119
          n!=-1 && nodes[n].first_in == -1;
120 120
          n = nodes[n].next) {}
121 121
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
122 122
    }
123 123

	
124 124
    void next(Arc& arc) const {
125 125
      if (arcs[arc.id].next_in != -1) {
126 126
        arc.id = arcs[arc.id].next_in;
127 127
      } else {
128 128
        int n;
129 129
        for(n = nodes[arcs[arc.id].target].next;
130 130
            n!=-1 && nodes[n].first_in == -1;
131 131
            n = nodes[n].next) {}
132 132
        arc.id = (n == -1) ? -1 : nodes[n].first_in;
133 133
      }
134 134
    }
135 135

	
136 136
    void firstOut(Arc &e, const Node& v) const {
137 137
      e.id = nodes[v.id].first_out;
138 138
    }
139 139
    void nextOut(Arc &e) const {
140 140
      e.id=arcs[e.id].next_out;
141 141
    }
142 142

	
143 143
    void firstIn(Arc &e, const Node& v) const {
144 144
      e.id = nodes[v.id].first_in;
145 145
    }
146 146
    void nextIn(Arc &e) const {
147 147
      e.id=arcs[e.id].next_in;
148 148
    }
149 149

	
150 150

	
151 151
    static int id(Node v) { return v.id; }
152 152
    static int id(Arc e) { return e.id; }
153 153

	
154 154
    static Node nodeFromId(int id) { return Node(id);}
155 155
    static Arc arcFromId(int id) { return Arc(id);}
156 156

	
157 157
    bool valid(Node n) const {
158 158
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
159 159
        nodes[n.id].prev != -2;
160 160
    }
161 161

	
162 162
    bool valid(Arc a) const {
163 163
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
164 164
        arcs[a.id].prev_in != -2;
165 165
    }
166 166

	
167 167
    Node addNode() {
168 168
      int n;
169 169

	
170 170
      if(first_free_node==-1) {
171 171
        n = nodes.size();
172 172
        nodes.push_back(NodeT());
173 173
      } else {
174 174
        n = first_free_node;
175 175
        first_free_node = nodes[n].next;
176 176
      }
177 177

	
178 178
      nodes[n].next = first_node;
179 179
      if(first_node != -1) nodes[first_node].prev = n;
180 180
      first_node = n;
181 181
      nodes[n].prev = -1;
182 182

	
183 183
      nodes[n].first_in = nodes[n].first_out = -1;
184 184

	
185 185
      return Node(n);
186 186
    }
187 187

	
188 188
    Arc addArc(Node u, Node v) {
189 189
      int n;
190 190

	
191 191
      if (first_free_arc == -1) {
192 192
        n = arcs.size();
193 193
        arcs.push_back(ArcT());
194 194
      } else {
195 195
        n = first_free_arc;
196 196
        first_free_arc = arcs[n].next_in;
197 197
      }
198 198

	
199 199
      arcs[n].source = u.id;
200 200
      arcs[n].target = v.id;
201 201

	
202 202
      arcs[n].next_out = nodes[u.id].first_out;
203 203
      if(nodes[u.id].first_out != -1) {
204 204
        arcs[nodes[u.id].first_out].prev_out = n;
205 205
      }
206 206

	
207 207
      arcs[n].next_in = nodes[v.id].first_in;
208 208
      if(nodes[v.id].first_in != -1) {
209 209
        arcs[nodes[v.id].first_in].prev_in = n;
210 210
      }
211 211

	
212 212
      arcs[n].prev_in = arcs[n].prev_out = -1;
213 213

	
214 214
      nodes[u.id].first_out = nodes[v.id].first_in = n;
215 215

	
216 216
      return Arc(n);
217 217
    }
218 218

	
219 219
    void erase(const Node& node) {
220 220
      int n = node.id;
221 221

	
222 222
      if(nodes[n].next != -1) {
223 223
        nodes[nodes[n].next].prev = nodes[n].prev;
224 224
      }
225 225

	
226 226
      if(nodes[n].prev != -1) {
227 227
        nodes[nodes[n].prev].next = nodes[n].next;
228 228
      } else {
229 229
        first_node = nodes[n].next;
230 230
      }
231 231

	
232 232
      nodes[n].next = first_free_node;
233 233
      first_free_node = n;
234 234
      nodes[n].prev = -2;
235 235

	
236 236
    }
237 237

	
238 238
    void erase(const Arc& arc) {
239 239
      int n = arc.id;
240 240

	
241 241
      if(arcs[n].next_in!=-1) {
242 242
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
243 243
      }
244 244

	
245 245
      if(arcs[n].prev_in!=-1) {
246 246
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
247 247
      } else {
248 248
        nodes[arcs[n].target].first_in = arcs[n].next_in;
249 249
      }
250 250

	
251 251

	
252 252
      if(arcs[n].next_out!=-1) {
253 253
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254 254
      }
255 255

	
256 256
      if(arcs[n].prev_out!=-1) {
257 257
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
258 258
      } else {
259 259
        nodes[arcs[n].source].first_out = arcs[n].next_out;
260 260
      }
261 261

	
262 262
      arcs[n].next_in = first_free_arc;
263 263
      first_free_arc = n;
264 264
      arcs[n].prev_in = -2;
265 265
    }
266 266

	
267 267
    void clear() {
268 268
      arcs.clear();
269 269
      nodes.clear();
270 270
      first_node = first_free_node = first_free_arc = -1;
271 271
    }
272 272

	
273 273
  protected:
274 274
    void changeTarget(Arc e, Node n)
275 275
    {
276 276
      if(arcs[e.id].next_in != -1)
277 277
        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
278 278
      if(arcs[e.id].prev_in != -1)
279 279
        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
280 280
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
281 281
      if (nodes[n.id].first_in != -1) {
282 282
        arcs[nodes[n.id].first_in].prev_in = e.id;
283 283
      }
284 284
      arcs[e.id].target = n.id;
285 285
      arcs[e.id].prev_in = -1;
286 286
      arcs[e.id].next_in = nodes[n.id].first_in;
287 287
      nodes[n.id].first_in = e.id;
288 288
    }
289 289
    void changeSource(Arc e, Node n)
290 290
    {
291 291
      if(arcs[e.id].next_out != -1)
292 292
        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
293 293
      if(arcs[e.id].prev_out != -1)
294 294
        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
295 295
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
296 296
      if (nodes[n.id].first_out != -1) {
297 297
        arcs[nodes[n.id].first_out].prev_out = e.id;
298 298
      }
299 299
      arcs[e.id].source = n.id;
300 300
      arcs[e.id].prev_out = -1;
301 301
      arcs[e.id].next_out = nodes[n.id].first_out;
302 302
      nodes[n.id].first_out = e.id;
303 303
    }
304 304

	
305 305
  };
306 306

	
307 307
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308 308

	
309 309
  /// \addtogroup graphs
310 310
  /// @{
311 311

	
312 312
  ///A general directed graph structure.
313 313

	
314 314
  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
315 315
  ///implementation based on static linked lists that are stored in
316 316
  ///\c std::vector structures.
317 317
  ///
318 318
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
319 319
  ///also provides several useful additional functionalities.
320 320
  ///Most of the member functions and nested classes are documented
321 321
  ///only in the concept class.
322 322
  ///
323 323
  ///An important extra feature of this digraph implementation is that
324 324
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
325 325
  ///
326 326
  ///\sa concepts::Digraph
327 327

	
328 328
  class ListDigraph : public ExtendedListDigraphBase {
329 329
  private:
330 330
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
331 331

	
332 332
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
333 333
    ///
334 334
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
335 335
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
336 336
    ///Use copyDigraph() instead.
337 337

	
338 338
    ///Assignment of ListDigraph to another one is \e not allowed.
339 339
    ///Use copyDigraph() instead.
340 340
    void operator=(const ListDigraph &) {}
341 341
  public:
342 342

	
343 343
    typedef ExtendedListDigraphBase Parent;
344 344

	
345 345
    /// Constructor
346 346

	
347 347
    /// Constructor.
348 348
    ///
349 349
    ListDigraph() {}
350 350

	
351 351
    ///Add a new node to the digraph.
352 352

	
353 353
    ///Add a new node to the digraph.
354 354
    ///\return the new node.
355 355
    Node addNode() { return Parent::addNode(); }
356 356

	
357 357
    ///Add a new arc to the digraph.
358 358

	
359 359
    ///Add a new arc to the digraph with source node \c s
360 360
    ///and target node \c t.
361 361
    ///\return the new arc.
362 362
    Arc addArc(const Node& s, const Node& t) {
363 363
      return Parent::addArc(s, t);
364 364
    }
365 365

	
366 366
    ///\brief Erase a node from the digraph.
367 367
    ///
368 368
    ///Erase a node from the digraph.
369 369
    ///
370 370
    void erase(const Node& n) { Parent::erase(n); }
371 371

	
372 372
    ///\brief Erase an arc from the digraph.
373 373
    ///
374 374
    ///Erase an arc from the digraph.
375 375
    ///
376 376
    void erase(const Arc& a) { Parent::erase(a); }
377 377

	
378 378
    /// Node validity check
379 379

	
380 380
    /// This function gives back true if the given node is valid,
381 381
    /// ie. it is a real node of the graph.
382 382
    ///
383 383
    /// \warning A Node pointing to a removed item
384 384
    /// could become valid again later if new nodes are
385 385
    /// added to the graph.
386 386
    bool valid(Node n) const { return Parent::valid(n); }
387 387

	
388 388
    /// Arc validity check
389 389

	
390 390
    /// This function gives back true if the given arc is valid,
391 391
    /// ie. it is a real arc of the graph.
392 392
    ///
393 393
    /// \warning An Arc pointing to a removed item
394 394
    /// could become valid again later if new nodes are
395 395
    /// added to the graph.
396 396
    bool valid(Arc a) const { return Parent::valid(a); }
397 397

	
398 398
    /// Change the target of \c a to \c n
399 399

	
400 400
    /// Change the target of \c a to \c n
401 401
    ///
402 402
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
403 403
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
404 404
    ///invalidated.
405 405
    ///
406 406
    ///\warning This functionality cannot be used together with the Snapshot
407 407
    ///feature.
408 408
    void changeTarget(Arc a, Node n) {
409 409
      Parent::changeTarget(a,n);
410 410
    }
411 411
    /// Change the source of \c a to \c n
412 412

	
413 413
    /// Change the source of \c a to \c n
414 414
    ///
415 415
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
416 416
    ///valid. However the <tt>ArcIt<tt>s and <tt>OutArcIt</tt>s are
417 417
    ///invalidated.
418 418
    ///
419 419
    ///\warning This functionality cannot be used together with the Snapshot
420 420
    ///feature.
421 421
    void changeSource(Arc a, Node n) {
422 422
      Parent::changeSource(a,n);
423 423
    }
424 424

	
425 425
    /// Invert the direction of an arc.
426 426

	
427 427
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
428 428
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
429 429
    ///invalidated.
430 430
    ///
431 431
    ///\warning This functionality cannot be used together with the Snapshot
432 432
    ///feature.
433 433
    void reverseArc(Arc e) {
434 434
      Node t=target(e);
435 435
      changeTarget(e,source(e));
436 436
      changeSource(e,t);
437 437
    }
438 438

	
439 439
    /// Reserve memory for nodes.
440 440

	
441 441
    /// Using this function it is possible to avoid the superfluous memory
442 442
    /// allocation: if you know that the digraph you want to build will
443 443
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
444 444
    /// then it is worth reserving space for this amount before starting
445 445
    /// to build the digraph.
446 446
    /// \sa reserveArc
447 447
    void reserveNode(int n) { nodes.reserve(n); };
448 448

	
449 449
    /// Reserve memory for arcs.
450 450

	
451 451
    /// Using this function it is possible to avoid the superfluous memory
452 452
    /// allocation: if you know that the digraph you want to build will
453 453
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
454 454
    /// then it is worth reserving space for this amount before starting
455 455
    /// to build the digraph.
456 456
    /// \sa reserveNode
457 457
    void reserveArc(int m) { arcs.reserve(m); };
458 458

	
459 459
    ///Contract two nodes.
460 460

	
461 461
    ///This function contracts two nodes.
462 462
    ///Node \p b will be removed but instead of deleting
463 463
    ///incident arcs, they will be joined to \p a.
464 464
    ///The last parameter \p r controls whether to remove loops. \c true
465 465
    ///means that loops will be removed.
466 466
    ///
467 467
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
468 468
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
469 469
    ///may be invalidated.
470 470
    ///
471 471
    ///\warning This functionality cannot be used together with the Snapshot
472 472
    ///feature.
473 473
    void contract(Node a, Node b, bool r = true)
474 474
    {
475 475
      for(OutArcIt e(*this,b);e!=INVALID;) {
476 476
        OutArcIt f=e;
477 477
        ++f;
478 478
        if(r && target(e)==a) erase(e);
479 479
        else changeSource(e,a);
480 480
        e=f;
481 481
      }
482 482
      for(InArcIt e(*this,b);e!=INVALID;) {
483 483
        InArcIt f=e;
484 484
        ++f;
485 485
        if(r && source(e)==a) erase(e);
486 486
        else changeTarget(e,a);
487 487
        e=f;
488 488
      }
489 489
      erase(b);
490 490
    }
491 491

	
492 492
    ///Split a node.
493 493

	
494 494
    ///This function splits a node. First a new node is added to the digraph,
495 495
    ///then the source of each outgoing arc of \c n is moved to this new node.
496 496
    ///If \c connect is \c true (this is the default value), then a new arc
497 497
    ///from \c n to the newly created node is also added.
498 498
    ///\return The newly created node.
499 499
    ///
500 500
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
501 501
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
502 502
    ///be invalidated.
503 503
    ///
504 504
    ///\warning This functionality cannot be used together with the
505 505
    ///Snapshot feature.
506 506
    ///
507 507
    ///\todo It could be implemented in a bit faster way.
508 508
    Node split(Node n, bool connect = true) {
509 509
      Node b = addNode();
510 510
      for(OutArcIt e(*this,n);e!=INVALID;) {
511 511
        OutArcIt f=e;
512 512
        ++f;
513 513
        changeSource(e,b);
514 514
        e=f;
515 515
      }
516 516
      if (connect) addArc(n,b);
517 517
      return b;
518 518
    }
519 519

	
520 520
    ///Split an arc.
521 521

	
522 522
    ///This function splits an arc. First a new node \c b is added to
523 523
    ///the digraph, then the original arc is re-targeted to \c
524 524
    ///b. Finally an arc from \c b to the original target is added.
525 525
    ///
526 526
    ///\return The newly created node.
527 527
    ///
528 528
    ///\warning This functionality cannot be used together with the
529 529
    ///Snapshot feature.
530 530
    Node split(Arc e) {
531 531
      Node b = addNode();
532 532
      addArc(b,target(e));
533 533
      changeTarget(e,b);
534 534
      return b;
535 535
    }
536 536

	
537 537
    /// \brief Class to make a snapshot of the digraph and restore
538 538
    /// it later.
539 539
    ///
540 540
    /// Class to make a snapshot of the digraph and restore it later.
541 541
    ///
542 542
    /// The newly added nodes and arcs can be removed using the
543 543
    /// restore() function.
544 544
    ///
545 545
    /// \warning Arc and node deletions and other modifications (e.g.
546 546
    /// contracting, splitting, reversing arcs or nodes) cannot be
547 547
    /// restored. These events invalidate the snapshot.
548 548
    class Snapshot {
549 549
    protected:
550 550

	
551 551
      typedef Parent::NodeNotifier NodeNotifier;
552 552

	
553 553
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
554 554
      public:
555 555

	
556 556
        NodeObserverProxy(Snapshot& _snapshot)
557 557
          : snapshot(_snapshot) {}
558 558

	
559 559
        using NodeNotifier::ObserverBase::attach;
560 560
        using NodeNotifier::ObserverBase::detach;
561 561
        using NodeNotifier::ObserverBase::attached;
562 562

	
563 563
      protected:
564 564

	
565 565
        virtual void add(const Node& node) {
566 566
          snapshot.addNode(node);
567 567
        }
568 568
        virtual void add(const std::vector<Node>& nodes) {
569 569
          for (int i = nodes.size() - 1; i >= 0; ++i) {
570 570
            snapshot.addNode(nodes[i]);
571 571
          }
572 572
        }
573 573
        virtual void erase(const Node& node) {
574 574
          snapshot.eraseNode(node);
575 575
        }
576 576
        virtual void erase(const std::vector<Node>& nodes) {
577 577
          for (int i = 0; i < int(nodes.size()); ++i) {
578 578
            snapshot.eraseNode(nodes[i]);
579 579
          }
580 580
        }
581 581
        virtual void build() {
582 582
          Node node;
583 583
          std::vector<Node> nodes;
584 584
          for (notifier()->first(node); node != INVALID;
585 585
               notifier()->next(node)) {
586 586
            nodes.push_back(node);
587 587
          }
588 588
          for (int i = nodes.size() - 1; i >= 0; --i) {
589 589
            snapshot.addNode(nodes[i]);
590 590
          }
591 591
        }
592 592
        virtual void clear() {
593 593
          Node node;
594 594
          for (notifier()->first(node); node != INVALID;
595 595
               notifier()->next(node)) {
596 596
            snapshot.eraseNode(node);
597 597
          }
598 598
        }
599 599

	
600 600
        Snapshot& snapshot;
601 601
      };
602 602

	
603 603
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
604 604
      public:
605 605

	
606 606
        ArcObserverProxy(Snapshot& _snapshot)
607 607
          : snapshot(_snapshot) {}
608 608

	
609 609
        using ArcNotifier::ObserverBase::attach;
610 610
        using ArcNotifier::ObserverBase::detach;
611 611
        using ArcNotifier::ObserverBase::attached;
612 612

	
613 613
      protected:
614 614

	
615 615
        virtual void add(const Arc& arc) {
616 616
          snapshot.addArc(arc);
617 617
        }
618 618
        virtual void add(const std::vector<Arc>& arcs) {
619 619
          for (int i = arcs.size() - 1; i >= 0; ++i) {
620 620
            snapshot.addArc(arcs[i]);
621 621
          }
622 622
        }
623 623
        virtual void erase(const Arc& arc) {
624 624
          snapshot.eraseArc(arc);
625 625
        }
626 626
        virtual void erase(const std::vector<Arc>& arcs) {
627 627
          for (int i = 0; i < int(arcs.size()); ++i) {
628 628
            snapshot.eraseArc(arcs[i]);
629 629
          }
630 630
        }
631 631
        virtual void build() {
632 632
          Arc arc;
633 633
          std::vector<Arc> arcs;
634 634
          for (notifier()->first(arc); arc != INVALID;
635 635
               notifier()->next(arc)) {
636 636
            arcs.push_back(arc);
637 637
          }
638 638
          for (int i = arcs.size() - 1; i >= 0; --i) {
639 639
            snapshot.addArc(arcs[i]);
640 640
          }
641 641
        }
642 642
        virtual void clear() {
643 643
          Arc arc;
644 644
          for (notifier()->first(arc); arc != INVALID;
645 645
               notifier()->next(arc)) {
646 646
            snapshot.eraseArc(arc);
647 647
          }
648 648
        }
649 649

	
650 650
        Snapshot& snapshot;
651 651
      };
652 652

	
653 653
      ListDigraph *digraph;
654 654

	
655 655
      NodeObserverProxy node_observer_proxy;
656 656
      ArcObserverProxy arc_observer_proxy;
657 657

	
658 658
      std::list<Node> added_nodes;
659 659
      std::list<Arc> added_arcs;
660 660

	
661 661

	
662 662
      void addNode(const Node& node) {
663 663
        added_nodes.push_front(node);
664 664
      }
665 665
      void eraseNode(const Node& node) {
666 666
        std::list<Node>::iterator it =
667 667
          std::find(added_nodes.begin(), added_nodes.end(), node);
668 668
        if (it == added_nodes.end()) {
669 669
          clear();
670 670
          arc_observer_proxy.detach();
671 671
          throw NodeNotifier::ImmediateDetach();
672 672
        } else {
673 673
          added_nodes.erase(it);
674 674
        }
675 675
      }
676 676

	
677 677
      void addArc(const Arc& arc) {
678 678
        added_arcs.push_front(arc);
679 679
      }
680 680
      void eraseArc(const Arc& arc) {
681 681
        std::list<Arc>::iterator it =
682 682
          std::find(added_arcs.begin(), added_arcs.end(), arc);
683 683
        if (it == added_arcs.end()) {
684 684
          clear();
685 685
          node_observer_proxy.detach();
686 686
          throw ArcNotifier::ImmediateDetach();
687 687
        } else {
688 688
          added_arcs.erase(it);
689 689
        }
690 690
      }
691 691

	
692 692
      void attach(ListDigraph &_digraph) {
693 693
        digraph = &_digraph;
694 694
        node_observer_proxy.attach(digraph->notifier(Node()));
695 695
        arc_observer_proxy.attach(digraph->notifier(Arc()));
696 696
      }
697 697

	
698 698
      void detach() {
699 699
        node_observer_proxy.detach();
700 700
        arc_observer_proxy.detach();
701 701
      }
702 702

	
703 703
      bool attached() const {
704 704
        return node_observer_proxy.attached();
705 705
      }
706 706

	
707 707
      void clear() {
708 708
        added_nodes.clear();
709 709
        added_arcs.clear();
710 710
      }
711 711

	
712 712
    public:
713 713

	
714 714
      /// \brief Default constructor.
715 715
      ///
716 716
      /// Default constructor.
717 717
      /// To actually make a snapshot you must call save().
718 718
      Snapshot()
719 719
        : digraph(0), node_observer_proxy(*this),
720 720
          arc_observer_proxy(*this) {}
721 721

	
722 722
      /// \brief Constructor that immediately makes a snapshot.
723 723
      ///
724 724
      /// This constructor immediately makes a snapshot of the digraph.
725 725
      /// \param _digraph The digraph we make a snapshot of.
726 726
      Snapshot(ListDigraph &_digraph)
727 727
        : node_observer_proxy(*this),
728 728
          arc_observer_proxy(*this) {
729 729
        attach(_digraph);
730 730
      }
731 731

	
732 732
      /// \brief Make a snapshot.
733 733
      ///
734 734
      /// Make a snapshot of the digraph.
735 735
      ///
736 736
      /// This function can be called more than once. In case of a repeated
737 737
      /// call, the previous snapshot gets lost.
738 738
      /// \param _digraph The digraph we make the snapshot of.
739 739
      void save(ListDigraph &_digraph) {
740 740
        if (attached()) {
741 741
          detach();
742 742
          clear();
743 743
        }
744 744
        attach(_digraph);
745 745
      }
746 746

	
747 747
      /// \brief Undo the changes until the last snapshot.
748 748
      //
749 749
      /// Undo the changes until the last snapshot created by save().
750 750
      void restore() {
751 751
        detach();
752 752
        for(std::list<Arc>::iterator it = added_arcs.begin();
753 753
            it != added_arcs.end(); ++it) {
754 754
          digraph->erase(*it);
755 755
        }
756 756
        for(std::list<Node>::iterator it = added_nodes.begin();
757 757
            it != added_nodes.end(); ++it) {
758 758
          digraph->erase(*it);
759 759
        }
760 760
        clear();
761 761
      }
762 762

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

	
771 771
  };
772 772

	
773 773
  ///@}
774 774

	
775 775
  class ListGraphBase {
776 776

	
777 777
  protected:
778 778

	
779 779
    struct NodeT {
780 780
      int first_out;
781 781
      int prev, next;
782 782
    };
783 783

	
784 784
    struct ArcT {
785 785
      int target;
786 786
      int prev_out, next_out;
787 787
    };
788 788

	
789 789
    std::vector<NodeT> nodes;
790 790

	
791 791
    int first_node;
792 792

	
793 793
    int first_free_node;
794 794

	
795 795
    std::vector<ArcT> arcs;
796 796

	
797 797
    int first_free_arc;
798 798

	
799 799
  public:
800 800

	
801 801
    typedef ListGraphBase Digraph;
802 802

	
803 803
    class Node;
804 804
    class Arc;
805 805
    class Edge;
806 806

	
807 807
    class Node {
808 808
      friend class ListGraphBase;
809 809
    protected:
810 810

	
811 811
      int id;
812 812
      explicit Node(int pid) { id = pid;}
813 813

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

	
822 822
    class Edge {
823 823
      friend class ListGraphBase;
824 824
    protected:
825 825

	
826 826
      int id;
827 827
      explicit Edge(int pid) { id = pid;}
828 828

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

	
837 837
    class Arc {
838 838
      friend class ListGraphBase;
839 839
    protected:
840 840

	
841 841
      int id;
842 842
      explicit Arc(int pid) { id = pid;}
843 843

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

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

	
854 856

	
855 857

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

	
860 862

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

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

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

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

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

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

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

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

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

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

	
923 925
    void next(Edge& e) const {
924 926
      int n = arcs[e.id * 2].target;
925 927
      e.id = arcs[(e.id * 2) | 1].next_out;
926 928
      while ((e.id & 1) != 1) {
927 929
        e.id = arcs[e.id].next_out;
928 930
      }
929 931
      if (e.id != -1) {
930 932
        e.id /= 2;
931 933
        return;
932 934
      }
933 935
      n = nodes[n].next;
934 936
      while (n != -1) {
935 937
        e.id = nodes[n].first_out;
936 938
        while ((e.id & 1) != 1) {
937 939
          e.id = arcs[e.id].next_out;
938 940
        }
939 941
        if (e.id != -1) {
940 942
          e.id /= 2;
941 943
          return;
942 944
        }
943 945
        n = nodes[n].next;
944 946
      }
945 947
      e.id = -1;
946 948
    }
947 949

	
948 950
    void firstOut(Arc &e, const Node& v) const {
949 951
      e.id = nodes[v.id].first_out;
950 952
    }
951 953
    void nextOut(Arc &e) const {
952 954
      e.id = arcs[e.id].next_out;
953 955
    }
954 956

	
955 957
    void firstIn(Arc &e, const Node& v) const {
956 958
      e.id = ((nodes[v.id].first_out) ^ 1);
957 959
      if (e.id == -2) e.id = -1;
958 960
    }
959 961
    void nextIn(Arc &e) const {
960 962
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
961 963
      if (e.id == -2) e.id = -1;
962 964
    }
963 965

	
964 966
    void firstInc(Edge &e, bool& d, const Node& v) const {
965 967
      int a = nodes[v.id].first_out;
966 968
      if (a != -1 ) {
967 969
        e.id = a / 2;
968 970
        d = ((a & 1) == 1);
969 971
      } else {
970 972
        e.id = -1;
971 973
        d = true;
972 974
      }
973 975
    }
974 976
    void nextInc(Edge &e, bool& d) const {
975 977
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
976 978
      if (a != -1 ) {
977 979
        e.id = a / 2;
978 980
        d = ((a & 1) == 1);
979 981
      } else {
980 982
        e.id = -1;
981 983
        d = true;
982 984
      }
983 985
    }
984 986

	
985 987
    static int id(Node v) { return v.id; }
986 988
    static int id(Arc e) { return e.id; }
987 989
    static int id(Edge e) { return e.id; }
988 990

	
989 991
    static Node nodeFromId(int id) { return Node(id);}
990 992
    static Arc arcFromId(int id) { return Arc(id);}
991 993
    static Edge edgeFromId(int id) { return Edge(id);}
992 994

	
993 995
    bool valid(Node n) const {
994 996
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
995 997
        nodes[n.id].prev != -2;
996 998
    }
997 999

	
998 1000
    bool valid(Arc a) const {
999 1001
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
1000 1002
        arcs[a.id].prev_out != -2;
1001 1003
    }
1002 1004

	
1003 1005
    bool valid(Edge e) const {
1004 1006
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1005 1007
        arcs[2 * e.id].prev_out != -2;
1006 1008
    }
1007 1009

	
1008 1010
    Node addNode() {
1009 1011
      int n;
1010 1012

	
1011 1013
      if(first_free_node==-1) {
1012 1014
        n = nodes.size();
1013 1015
        nodes.push_back(NodeT());
1014 1016
      } else {
1015 1017
        n = first_free_node;
1016 1018
        first_free_node = nodes[n].next;
1017 1019
      }
1018 1020

	
1019 1021
      nodes[n].next = first_node;
1020 1022
      if (first_node != -1) nodes[first_node].prev = n;
1021 1023
      first_node = n;
1022 1024
      nodes[n].prev = -1;
1023 1025

	
1024 1026
      nodes[n].first_out = -1;
1025 1027

	
1026 1028
      return Node(n);
1027 1029
    }
1028 1030

	
1029 1031
    Edge addEdge(Node u, Node v) {
1030 1032
      int n;
1031 1033

	
1032 1034
      if (first_free_arc == -1) {
1033 1035
        n = arcs.size();
1034 1036
        arcs.push_back(ArcT());
1035 1037
        arcs.push_back(ArcT());
1036 1038
      } else {
1037 1039
        n = first_free_arc;
1038 1040
        first_free_arc = arcs[n].next_out;
1039 1041
      }
1040 1042

	
1041 1043
      arcs[n].target = u.id;
1042 1044
      arcs[n | 1].target = v.id;
1043 1045

	
1044 1046
      arcs[n].next_out = nodes[v.id].first_out;
1045 1047
      if (nodes[v.id].first_out != -1) {
1046 1048
        arcs[nodes[v.id].first_out].prev_out = n;
1047 1049
      }
1048 1050
      arcs[n].prev_out = -1;
1049 1051
      nodes[v.id].first_out = n;
1050 1052

	
1051 1053
      arcs[n | 1].next_out = nodes[u.id].first_out;
1052 1054
      if (nodes[u.id].first_out != -1) {
1053 1055
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1054 1056
      }
1055 1057
      arcs[n | 1].prev_out = -1;
1056 1058
      nodes[u.id].first_out = (n | 1);
1057 1059

	
1058 1060
      return Edge(n / 2);
1059 1061
    }
1060 1062

	
1061 1063
    void erase(const Node& node) {
1062 1064
      int n = node.id;
1063 1065

	
1064 1066
      if(nodes[n].next != -1) {
1065 1067
        nodes[nodes[n].next].prev = nodes[n].prev;
1066 1068
      }
1067 1069

	
1068 1070
      if(nodes[n].prev != -1) {
1069 1071
        nodes[nodes[n].prev].next = nodes[n].next;
1070 1072
      } else {
1071 1073
        first_node = nodes[n].next;
1072 1074
      }
1073 1075

	
1074 1076
      nodes[n].next = first_free_node;
1075 1077
      first_free_node = n;
1076 1078
      nodes[n].prev = -2;
1077 1079
    }
1078 1080

	
1079 1081
    void erase(const Edge& edge) {
1080 1082
      int n = edge.id * 2;
1081 1083

	
1082 1084
      if (arcs[n].next_out != -1) {
1083 1085
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1084 1086
      }
1085 1087

	
1086 1088
      if (arcs[n].prev_out != -1) {
1087 1089
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1088 1090
      } else {
1089 1091
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1090 1092
      }
1091 1093

	
1092 1094
      if (arcs[n | 1].next_out != -1) {
1093 1095
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1094 1096
      }
1095 1097

	
1096 1098
      if (arcs[n | 1].prev_out != -1) {
1097 1099
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1098 1100
      } else {
1099 1101
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1100 1102
      }
1101 1103

	
1102 1104
      arcs[n].next_out = first_free_arc;
1103 1105
      first_free_arc = n;
1104 1106
      arcs[n].prev_out = -2;
1105 1107
      arcs[n | 1].prev_out = -2;
1106 1108

	
1107 1109
    }
1108 1110

	
1109 1111
    void clear() {
1110 1112
      arcs.clear();
1111 1113
      nodes.clear();
1112 1114
      first_node = first_free_node = first_free_arc = -1;
1113 1115
    }
1114 1116

	
1115 1117
  protected:
1116 1118

	
1117 1119
    void changeV(Edge e, Node n) {
1118 1120
      if(arcs[2 * e.id].next_out != -1) {
1119 1121
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1120 1122
      }
1121 1123
      if(arcs[2 * e.id].prev_out != -1) {
1122 1124
        arcs[arcs[2 * e.id].prev_out].next_out =
1123 1125
          arcs[2 * e.id].next_out;
1124 1126
      } else {
1125 1127
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1126 1128
          arcs[2 * e.id].next_out;
1127 1129
      }
1128 1130

	
1129 1131
      if (nodes[n.id].first_out != -1) {
1130 1132
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1131 1133
      }
1132 1134
      arcs[(2 * e.id) | 1].target = n.id;
1133 1135
      arcs[2 * e.id].prev_out = -1;
1134 1136
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1135 1137
      nodes[n.id].first_out = 2 * e.id;
1136 1138
    }
1137 1139

	
1138 1140
    void changeU(Edge e, Node n) {
1139 1141
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1140 1142
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1141 1143
          arcs[(2 * e.id) | 1].prev_out;
1142 1144
      }
1143 1145
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1144 1146
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1145 1147
          arcs[(2 * e.id) | 1].next_out;
1146 1148
      } else {
1147 1149
        nodes[arcs[2 * e.id].target].first_out =
1148 1150
          arcs[(2 * e.id) | 1].next_out;
1149 1151
      }
1150 1152

	
1151 1153
      if (nodes[n.id].first_out != -1) {
1152 1154
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1153 1155
      }
1154 1156
      arcs[2 * e.id].target = n.id;
1155 1157
      arcs[(2 * e.id) | 1].prev_out = -1;
1156 1158
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1157 1159
      nodes[n.id].first_out = ((2 * e.id) | 1);
1158 1160
    }
1159 1161

	
1160 1162
  };
1161 1163

	
1162 1164
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1163 1165

	
1164 1166

	
1165 1167
  /// \addtogroup graphs
1166 1168
  /// @{
1167 1169

	
1168 1170
  ///A general undirected graph structure.
1169 1171

	
1170 1172
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1171 1173
  ///implementation based on static linked lists that are stored in
1172 1174
  ///\c std::vector structures.
1173 1175
  ///
1174 1176
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1175 1177
  ///also provides several useful additional functionalities.
1176 1178
  ///Most of the member functions and nested classes are documented
1177 1179
  ///only in the concept class.
1178 1180
  ///
1179 1181
  ///An important extra feature of this graph implementation is that
1180 1182
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1181 1183
  ///
1182 1184
  ///\sa concepts::Graph
1183 1185

	
1184 1186
  class ListGraph : public ExtendedListGraphBase {
1185 1187
  private:
1186 1188
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1187 1189

	
1188 1190
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1189 1191
    ///
1190 1192
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1191 1193
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1192 1194
    ///Use copyGraph() instead.
1193 1195

	
1194 1196
    ///Assignment of ListGraph to another one is \e not allowed.
1195 1197
    ///Use copyGraph() instead.
1196 1198
    void operator=(const ListGraph &) {}
1197 1199
  public:
1198 1200
    /// Constructor
1199 1201

	
1200 1202
    /// Constructor.
1201 1203
    ///
1202 1204
    ListGraph() {}
1203 1205

	
1204 1206
    typedef ExtendedListGraphBase Parent;
1205 1207

	
1206 1208
    typedef Parent::OutArcIt IncEdgeIt;
1207 1209

	
1208 1210
    /// \brief Add a new node to the graph.
1209 1211
    ///
1210 1212
    /// Add a new node to the graph.
1211 1213
    /// \return the new node.
1212 1214
    Node addNode() { return Parent::addNode(); }
1213 1215

	
1214 1216
    /// \brief Add a new edge to the graph.
1215 1217
    ///
1216 1218
    /// Add a new edge to the graph with source node \c s
1217 1219
    /// and target node \c t.
1218 1220
    /// \return the new edge.
1219 1221
    Edge addEdge(const Node& s, const Node& t) {
1220 1222
      return Parent::addEdge(s, t);
1221 1223
    }
1222 1224

	
1223 1225
    /// \brief Erase a node from the graph.
1224 1226
    ///
1225 1227
    /// Erase a node from the graph.
1226 1228
    ///
1227 1229
    void erase(const Node& n) { Parent::erase(n); }
1228 1230

	
1229 1231
    /// \brief Erase an edge from the graph.
1230 1232
    ///
1231 1233
    /// Erase an edge from the graph.
1232 1234
    ///
1233 1235
    void erase(const Edge& e) { Parent::erase(e); }
1234 1236
    /// Node validity check
1235 1237

	
1236 1238
    /// This function gives back true if the given node is valid,
1237 1239
    /// ie. it is a real node of the graph.
1238 1240
    ///
1239 1241
    /// \warning A Node pointing to a removed item
1240 1242
    /// could become valid again later if new nodes are
1241 1243
    /// added to the graph.
1242 1244
    bool valid(Node n) const { return Parent::valid(n); }
1243 1245
    /// Arc validity check
1244 1246

	
1245 1247
    /// This function gives back true if the given arc is valid,
1246 1248
    /// ie. it is a real arc of the graph.
1247 1249
    ///
1248 1250
    /// \warning An Arc pointing to a removed item
1249 1251
    /// could become valid again later if new edges are
1250 1252
    /// added to the graph.
1251 1253
    bool valid(Arc a) const { return Parent::valid(a); }
1252 1254
    /// Edge validity check
1253 1255

	
1254 1256
    /// This function gives back true if the given edge is valid,
1255 1257
    /// ie. it is a real arc of the graph.
1256 1258
    ///
1257 1259
    /// \warning A Edge pointing to a removed item
1258 1260
    /// could become valid again later if new edges are
1259 1261
    /// added to the graph.
1260 1262
    bool valid(Edge e) const { return Parent::valid(e); }
1261 1263
    /// \brief Change the end \c u of \c e to \c n
1262 1264
    ///
1263 1265
    /// This function changes the end \c u of \c e to node \c n.
1264 1266
    ///
1265 1267
    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
1266 1268
    ///changed edge are invalidated and if the changed node is the
1267 1269
    ///base node of an iterator then this iterator is also
1268 1270
    ///invalidated.
1269 1271
    ///
1270 1272
    ///\warning This functionality cannot be used together with the
1271 1273
    ///Snapshot feature.
1272 1274
    void changeU(Edge e, Node n) {
1273 1275
      Parent::changeU(e,n);
1274 1276
    }
1275 1277
    /// \brief Change the end \c v of \c e to \c n
1276 1278
    ///
1277 1279
    /// This function changes the end \c v of \c e to \c n.
1278 1280
    ///
1279 1281
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
1280 1282
    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
1281 1283
    ///base node of an iterator then this iterator is invalidated.
1282 1284
    ///
1283 1285
    ///\warning This functionality cannot be used together with the
1284 1286
    ///Snapshot feature.
1285 1287
    void changeV(Edge e, Node n) {
1286 1288
      Parent::changeV(e,n);
1287 1289
    }
1288 1290
    /// \brief Contract two nodes.
1289 1291
    ///
1290 1292
    /// This function contracts two nodes.
1291 1293
    /// Node \p b will be removed but instead of deleting
1292 1294
    /// its neighboring arcs, they will be joined to \p a.
1293 1295
    /// The last parameter \p r controls whether to remove loops. \c true
1294 1296
    /// means that loops will be removed.
1295 1297
    ///
1296 1298
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1297 1299
    /// valid.
1298 1300
    ///
1299 1301
    ///\warning This functionality cannot be used together with the
1300 1302
    ///Snapshot feature.
1301 1303
    void contract(Node a, Node b, bool r = true) {
1302 1304
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1303 1305
        IncEdgeIt f = e; ++f;
1304 1306
        if (r && runningNode(e) == a) {
1305 1307
          erase(e);
1306 1308
        } else if (u(e) == b) {
1307 1309
          changeU(e, a);
1308 1310
        } else {
1309 1311
          changeV(e, a);
1310 1312
        }
1311 1313
        e = f;
1312 1314
      }
1313 1315
      erase(b);
1314 1316
    }
1315 1317

	
1316 1318

	
1317 1319
    /// \brief Class to make a snapshot of the graph and restore
1318 1320
    /// it later.
1319 1321
    ///
1320 1322
    /// Class to make a snapshot of the graph and restore it later.
1321 1323
    ///
1322 1324
    /// The newly added nodes and edges can be removed
1323 1325
    /// using the restore() function.
1324 1326
    ///
1325 1327
    /// \warning Edge and node deletions and other modifications
1326 1328
    /// (e.g. changing nodes of edges, contracting nodes) cannot be
1327 1329
    /// restored. These events invalidate the snapshot.
1328 1330
    class Snapshot {
1329 1331
    protected:
1330 1332

	
1331 1333
      typedef Parent::NodeNotifier NodeNotifier;
1332 1334

	
1333 1335
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1334 1336
      public:
1335 1337

	
1336 1338
        NodeObserverProxy(Snapshot& _snapshot)
1337 1339
          : snapshot(_snapshot) {}
1338 1340

	
1339 1341
        using NodeNotifier::ObserverBase::attach;
1340 1342
        using NodeNotifier::ObserverBase::detach;
1341 1343
        using NodeNotifier::ObserverBase::attached;
1342 1344

	
1343 1345
      protected:
1344 1346

	
1345 1347
        virtual void add(const Node& node) {
1346 1348
          snapshot.addNode(node);
1347 1349
        }
1348 1350
        virtual void add(const std::vector<Node>& nodes) {
1349 1351
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1350 1352
            snapshot.addNode(nodes[i]);
1351 1353
          }
1352 1354
        }
1353 1355
        virtual void erase(const Node& node) {
1354 1356
          snapshot.eraseNode(node);
1355 1357
        }
1356 1358
        virtual void erase(const std::vector<Node>& nodes) {
1357 1359
          for (int i = 0; i < int(nodes.size()); ++i) {
1358 1360
            snapshot.eraseNode(nodes[i]);
1359 1361
          }
1360 1362
        }
1361 1363
        virtual void build() {
1362 1364
          Node node;
1363 1365
          std::vector<Node> nodes;
1364 1366
          for (notifier()->first(node); node != INVALID;
1365 1367
               notifier()->next(node)) {
1366 1368
            nodes.push_back(node);
1367 1369
          }
1368 1370
          for (int i = nodes.size() - 1; i >= 0; --i) {
1369 1371
            snapshot.addNode(nodes[i]);
1370 1372
          }
1371 1373
        }
1372 1374
        virtual void clear() {
1373 1375
          Node node;
1374 1376
          for (notifier()->first(node); node != INVALID;
1375 1377
               notifier()->next(node)) {
1376 1378
            snapshot.eraseNode(node);
1377 1379
          }
1378 1380
        }
1379 1381

	
1380 1382
        Snapshot& snapshot;
1381 1383
      };
1382 1384

	
1383 1385
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1384 1386
      public:
1385 1387

	
1386 1388
        EdgeObserverProxy(Snapshot& _snapshot)
1387 1389
          : snapshot(_snapshot) {}
1388 1390

	
1389 1391
        using EdgeNotifier::ObserverBase::attach;
1390 1392
        using EdgeNotifier::ObserverBase::detach;
1391 1393
        using EdgeNotifier::ObserverBase::attached;
1392 1394

	
1393 1395
      protected:
1394 1396

	
1395 1397
        virtual void add(const Edge& edge) {
1396 1398
          snapshot.addEdge(edge);
1397 1399
        }
1398 1400
        virtual void add(const std::vector<Edge>& edges) {
1399 1401
          for (int i = edges.size() - 1; i >= 0; ++i) {
1400 1402
            snapshot.addEdge(edges[i]);
1401 1403
          }
1402 1404
        }
1403 1405
        virtual void erase(const Edge& edge) {
1404 1406
          snapshot.eraseEdge(edge);
1405 1407
        }
1406 1408
        virtual void erase(const std::vector<Edge>& edges) {
1407 1409
          for (int i = 0; i < int(edges.size()); ++i) {
1408 1410
            snapshot.eraseEdge(edges[i]);
1409 1411
          }
1410 1412
        }
1411 1413
        virtual void build() {
1412 1414
          Edge edge;
1413 1415
          std::vector<Edge> edges;
1414 1416
          for (notifier()->first(edge); edge != INVALID;
1415 1417
               notifier()->next(edge)) {
1416 1418
            edges.push_back(edge);
1417 1419
          }
1418 1420
          for (int i = edges.size() - 1; i >= 0; --i) {
1419 1421
            snapshot.addEdge(edges[i]);
1420 1422
          }
1421 1423
        }
1422 1424
        virtual void clear() {
1423 1425
          Edge edge;
1424 1426
          for (notifier()->first(edge); edge != INVALID;
1425 1427
               notifier()->next(edge)) {
1426 1428
            snapshot.eraseEdge(edge);
1427 1429
          }
1428 1430
        }
1429 1431

	
1430 1432
        Snapshot& snapshot;
1431 1433
      };
1432 1434

	
1433 1435
      ListGraph *graph;
1434 1436

	
1435 1437
      NodeObserverProxy node_observer_proxy;
1436 1438
      EdgeObserverProxy edge_observer_proxy;
1437 1439

	
1438 1440
      std::list<Node> added_nodes;
1439 1441
      std::list<Edge> added_edges;
1440 1442

	
1441 1443

	
1442 1444
      void addNode(const Node& node) {
1443 1445
        added_nodes.push_front(node);
1444 1446
      }
1445 1447
      void eraseNode(const Node& node) {
1446 1448
        std::list<Node>::iterator it =
1447 1449
          std::find(added_nodes.begin(), added_nodes.end(), node);
1448 1450
        if (it == added_nodes.end()) {
1449 1451
          clear();
1450 1452
          edge_observer_proxy.detach();
1451 1453
          throw NodeNotifier::ImmediateDetach();
1452 1454
        } else {
1453 1455
          added_nodes.erase(it);
1454 1456
        }
1455 1457
      }
1456 1458

	
1457 1459
      void addEdge(const Edge& edge) {
1458 1460
        added_edges.push_front(edge);
1459 1461
      }
1460 1462
      void eraseEdge(const Edge& edge) {
1461 1463
        std::list<Edge>::iterator it =
1462 1464
          std::find(added_edges.begin(), added_edges.end(), edge);
1463 1465
        if (it == added_edges.end()) {
1464 1466
          clear();
1465 1467
          node_observer_proxy.detach();
1466 1468
          throw EdgeNotifier::ImmediateDetach();
1467 1469
        } else {
1468 1470
          added_edges.erase(it);
1469 1471
        }
1470 1472
      }
1471 1473

	
1472 1474
      void attach(ListGraph &_graph) {
1473 1475
        graph = &_graph;
1474 1476
        node_observer_proxy.attach(graph->notifier(Node()));
1475 1477
        edge_observer_proxy.attach(graph->notifier(Edge()));
1476 1478
      }
1477 1479

	
1478 1480
      void detach() {
1479 1481
        node_observer_proxy.detach();
1480 1482
        edge_observer_proxy.detach();
1481 1483
      }
1482 1484

	
1483 1485
      bool attached() const {
1484 1486
        return node_observer_proxy.attached();
1485 1487
      }
1486 1488

	
1487 1489
      void clear() {
1488 1490
        added_nodes.clear();
1489 1491
        added_edges.clear();
1490 1492
      }
1491 1493

	
1492 1494
    public:
1493 1495

	
1494 1496
      /// \brief Default constructor.
1495 1497
      ///
1496 1498
      /// Default constructor.
1497 1499
      /// To actually make a snapshot you must call save().
1498 1500
      Snapshot()
1499 1501
        : graph(0), node_observer_proxy(*this),
1500 1502
          edge_observer_proxy(*this) {}
1501 1503

	
1502 1504
      /// \brief Constructor that immediately makes a snapshot.
1503 1505
      ///
1504 1506
      /// This constructor immediately makes a snapshot of the graph.
1505 1507
      /// \param _graph The graph we make a snapshot of.
1506 1508
      Snapshot(ListGraph &_graph)
1507 1509
        : node_observer_proxy(*this),
1508 1510
          edge_observer_proxy(*this) {
1509 1511
        attach(_graph);
1510 1512
      }
1511 1513

	
1512 1514
      /// \brief Make a snapshot.
1513 1515
      ///
1514 1516
      /// Make a snapshot of the graph.
1515 1517
      ///
1516 1518
      /// This function can be called more than once. In case of a repeated
1517 1519
      /// call, the previous snapshot gets lost.
1518 1520
      /// \param _graph The graph we make the snapshot of.
1519 1521
      void save(ListGraph &_graph) {
1520 1522
        if (attached()) {
1521 1523
          detach();
1522 1524
          clear();
1523 1525
        }
1524 1526
        attach(_graph);
1525 1527
      }
1526 1528

	
1527 1529
      /// \brief Undo the changes until the last snapshot.
1528 1530
      //
1529 1531
      /// Undo the changes until the last snapshot created by save().
1530 1532
      void restore() {
1531 1533
        detach();
1532 1534
        for(std::list<Edge>::iterator it = added_edges.begin();
1533 1535
            it != added_edges.end(); ++it) {
1534 1536
          graph->erase(*it);
1535 1537
        }
1536 1538
        for(std::list<Node>::iterator it = added_nodes.begin();
1537 1539
            it != added_nodes.end(); ++it) {
1538 1540
          graph->erase(*it);
1539 1541
        }
1540 1542
        clear();
1541 1543
      }
1542 1544

	
1543 1545
      /// \brief Gives back true when the snapshot is valid.
1544 1546
      ///
1545 1547
      /// Gives back true when the snapshot is valid.
1546 1548
      bool valid() const {
1547 1549
        return attached();
1548 1550
      }
1549 1551
    };
1550 1552
  };
1551 1553

	
1552 1554
  /// @}
1553 1555
} //namespace lemon
1554 1556

	
1555 1557

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

	
19 19
///\ingroup paths
20 20
///\file
21 21
///\brief Classes for representing paths in digraphs.
22 22
///
23 23

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

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

	
30 30
#include <lemon/error.h>
31 31
#include <lemon/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
      copyPath(*this, cpath);
74 74
    }
75 75

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

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

	
99 99
    private:
100 100

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

	
104 104
    public:
105 105

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
202 202
    typedef True BuildTag;
203 203

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

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

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

	
226 226
  };
227 227

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

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

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

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

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

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

	
290 290
    private:
291 291

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

	
296 296
    public:
297 297

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

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

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

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

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

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

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

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

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

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

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

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

	
362 362
    typedef True BuildTag;
363 363

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

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

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

	
390 390
  };
391 391

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

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

	
414 414
  protected:
415 415

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

	
423 423
    Node *first, *last;
424 424

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

	
427 427
  public:
428 428

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

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

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

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

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

	
476 476
    protected:
477 477

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

	
481 481

	
482 482
    public:
483 483

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
713 713

	
714 714
    typedef True BuildTag;
715 715

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

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

	
730 730
  };
731 731

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

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

	
756 756
    /// \brief Default constructor
757 757
    ///
758 758
    /// Default constructor
759 759
    StaticPath() : len(0), arcs(0) {}
760 760

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

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

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

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

	
802 802
    private:
803 803

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

	
808 808
    public:
809 809

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

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

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

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

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

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

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

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

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

	
19 19
#ifndef LEMON_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
    }
102 102

	
103 103
    Node source(Arc a) const { return Node(arcs[a._id].source); }
104 104
    Node target(Arc a) const { return Node(arcs[a._id].target); }
105 105

	
106 106
    static int id(Node v) { return v._id; }
107 107
    static int id(Arc a) { return a._id; }
108 108

	
109 109
    static Node nodeFromId(int id) { return Node(id);}
110 110
    static Arc arcFromId(int id) { return Arc(id);}
111 111

	
112 112
    bool valid(Node n) const {
113 113
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
114 114
    }
115 115
    bool valid(Arc a) const {
116 116
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
117 117
    }
118 118

	
119 119
    class Node {
120 120
      friend class SmartDigraphBase;
121 121
      friend class SmartDigraph;
122 122

	
123 123
    protected:
124 124
      int _id;
125 125
      explicit Node(int id) : _id(id) {}
126 126
    public:
127 127
      Node() {}
128 128
      Node (Invalid) : _id(-1) {}
129 129
      bool operator==(const Node i) const {return _id == i._id;}
130 130
      bool operator!=(const Node i) const {return _id != i._id;}
131 131
      bool operator<(const Node i) const {return _id < i._id;}
132 132
    };
133 133

	
134 134

	
135 135
    class Arc {
136 136
      friend class SmartDigraphBase;
137 137
      friend class SmartDigraph;
138 138

	
139 139
    protected:
140 140
      int _id;
141 141
      explicit Arc(int id) : _id(id) {}
142 142
    public:
143 143
      Arc() { }
144 144
      Arc (Invalid) : _id(-1) {}
145 145
      bool operator==(const Arc i) const {return _id == i._id;}
146 146
      bool operator!=(const Arc i) const {return _id != i._id;}
147 147
      bool operator<(const Arc i) const {return _id < i._id;}
148 148
    };
149 149

	
150 150
    void first(Node& node) const {
151 151
      node._id = nodes.size() - 1;
152 152
    }
153 153

	
154 154
    static void next(Node& node) {
155 155
      --node._id;
156 156
    }
157 157

	
158 158
    void first(Arc& arc) const {
159 159
      arc._id = arcs.size() - 1;
160 160
    }
161 161

	
162 162
    static void next(Arc& arc) {
163 163
      --arc._id;
164 164
    }
165 165

	
166 166
    void firstOut(Arc& arc, const Node& node) const {
167 167
      arc._id = nodes[node._id].first_out;
168 168
    }
169 169

	
170 170
    void nextOut(Arc& arc) const {
171 171
      arc._id = arcs[arc._id].next_out;
172 172
    }
173 173

	
174 174
    void firstIn(Arc& arc, const Node& node) const {
175 175
      arc._id = nodes[node._id].first_in;
176 176
    }
177 177

	
178 178
    void nextIn(Arc& arc) const {
179 179
      arc._id = arcs[arc._id].next_in;
180 180
    }
181 181

	
182 182
  };
183 183

	
184 184
  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
185 185

	
186 186
  ///\ingroup graphs
187 187
  ///
188 188
  ///\brief A smart directed graph class.
189 189
  ///
190 190
  ///This is a simple and fast digraph implementation.
191 191
  ///It is also quite memory efficient, but at the price
192 192
  ///that <b> it does support only limited (only stack-like)
193 193
  ///node and arc deletions</b>.
194 194
  ///It conforms to the \ref concepts::Digraph "Digraph concept" with
195 195
  ///an important extra feature that its maps are real \ref
196 196
  ///concepts::ReferenceMap "reference map"s.
197 197
  ///
198 198
  ///\sa concepts::Digraph.
199 199
  class SmartDigraph : public ExtendedSmartDigraphBase {
200 200
  public:
201 201

	
202 202
    typedef ExtendedSmartDigraphBase Parent;
203 203

	
204 204
  private:
205 205

	
206 206
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
207 207

	
208 208
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
209 209
    ///
210 210
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
211 211
    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
212 212
    ///Use DigraphCopy() instead.
213 213

	
214 214
    ///Assignment of SmartDigraph to another one is \e not allowed.
215 215
    ///Use DigraphCopy() instead.
216 216
    void operator=(const SmartDigraph &) {}
217 217

	
218 218
  public:
219 219

	
220 220
    /// Constructor
221 221

	
222 222
    /// Constructor.
223 223
    ///
224 224
    SmartDigraph() {};
225 225

	
226 226
    ///Add a new node to the digraph.
227 227

	
228 228
    /// \return the new node.
229 229
    ///
230 230
    Node addNode() { return Parent::addNode(); }
231 231

	
232 232
    ///Add a new arc to the digraph.
233 233

	
234 234
    ///Add a new arc to the digraph with source node \c s
235 235
    ///and target node \c t.
236 236
    ///\return the new arc.
237 237
    Arc addArc(const Node& s, const Node& t) {
238 238
      return Parent::addArc(s, t);
239 239
    }
240 240

	
241 241
    /// \brief Using this it is possible to avoid the superfluous memory
242 242
    /// allocation.
243 243

	
244 244
    /// Using this it is possible to avoid the superfluous memory
245 245
    /// allocation: if you know that the digraph you want to build will
246 246
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
247 247
    /// then it is worth reserving space for this amount before starting
248 248
    /// to build the digraph.
249 249
    /// \sa reserveArc
250 250
    void reserveNode(int n) { nodes.reserve(n); };
251 251

	
252 252
    /// \brief Using this it is possible to avoid the superfluous memory
253 253
    /// allocation.
254 254

	
255 255
    /// Using this it is possible to avoid the superfluous memory
256 256
    /// allocation: if you know that the digraph you want to build will
257 257
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
258 258
    /// then it is worth reserving space for this amount before starting
259 259
    /// to build the digraph.
260 260
    /// \sa reserveNode
261 261
    void reserveArc(int m) { arcs.reserve(m); };
262 262

	
263 263
    /// \brief Node validity check
264 264
    ///
265 265
    /// This function gives back true if the given node is valid,
266 266
    /// ie. it is a real node of the graph.
267 267
    ///
268 268
    /// \warning A removed node (using Snapshot) could become valid again
269 269
    /// when new nodes are added to the graph.
270 270
    bool valid(Node n) const { return Parent::valid(n); }
271 271

	
272 272
    /// \brief Arc validity check
273 273
    ///
274 274
    /// This function gives back true if the given arc is valid,
275 275
    /// ie. it is a real arc of the graph.
276 276
    ///
277 277
    /// \warning A removed arc (using Snapshot) could become valid again
278 278
    /// when new arcs are added to the graph.
279 279
    bool valid(Arc a) const { return Parent::valid(a); }
280 280

	
281 281
    ///Clear the digraph.
282 282

	
283 283
    ///Erase all the nodes and arcs from the digraph.
284 284
    ///
285 285
    void clear() {
286 286
      Parent::clear();
287 287
    }
288 288

	
289 289
    ///Split a node.
290 290

	
291 291
    ///This function splits a node. First a new node is added to the digraph,
292 292
    ///then the source of each outgoing arc of \c n is moved to this new node.
293 293
    ///If \c connect is \c true (this is the default value), then a new arc
294 294
    ///from \c n to the newly created node is also added.
295 295
    ///\return The newly created node.
296 296
    ///
297 297
    ///\note The <tt>Arc</tt>s
298 298
    ///referencing a moved arc remain
299 299
    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
300 300
    ///may be invalidated.
301 301
    ///\warning This functionality cannot be used together with the Snapshot
302 302
    ///feature.
303 303
    ///\todo It could be implemented in a bit faster way.
304 304
    Node split(Node n, bool connect = true)
305 305
    {
306 306
      Node b = addNode();
307 307
      nodes[b._id].first_out=nodes[n._id].first_out;
308 308
      nodes[n._id].first_out=-1;
309 309
      for(int i=nodes[b._id].first_out;i!=-1;i++) arcs[i].source=b._id;
310 310
      if(connect) addArc(n,b);
311 311
      return b;
312 312
    }
313 313

	
314 314
  public:
315 315

	
316 316
    class Snapshot;
317 317

	
318 318
  protected:
319 319

	
320 320
    void restoreSnapshot(const Snapshot &s)
321 321
    {
322 322
      while(s.arc_num<arcs.size()) {
323 323
        Arc arc = arcFromId(arcs.size()-1);
324 324
        Parent::notifier(Arc()).erase(arc);
325 325
        nodes[arcs.back().source].first_out=arcs.back().next_out;
326 326
        nodes[arcs.back().target].first_in=arcs.back().next_in;
327 327
        arcs.pop_back();
328 328
      }
329 329
      while(s.node_num<nodes.size()) {
330 330
        Node node = nodeFromId(nodes.size()-1);
331 331
        Parent::notifier(Node()).erase(node);
332 332
        nodes.pop_back();
333 333
      }
334 334
    }
335 335

	
336 336
  public:
337 337

	
338 338
    ///Class to make a snapshot of the digraph and to restrore to it later.
339 339

	
340 340
    ///Class to make a snapshot of the digraph and to restrore to it later.
341 341
    ///
342 342
    ///The newly added nodes and arcs can be removed using the
343 343
    ///restore() function.
344 344
    ///\note After you restore a state, you cannot restore
345 345
    ///a later state, in other word you cannot add again the arcs deleted
346 346
    ///by restore() using another one Snapshot instance.
347 347
    ///
348 348
    ///\warning If you do not use correctly the snapshot that can cause
349 349
    ///either broken program, invalid state of the digraph, valid but
350 350
    ///not the restored digraph or no change. Because the runtime performance
351 351
    ///the validity of the snapshot is not stored.
352 352
    class Snapshot
353 353
    {
354 354
      SmartDigraph *_graph;
355 355
    protected:
356 356
      friend class SmartDigraph;
357 357
      unsigned int node_num;
358 358
      unsigned int arc_num;
359 359
    public:
360 360
      ///Default constructor.
361 361

	
362 362
      ///Default constructor.
363 363
      ///To actually make a snapshot you must call save().
364 364
      ///
365 365
      Snapshot() : _graph(0) {}
366 366
      ///Constructor that immediately makes a snapshot
367 367

	
368 368
      ///This constructor immediately makes a snapshot of the digraph.
369 369
      ///\param _g The digraph we make a snapshot of.
370 370
      Snapshot(SmartDigraph &graph) : _graph(&graph) {
371 371
        node_num=_graph->nodes.size();
372 372
        arc_num=_graph->arcs.size();
373 373
      }
374 374

	
375 375
      ///Make a snapshot.
376 376

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

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

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

	
403 403

	
404 404
  class SmartGraphBase {
405 405

	
406 406
  protected:
407 407

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

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

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

	
420 420
    int first_free_arc;
421 421

	
422 422
  public:
423 423

	
424 424
    typedef SmartGraphBase Digraph;
425 425

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

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

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

	
437 437
    public:
438 438
      Node() {}
439 439
      Node (Invalid) { _id = -1; }
440 440
      bool operator==(const Node& node) const {return _id == node._id;}
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
    };
444 444

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

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

	
452 452
    public:
453 453
      Edge() {}
454 454
      Edge (Invalid) { _id = -1; }
455 455
      bool operator==(const Edge& arc) const {return _id == arc._id;}
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
    };
459 459

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

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

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

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

	
477 479

	
478 480

	
479 481
    SmartGraphBase()
480 482
      : nodes(), arcs() {}
481 483

	
482 484

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
562 564
    static int id(Node v) { return v._id; }
563 565
    static int id(Arc e) { return e._id; }
564 566
    static int id(Edge e) { return e._id; }
565 567

	
566 568
    static Node nodeFromId(int id) { return Node(id);}
567 569
    static Arc arcFromId(int id) { return Arc(id);}
568 570
    static Edge edgeFromId(int id) { return Edge(id);}
569 571

	
570 572
    bool valid(Node n) const {
571 573
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
572 574
    }
573 575
    bool valid(Arc a) const {
574 576
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
575 577
    }
576 578
    bool valid(Edge e) const {
577 579
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
578 580
    }
579 581

	
580 582
    Node addNode() {
581 583
      int n = nodes.size();
582 584
      nodes.push_back(NodeT());
583 585
      nodes[n].first_out = -1;
584 586

	
585 587
      return Node(n);
586 588
    }
587 589

	
588 590
    Edge addEdge(Node u, Node v) {
589 591
      int n = arcs.size();
590 592
      arcs.push_back(ArcT());
591 593
      arcs.push_back(ArcT());
592 594

	
593 595
      arcs[n].target = u._id;
594 596
      arcs[n | 1].target = v._id;
595 597

	
596 598
      arcs[n].next_out = nodes[v._id].first_out;
597 599
      nodes[v._id].first_out = n;
598 600

	
599 601
      arcs[n | 1].next_out = nodes[u._id].first_out;
600 602
      nodes[u._id].first_out = (n | 1);
601 603

	
602 604
      return Edge(n / 2);
603 605
    }
604 606

	
605 607
    void clear() {
606 608
      arcs.clear();
607 609
      nodes.clear();
608 610
    }
609 611

	
610 612
  };
611 613

	
612 614
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
613 615

	
614 616
  /// \ingroup graphs
615 617
  ///
616 618
  /// \brief A smart undirected graph class.
617 619
  ///
618 620
  /// This is a simple and fast graph implementation.
619 621
  /// It is also quite memory efficient, but at the price
620 622
  /// that <b> it does support only limited (only stack-like)
621 623
  /// node and arc deletions</b>.
622 624
  /// Except from this it conforms to
623 625
  /// the \ref concepts::Graph "Graph concept".
624 626
  ///
625 627
  /// It also has an
626 628
  /// important extra feature that
627 629
  /// its maps are real \ref concepts::ReferenceMap "reference map"s.
628 630
  ///
629 631
  /// \sa concepts::Graph.
630 632
  ///
631 633
  class SmartGraph : public ExtendedSmartGraphBase {
632 634
  private:
633 635

	
634 636
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
635 637

	
636 638
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
637 639
    ///
638 640
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
639 641

	
640 642
    ///\brief Assignment of SmartGraph to another one is \e not allowed.
641 643
    ///Use GraphCopy() instead.
642 644

	
643 645
    ///Assignment of SmartGraph to another one is \e not allowed.
644 646
    ///Use GraphCopy() instead.
645 647
    void operator=(const SmartGraph &) {}
646 648

	
647 649
  public:
648 650

	
649 651
    typedef ExtendedSmartGraphBase Parent;
650 652

	
651 653
    /// Constructor
652 654

	
653 655
    /// Constructor.
654 656
    ///
655 657
    SmartGraph() {}
656 658

	
657 659
    ///Add a new node to the graph.
658 660

	
659 661
    /// \return the new node.
660 662
    ///
661 663
    Node addNode() { return Parent::addNode(); }
662 664

	
663 665
    ///Add a new edge to the graph.
664 666

	
665 667
    ///Add a new edge to the graph with node \c s
666 668
    ///and \c t.
667 669
    ///\return the new edge.
668 670
    Edge addEdge(const Node& s, const Node& t) {
669 671
      return Parent::addEdge(s, t);
670 672
    }
671 673

	
672 674
    /// \brief Node validity check
673 675
    ///
674 676
    /// This function gives back true if the given node is valid,
675 677
    /// ie. it is a real node of the graph.
676 678
    ///
677 679
    /// \warning A removed node (using Snapshot) could become valid again
678 680
    /// when new nodes are added to the graph.
679 681
    bool valid(Node n) const { return Parent::valid(n); }
680 682

	
681 683
    /// \brief Arc validity check
682 684
    ///
683 685
    /// This function gives back true if the given arc is valid,
684 686
    /// ie. it is a real arc of the graph.
685 687
    ///
686 688
    /// \warning A removed arc (using Snapshot) could become valid again
687 689
    /// when new edges are added to the graph.
688 690
    bool valid(Arc a) const { return Parent::valid(a); }
689 691

	
690 692
    /// \brief Edge validity check
691 693
    ///
692 694
    /// This function gives back true if the given edge is valid,
693 695
    /// ie. it is a real edge of the graph.
694 696
    ///
695 697
    /// \warning A removed edge (using Snapshot) could become valid again
696 698
    /// when new edges are added to the graph.
697 699
    bool valid(Edge e) const { return Parent::valid(e); }
698 700

	
699 701
    ///Clear the graph.
700 702

	
701 703
    ///Erase all the nodes and edges from the graph.
702 704
    ///
703 705
    void clear() {
704 706
      Parent::clear();
705 707
    }
706 708

	
707 709
  public:
708 710

	
709 711
    class Snapshot;
710 712

	
711 713
  protected:
712 714

	
713 715
    void saveSnapshot(Snapshot &s)
714 716
    {
715 717
      s._graph = this;
716 718
      s.node_num = nodes.size();
717 719
      s.arc_num = arcs.size();
718 720
    }
719 721

	
720 722
    void restoreSnapshot(const Snapshot &s)
721 723
    {
722 724
      while(s.arc_num<arcs.size()) {
723 725
        int n=arcs.size()-1;
724 726
        Edge arc=edgeFromId(n/2);
725 727
        Parent::notifier(Edge()).erase(arc);
726 728
        std::vector<Arc> dir;
727 729
        dir.push_back(arcFromId(n));
728 730
        dir.push_back(arcFromId(n-1));
729 731
        Parent::notifier(Arc()).erase(dir);
730 732
        nodes[arcs[n].target].first_out=arcs[n].next_out;
731 733
        nodes[arcs[n-1].target].first_out=arcs[n-1].next_out;
732 734
        arcs.pop_back();
733 735
        arcs.pop_back();
734 736
      }
735 737
      while(s.node_num<nodes.size()) {
736 738
        int n=nodes.size()-1;
737 739
        Node node = nodeFromId(n);
738 740
        Parent::notifier(Node()).erase(node);
739 741
        nodes.pop_back();
740 742
      }
741 743
    }
742 744

	
743 745
  public:
744 746

	
745 747
    ///Class to make a snapshot of the digraph and to restrore to it later.
746 748

	
747 749
    ///Class to make a snapshot of the digraph and to restrore to it later.
748 750
    ///
749 751
    ///The newly added nodes and arcs can be removed using the
750 752
    ///restore() function.
751 753
    ///
752 754
    ///\note After you restore a state, you cannot restore
753 755
    ///a later state, in other word you cannot add again the arcs deleted
754 756
    ///by restore() using another one Snapshot instance.
755 757
    ///
756 758
    ///\warning If you do not use correctly the snapshot that can cause
757 759
    ///either broken program, invalid state of the digraph, valid but
758 760
    ///not the restored digraph or no change. Because the runtime performance
759 761
    ///the validity of the snapshot is not stored.
760 762
    class Snapshot
761 763
    {
762 764
      SmartGraph *_graph;
763 765
    protected:
764 766
      friend class SmartGraph;
765 767
      unsigned int node_num;
766 768
      unsigned int arc_num;
767 769
    public:
768 770
      ///Default constructor.
769 771

	
770 772
      ///Default constructor.
771 773
      ///To actually make a snapshot you must call save().
772 774
      ///
773 775
      Snapshot() : _graph(0) {}
774 776
      ///Constructor that immediately makes a snapshot
775 777

	
776 778
      ///This constructor immediately makes a snapshot of the digraph.
777 779
      ///\param g The digraph we make a snapshot of.
778 780
      Snapshot(SmartGraph &graph) {
779 781
        graph.saveSnapshot(*this);
780 782
      }
781 783

	
782 784
      ///Make a snapshot.
783 785

	
784 786
      ///Make a snapshot of the graph.
785 787
      ///
786 788
      ///This function can be called more than once. In case of a repeated
787 789
      ///call, the previous snapshot gets lost.
788 790
      ///\param g The digraph we make the snapshot of.
789 791
      void save(SmartGraph &graph)
790 792
      {
791 793
        graph.saveSnapshot(*this);
792 794
      }
793 795

	
794 796
      ///Undo the changes until a snapshot.
795 797

	
796 798
      ///Undo the changes until a snapshot created by save().
797 799
      ///
798 800
      ///\note After you restored a state, you cannot restore
799 801
      ///a later state, in other word you cannot add again the arcs deleted
800 802
      ///by restore().
801 803
      void restore()
802 804
      {
803 805
        _graph->restoreSnapshot(*this);
804 806
      }
805 807
    };
806 808
  };
807 809

	
808 810
} //namespace lemon
809 811

	
810 812

	
811 813
#endif //LEMON_SMART_GRAPH_H

Changeset was too big and was cut off... Show full diff

0 comments (0 inline)