gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Fix the incorrect tab replacements of unify-sources.sh
0 11 0
default
11 files changed with 106 insertions and 116 deletions:
↑ Collapse diff ↑
Ignore white space 1536 line context
1 1
# Doxyfile 1.5.5
2 2

	
3 3
#---------------------------------------------------------------------------
4 4
# Project related configuration options
5 5
#---------------------------------------------------------------------------
6 6
DOXYFILE_ENCODING      = UTF-8
7 7
PROJECT_NAME           = @PACKAGE_NAME@
8 8
PROJECT_NUMBER         = @PACKAGE_VERSION@
9 9
OUTPUT_DIRECTORY       = 
10 10
CREATE_SUBDIRS         = NO
11 11
OUTPUT_LANGUAGE        = English
12 12
BRIEF_MEMBER_DESC      = YES
13 13
REPEAT_BRIEF           = NO
14 14
ABBREVIATE_BRIEF       = 
15 15
ALWAYS_DETAILED_SEC    = NO
16 16
INLINE_INHERITED_MEMB  = NO
17 17
FULL_PATH_NAMES        = YES
18 18
STRIP_FROM_PATH        = @abs_top_srcdir@
19 19
STRIP_FROM_INC_PATH    = @abs_top_srcdir@
20 20
SHORT_NAMES            = YES
21 21
JAVADOC_AUTOBRIEF      = NO
22 22
QT_AUTOBRIEF           = NO
23 23
MULTILINE_CPP_IS_BRIEF = NO
24 24
DETAILS_AT_TOP         = YES
25 25
INHERIT_DOCS           = NO
26 26
SEPARATE_MEMBER_PAGES  = NO
27 27
TAB_SIZE               = 8
28 28
ALIASES                = 
29 29
OPTIMIZE_OUTPUT_FOR_C  = NO
30 30
OPTIMIZE_OUTPUT_JAVA   = NO
31 31
OPTIMIZE_FOR_FORTRAN   = NO
32 32
OPTIMIZE_OUTPUT_VHDL   = NO
33 33
BUILTIN_STL_SUPPORT    = YES
34 34
CPP_CLI_SUPPORT        = NO
35 35
SIP_SUPPORT            = NO
36 36
DISTRIBUTE_GROUP_DOC   = NO
37 37
SUBGROUPING            = YES
38 38
TYPEDEF_HIDES_STRUCT   = NO
39 39
#---------------------------------------------------------------------------
40 40
# Build related configuration options
41 41
#---------------------------------------------------------------------------
42 42
EXTRACT_ALL            = NO
43 43
EXTRACT_PRIVATE        = YES
44 44
EXTRACT_STATIC         = YES
45 45
EXTRACT_LOCAL_CLASSES  = NO
46 46
EXTRACT_LOCAL_METHODS  = NO
47 47
EXTRACT_ANON_NSPACES   = NO
48 48
HIDE_UNDOC_MEMBERS     = YES
49 49
HIDE_UNDOC_CLASSES     = YES
50 50
HIDE_FRIEND_COMPOUNDS  = NO
51 51
HIDE_IN_BODY_DOCS      = NO
52 52
INTERNAL_DOCS          = NO
53 53
CASE_SENSE_NAMES       = YES
54 54
HIDE_SCOPE_NAMES       = YES
55 55
SHOW_INCLUDE_FILES     = YES
56 56
INLINE_INFO            = YES
57 57
SORT_MEMBER_DOCS       = NO
58 58
SORT_BRIEF_DOCS        = NO
59 59
SORT_GROUP_NAMES       = NO
60 60
SORT_BY_SCOPE_NAME     = NO
61 61
GENERATE_TODOLIST      = YES
62 62
GENERATE_TESTLIST      = YES
63 63
GENERATE_BUGLIST       = YES
64 64
GENERATE_DEPRECATEDLIST= YES
65 65
ENABLED_SECTIONS       = 
66 66
MAX_INITIALIZER_LINES  = 5
67 67
SHOW_USED_FILES        = YES
68 68
SHOW_DIRECTORIES       = YES
69 69
FILE_VERSION_FILTER    = 
70 70
#---------------------------------------------------------------------------
71 71
# configuration options related to warning and progress messages
72 72
#---------------------------------------------------------------------------
73 73
QUIET                  = NO
74 74
WARNINGS               = YES
75 75
WARN_IF_UNDOCUMENTED   = YES
76 76
WARN_IF_DOC_ERROR      = YES
77 77
WARN_NO_PARAMDOC       = NO
78 78
WARN_FORMAT            = "$file:$line: $text  "
79 79
WARN_LOGFILE           = doxygen.log
80 80
#---------------------------------------------------------------------------
81 81
# configuration options related to the input files
82 82
#---------------------------------------------------------------------------
83 83
INPUT                  = @abs_top_srcdir@/doc \
84 84
                         @abs_top_srcdir@/lemon \
85 85
                         @abs_top_srcdir@/lemon/bits \
86 86
                         @abs_top_srcdir@/lemon/concepts \
87 87
                         @abs_top_srcdir@/demo \
88 88
                         @abs_top_srcdir@/tools \
89 89
                         @abs_top_srcdir@/test/test_tools.h
90 90
INPUT_ENCODING         = UTF-8
91 91
FILE_PATTERNS          = *.h \
92 92
                         *.cc \
93 93
                         *.dox
94 94
RECURSIVE              = NO
95 95
EXCLUDE                = 
96 96
EXCLUDE_SYMLINKS       = NO
97 97
EXCLUDE_PATTERNS       = 
98 98
EXCLUDE_SYMBOLS        = 
99 99
EXAMPLE_PATH           = @abs_top_srcdir@/demo \
100 100
                         @abs_top_srcdir@/LICENSE \
101 101
                         @abs_top_srcdir@/doc
102 102
EXAMPLE_PATTERNS       = 
103 103
EXAMPLE_RECURSIVE      = NO
104 104
IMAGE_PATH             = @abs_top_srcdir@/doc/images \
105
		       	 @abs_top_builddir@/doc/gen-images
105
                         @abs_top_builddir@/doc/gen-images
106 106
INPUT_FILTER           = 
107 107
FILTER_PATTERNS        = 
108 108
FILTER_SOURCE_FILES    = NO
109 109
#---------------------------------------------------------------------------
110 110
# configuration options related to source browsing
111 111
#---------------------------------------------------------------------------
112 112
SOURCE_BROWSER         = NO
113 113
INLINE_SOURCES         = NO
114 114
STRIP_CODE_COMMENTS    = YES
115 115
REFERENCED_BY_RELATION = NO
116 116
REFERENCES_RELATION    = NO
117 117
REFERENCES_LINK_SOURCE = YES
118 118
USE_HTAGS              = NO
119 119
VERBATIM_HEADERS       = NO
120 120
#---------------------------------------------------------------------------
121 121
# configuration options related to the alphabetical class index
122 122
#---------------------------------------------------------------------------
123 123
ALPHABETICAL_INDEX     = YES
124 124
COLS_IN_ALPHA_INDEX    = 2
125 125
IGNORE_PREFIX          = 
126 126
#---------------------------------------------------------------------------
127 127
# configuration options related to the HTML output
128 128
#---------------------------------------------------------------------------
129 129
GENERATE_HTML          = YES
130 130
HTML_OUTPUT            = html
131 131
HTML_FILE_EXTENSION    = .html
132 132
HTML_HEADER            = 
133 133
HTML_FOOTER            = 
134 134
HTML_STYLESHEET        = 
135 135
HTML_ALIGN_MEMBERS     = YES
136 136
GENERATE_HTMLHELP      = NO
137 137
GENERATE_DOCSET        = NO
138 138
DOCSET_FEEDNAME        = "Doxygen generated docs"
139 139
DOCSET_BUNDLE_ID       = org.doxygen.Project
140 140
HTML_DYNAMIC_SECTIONS  = NO
141 141
CHM_FILE               = 
142 142
HHC_LOCATION           = 
143 143
GENERATE_CHI           = NO
144 144
BINARY_TOC             = NO
145 145
TOC_EXPAND             = NO
146 146
DISABLE_INDEX          = NO
147 147
ENUM_VALUES_PER_LINE   = 4
148 148
GENERATE_TREEVIEW      = YES
149 149
TREEVIEW_WIDTH         = 250
150 150
#---------------------------------------------------------------------------
151 151
# configuration options related to the LaTeX output
152 152
#---------------------------------------------------------------------------
153 153
GENERATE_LATEX         = NO
154 154
LATEX_OUTPUT           = latex
155 155
LATEX_CMD_NAME         = latex
156 156
MAKEINDEX_CMD_NAME     = makeindex
157 157
COMPACT_LATEX          = YES
158 158
PAPER_TYPE             = a4wide
159 159
EXTRA_PACKAGES         = amsmath \
160 160
                         amssymb
161 161
LATEX_HEADER           = 
162 162
PDF_HYPERLINKS         = YES
163 163
USE_PDFLATEX           = YES
164 164
LATEX_BATCHMODE        = NO
165 165
LATEX_HIDE_INDICES     = NO
166 166
#---------------------------------------------------------------------------
167 167
# configuration options related to the RTF output
168 168
#---------------------------------------------------------------------------
169 169
GENERATE_RTF           = NO
170 170
RTF_OUTPUT             = rtf
171 171
COMPACT_RTF            = NO
172 172
RTF_HYPERLINKS         = NO
173 173
RTF_STYLESHEET_FILE    = 
174 174
RTF_EXTENSIONS_FILE    = 
175 175
#---------------------------------------------------------------------------
176 176
# configuration options related to the man page output
177 177
#---------------------------------------------------------------------------
178 178
GENERATE_MAN           = NO
179 179
MAN_OUTPUT             = man
180 180
MAN_EXTENSION          = .3
181 181
MAN_LINKS              = NO
182 182
#---------------------------------------------------------------------------
183 183
# configuration options related to the XML output
184 184
#---------------------------------------------------------------------------
185 185
GENERATE_XML           = NO
186 186
XML_OUTPUT             = xml
187 187
XML_SCHEMA             = 
188 188
XML_DTD                = 
189 189
XML_PROGRAMLISTING     = YES
190 190
#---------------------------------------------------------------------------
191 191
# configuration options for the AutoGen Definitions output
192 192
#---------------------------------------------------------------------------
193 193
GENERATE_AUTOGEN_DEF   = NO
194 194
#---------------------------------------------------------------------------
195 195
# configuration options related to the Perl module output
196 196
#---------------------------------------------------------------------------
197 197
GENERATE_PERLMOD       = NO
198 198
PERLMOD_LATEX          = NO
199 199
PERLMOD_PRETTY         = YES
200 200
PERLMOD_MAKEVAR_PREFIX = 
201 201
#---------------------------------------------------------------------------
202 202
# Configuration options related to the preprocessor   
203 203
#---------------------------------------------------------------------------
204 204
ENABLE_PREPROCESSING   = YES
205 205
MACRO_EXPANSION        = NO
206 206
EXPAND_ONLY_PREDEF     = NO
207 207
SEARCH_INCLUDES        = YES
208 208
INCLUDE_PATH           = 
209 209
INCLUDE_FILE_PATTERNS  = 
210 210
PREDEFINED             = DOXYGEN
211 211
EXPAND_AS_DEFINED      = 
212 212
SKIP_FUNCTION_MACROS   = YES
213 213
#---------------------------------------------------------------------------
214 214
# Configuration::additions related to external references   
215 215
#---------------------------------------------------------------------------
216 216
TAGFILES               = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
217 217
GENERATE_TAGFILE       = html/lemon.tag
218 218
ALLEXTERNALS           = NO
219 219
EXTERNAL_GROUPS        = NO
220 220
PERL_PATH              = /usr/bin/perl
221 221
#---------------------------------------------------------------------------
222 222
# Configuration options related to the dot tool   
223 223
#---------------------------------------------------------------------------
224 224
CLASS_DIAGRAMS         = NO
225 225
MSCGEN_PATH            = 
226 226
HIDE_UNDOC_RELATIONS   = YES
227 227
HAVE_DOT               = YES
228 228
CLASS_GRAPH            = YES
229 229
COLLABORATION_GRAPH    = NO
230 230
GROUP_GRAPHS           = NO
231 231
UML_LOOK               = NO
232 232
TEMPLATE_RELATIONS     = NO
233 233
INCLUDE_GRAPH          = NO
234 234
INCLUDED_BY_GRAPH      = NO
235 235
CALL_GRAPH             = NO
236 236
CALLER_GRAPH           = NO
237 237
GRAPHICAL_HIERARCHY    = NO
238 238
DIRECTORY_GRAPH        = NO
239 239
DOT_IMAGE_FORMAT       = png
240 240
DOT_PATH               = 
241 241
DOTFILE_DIRS           = 
242 242
DOT_GRAPH_MAX_NODES    = 50
243 243
MAX_DOT_GRAPH_DEPTH    = 0
244 244
DOT_TRANSPARENT        = NO
245 245
DOT_MULTI_TARGETS      = NO
246 246
GENERATE_LEGEND        = YES
247 247
DOT_CLEANUP            = YES
248 248
#---------------------------------------------------------------------------
249 249
# Configuration::additions related to the search engine   
250 250
#---------------------------------------------------------------------------
251 251
SEARCHENGINE           = NO
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 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
 label   coordinates size    title
61
 1       (10,20)     10      "First node"
62
 2       (80,80)     8       "Second node"
63
 3       (40,10)     10      "Third node"
60
 label  coordinates  size    title
61
 1      (10,20)      10      "First node"
62
 2      (80,80)      8       "Second node"
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
               capacity
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_ASSERT_H
20 20
#define LEMON_ASSERT_H
21 21

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

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

	
28 28
namespace lemon {
29 29

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

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

	
50 50
  namespace _assert_bits {
51 51

	
52 52

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

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

	
63 63
#endif // LEMON_ASSERT_H
64 64

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

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

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

	
84 84

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

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

	
115 115
#ifdef DOXYGEN
116 116

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

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

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

	
221 221
#else
222 222

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

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

	
251 251
#endif
252

	
253
#ifdef DOXYGEN
254

	
255

	
256
#else
257

	
258

	
259
#endif
260

	
261

	
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/bits/invalid.h>
29 29
#include <lemon/bits/utility.h>
30 30
#include <lemon/concept_check.h>
31 31

	
32 32
namespace lemon {
33 33
  namespace concepts {
34 34

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

	
38 38
    /// \brief A skeleton structure for representing directed paths in
39 39
    /// a digraph.
40 40
    ///
41 41
    /// A skeleton structure for representing directed paths in a
42 42
    /// 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 in the path and the zero length
48 48
    /// paths cannot store the source.
49 49
    ///
50 50
    template <typename _Digraph>
51 51
    class Path {
52 52
    public:
53 53

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

	
59 59
      class ArcIt;
60 60

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

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

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

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

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

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

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

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

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

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

	
106 106
      };
107 107

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

	
117 117
          p = pc;
118 118

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

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

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

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

	
137 137
    };
138 138

	
139 139
    namespace _path_bits {
140 140

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

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

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

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

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

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

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

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

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

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

	
188 188
    }
189 189

	
190 190

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

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

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

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

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

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

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

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

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

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

	
261 261
      };
262 262

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

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

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

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

	
289 289
      };
290 290

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

	
299 299
    };
300 300

	
301 301

	
302 302
    ///@}
303 303
  }
304 304

	
305 305
} // namespace lemon
306 306

	
307 307
#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
#ifndef LEMON_ERROR_H
20 20
#define LEMON_ERROR_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Basic exception classes and error handling.
25 25

	
26 26
#include <exception>
27 27
#include <string>
28 28
#include <sstream>
29 29
#include <iostream>
30 30
#include <cstdlib>
31 31
#include <memory>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \addtogroup exceptions
36 36
  /// @{
37 37

	
38 38
  /// \brief Exception safe wrapper class.
39 39
  ///
40 40
  /// Exception safe wrapper class to implement the members of exceptions.
41 41
  template <typename _Type>
42 42
  class ExceptionMember {
43 43
  public:
44 44
    typedef _Type Type;
45 45

	
46 46
    ExceptionMember() throw() {
47 47
      try {
48 48
        ptr.reset(new Type());
49 49
      } catch (...) {}
50 50
    }
51 51

	
52 52
    ExceptionMember(const Type& type) throw() {
53 53
      try {
54 54
        ptr.reset(new Type());
55 55
        if (ptr.get() == 0) return;
56 56
        *ptr = type;
57 57
      } catch (...) {}
58 58
    }
59 59

	
60 60
    ExceptionMember(const ExceptionMember& copy) throw() {
61 61
      try {
62 62
        if (!copy.valid()) return;
63 63
        ptr.reset(new Type());
64 64
        if (ptr.get() == 0) return;
65 65
        *ptr = copy.get();
66 66
      } catch (...) {}
67 67
    }
68 68

	
69 69
    ExceptionMember& operator=(const ExceptionMember& copy) throw() {
70 70
      if (ptr.get() == 0) return;
71 71
      try {
72 72
        if (!copy.valid()) return;
73
         *ptr = copy.get();
73
        *ptr = copy.get();
74 74
      } catch (...) {}
75 75
    }
76 76

	
77 77
    void set(const Type& type) throw() {
78 78
      if (ptr.get() == 0) return;
79 79
      try {
80 80
        *ptr = type;
81 81
      } catch (...) {}
82 82
    }
83 83

	
84 84
    const Type& get() const {
85 85
      return *ptr;
86 86
    }
87 87

	
88 88
    bool valid() const throw() {
89 89
      return ptr.get() != 0;
90 90
    }
91 91

	
92 92
  private:
93 93
    std::auto_ptr<_Type> ptr;
94 94
  };
95 95

	
96 96
  /// Exception-safe convenient error message builder class.
97 97

	
98 98
  /// Helper class which provides a convenient ostream-like (operator <<
99 99
  /// based) interface to create a string message. Mostly useful in
100 100
  /// exception classes (therefore the name).
101 101
  class ErrorMessage {
102 102
  protected:
103 103
    ///\e
104 104

	
105 105
    ///\todo The good solution is boost::shared_ptr...
106 106
    ///
107 107
    mutable std::auto_ptr<std::ostringstream> buf;
108 108

	
109 109
    ///\e
110 110
    bool init() throw() {
111 111
      try {
112 112
        buf.reset(new std::ostringstream);
113 113
      }
114 114
      catch(...) {
115 115
        buf.reset();
116 116
      }
117 117
      return buf.get();
118 118
    }
119 119

	
120 120
  public:
121 121

	
122 122
    ///\e
123 123
    ErrorMessage() throw() { init(); }
124 124

	
125 125
    ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
126 126

	
127 127
    ///\e
128 128
    ErrorMessage(const char *msg) throw() {
129 129
      init();
130 130
      *this << msg;
131 131
    }
132 132

	
133 133
    ///\e
134 134
    ErrorMessage(const std::string &msg) throw() {
135 135
      init();
136 136
      *this << msg;
137 137
    }
138 138

	
139 139
    ///\e
140 140
    template <typename T>
141 141
    ErrorMessage& operator<<(const T &t) throw() {
142 142
      if( ! buf.get() ) return *this;
143 143

	
144 144
      try {
145 145
        *buf << t;
146 146
      }
147 147
      catch(...) {
148 148
        buf.reset();
149 149
      }
150 150
      return *this;
151 151
    }
152 152

	
153 153
    ///\e
154 154
    const char* message() throw() {
155 155
      if( ! buf.get() ) return 0;
156 156

	
157 157
      const char* mes = 0;
158 158
      try {
159 159
        mes = buf->str().c_str();
160 160
      }
161 161
      catch(...) {}
162 162
      return mes;
163 163
    }
164 164

	
165 165
  };
166 166

	
167 167
  /// Generic exception class.
168 168

	
169 169
  /// Base class for exceptions used in LEMON.
170 170
  ///
171 171
  class Exception : public std::exception {
172 172
  public:
173 173
    ///\e
174 174
    Exception() {}
175 175
    ///\e
176 176
    virtual ~Exception() throw() {}
177 177
    ///\e
178 178
    virtual const char* what() const throw() {
179 179
      return "lemon::Exception";
180 180
    }
181 181
  };
182 182

	
183 183
  /// One of the two main subclasses of \ref Exception.
184 184

	
185 185
  /// Logic errors represent problems in the internal logic of a program;
186 186
  /// in theory, these are preventable, and even detectable before the
187 187
  /// program runs (e.g. violations of class invariants).
188 188
  ///
189 189
  /// A typical example for this is \ref UninitializedParameter.
190 190
  class LogicError : public Exception {
191 191
  public:
192 192
    virtual const char* what() const throw() {
193 193
      return "lemon::LogicError";
194 194
    }
195 195
  };
196 196

	
197 197
  /// \ref Exception for uninitialized parameters.
198 198

	
199 199
  /// This error represents problems in the initialization
200 200
  /// of the parameters of the algorithms.
201 201
  class UninitializedParameter : public LogicError {
202 202
  public:
203 203
    virtual const char* what() const throw() {
204 204
      return "lemon::UninitializedParameter";
205 205
    }
206 206
  };
207 207

	
208 208

	
209 209
  /// One of the two main subclasses of \ref Exception.
210 210

	
211 211
  /// Runtime errors represent problems outside the scope of a program;
212 212
  /// they cannot be easily predicted and can generally only be caught
213 213
  /// as the program executes.
214 214
  class RuntimeError : public Exception {
215 215
  public:
216 216
    virtual const char* what() const throw() {
217 217
      return "lemon::RuntimeError";
218 218
    }
219 219
  };
220 220

	
221 221
  ///\e
222 222
  class RangeError : public RuntimeError {
223 223
  public:
224 224
    virtual const char* what() const throw() {
225 225
      return "lemon::RangeError";
226 226
    }
227 227
  };
228 228

	
229 229
  ///\e
230 230
  class IoError : public RuntimeError {
231 231
  public:
232 232
    virtual const char* what() const throw() {
233 233
      return "lemon::IoError";
234 234
    }
235 235
  };
236 236

	
237 237
  ///\e
238 238
  class DataFormatError : public IoError {
239 239
  protected:
240 240
    ExceptionMember<std::string> _message;
241 241
    ExceptionMember<std::string> _file;
242 242
    int _line;
243 243

	
244 244
    mutable ExceptionMember<std::string> _message_holder;
245 245
  public:
246 246

	
247 247
    DataFormatError(const DataFormatError &dfe) :
248 248
      IoError(dfe), _message(dfe._message), _file(dfe._file),
249 249
      _line(dfe._line) {}
250 250

	
251 251
    ///\e
252 252
    explicit DataFormatError(const char *the_message)
253 253
      : _message(the_message), _line(0) {}
254 254

	
255 255
    ///\e
256 256
    DataFormatError(const std::string &file_name, int line_num,
257 257
                    const char *the_message)
258 258
      : _message(the_message), _line(line_num) { file(file_name); }
259 259

	
260 260
    ///\e
261 261
    void line(int ln) { _line = ln; }
262 262
    ///\e
263 263
    void message(const std::string& msg) { _message.set(msg); }
264 264
    ///\e
265 265
    void file(const std::string &fl) { _file.set(fl); }
266 266

	
267 267
    ///\e
268 268
    int line() const { return _line; }
269 269
    ///\e
270 270
    const char* message() const {
271 271
      if (_message.valid() && !_message.get().empty()) {
272 272
        return _message.get().c_str();
273 273
      } else {
274 274
        return 0;
275 275
      }
276 276
    }
277 277

	
278 278
    /// \brief Returns the filename.
279 279
    ///
280 280
    /// Returns \e null if the filename was not specified.
281 281
    const char* file() const {
282 282
      if (_file.valid() && !_file.get().empty()) {
283 283
        return _file.get().c_str();
284 284
      } else {
285 285
        return 0;
286 286
      }
287 287
    }
288 288

	
289 289
    ///\e
290 290
    virtual const char* what() const throw() {
291 291
      try {
292 292
        std::ostringstream ostr;
293 293
        ostr << "lemon:DataFormatError" << ": ";
294 294
        if (message()) ostr << message();
295 295
        if( file() || line() != 0 ) {
296 296
          ostr << " (";
297 297
          if( file() ) ostr << "in file '" << file() << "'";
298 298
          if( file() && line() != 0 ) ostr << " ";
299 299
          if( line() != 0 ) ostr << "at line " << line();
300 300
          ostr << ")";
301 301
        }
302 302
        _message_holder.set(ostr.str());
303 303
      }
304 304
      catch (...) {}
305 305
      if( _message_holder.valid()) return _message_holder.get().c_str();
306 306
      return "lemon:DataFormatError";
307 307
    }
308 308

	
309 309
    virtual ~DataFormatError() throw() {}
310 310
  };
311 311

	
312 312
  ///\e
313 313
  class FileOpenError : public IoError {
314 314
  protected:
315 315
    ExceptionMember<std::string> _file;
316 316

	
317 317
    mutable ExceptionMember<std::string> _message_holder;
318 318
  public:
319 319

	
320 320
    FileOpenError(const FileOpenError &foe) :
321 321
      IoError(foe), _file(foe._file) {}
322 322

	
323 323
    ///\e
324 324
    explicit FileOpenError(const std::string& fl)
325 325
      : _file(fl) {}
326 326

	
327 327

	
328 328
    ///\e
329 329
    void file(const std::string &fl) { _file.set(fl); }
330 330

	
331 331
    /// \brief Returns the filename.
332 332
    ///
333 333
    /// Returns \e null if the filename was not specified.
334 334
    const char* file() const {
335 335
      if (_file.valid() && !_file.get().empty()) {
336 336
        return _file.get().c_str();
337 337
      } else {
338 338
        return 0;
339 339
      }
340 340
    }
341 341

	
342 342
    ///\e
343 343
    virtual const char* what() const throw() {
344 344
      try {
345 345
        std::ostringstream ostr;
346 346
        ostr << "lemon::FileOpenError" << ": ";
347 347
        ostr << "Cannot open file - " << file();
348 348
        _message_holder.set(ostr.str());
349 349
      }
350 350
      catch (...) {}
351 351
      if( _message_holder.valid()) return _message_holder.get().c_str();
352 352
      return "lemon::FileOpenError";
353 353
    }
354 354
    virtual ~FileOpenError() throw() {}
355 355
  };
356 356

	
357 357
  class IoParameterError : public IoError {
358 358
  protected:
359 359
    ExceptionMember<std::string> _message;
360 360
    ExceptionMember<std::string> _file;
361 361

	
362 362
    mutable ExceptionMember<std::string> _message_holder;
363 363
  public:
364 364

	
365 365
    IoParameterError(const IoParameterError &ile) :
366 366
      IoError(ile), _message(ile._message), _file(ile._file) {}
367 367

	
368 368
    ///\e
369 369
    explicit IoParameterError(const char *the_message)
370 370
      : _message(the_message) {}
371 371

	
372 372
    ///\e
373 373
    IoParameterError(const char *file_name, const char *the_message)
374 374
      : _message(the_message), _file(file_name) {}
375 375

	
376 376
     ///\e
377 377
    void message(const std::string& msg) { _message.set(msg); }
378 378
    ///\e
379 379
    void file(const std::string &fl) { _file.set(fl); }
380 380

	
381 381
     ///\e
382 382
    const char* message() const {
383 383
      if (_message.valid()) {
384 384
        return _message.get().c_str();
385 385
      } else {
386 386
        return 0;
387 387
      }
388 388
    }
389 389

	
390 390
    /// \brief Returns the filename.
391 391
    ///
392 392
    /// Returns \c 0 if the filename was not specified.
393 393
    const char* file() const {
394 394
      if (_file.valid()) {
395 395
        return _file.get().c_str();
396 396
      } else {
397 397
        return 0;
398 398
      }
399 399
    }
400 400

	
401 401
    ///\e
402 402
    virtual const char* what() const throw() {
403 403
      try {
404 404
        std::ostringstream ostr;
405 405
        if (message()) ostr << message();
406 406
        if (file()) ostr << "(when reading file '" << file() << "')";
407 407
        _message_holder.set(ostr.str());
408 408
      }
409 409
      catch (...) {}
410 410
      if( _message_holder.valid() ) return _message_holder.get().c_str();
411 411
      return "lemon:IoParameterError";
412 412
    }
413 413
    virtual ~IoParameterError() throw() {}
414 414
  };
415 415

	
416 416
  /// @}
417 417

	
418 418
}
419 419

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

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

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

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

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

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

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

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

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

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

	
217 217
  using T::_undirected;
218 218

	
219 219
  using T::_pleaseRemoveOsStream;
220 220

	
221 221
  using T::_scaleToA4;
222 222

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

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

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

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

	
239 239

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

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

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

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

	
258 258
  bool dontPrint;
259 259

	
260 260
public:
261 261
  ///Node shapes
262 262

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
630 630
  ///Sets the title.
631 631

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

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

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

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

	
662 662
  ///Draws the graph.
663 663

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

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

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

	
681 681
    {
682 682
#ifndef WIN32
683 683
      timeval tv;
684 684
      gettimeofday(&tv, 0);
685 685

	
686 686
      char cbuf[26];
687 687
      ctime_r(&tv.tv_sec,cbuf);
688 688
      os << "%%CreationDate: " << cbuf;
689 689
#else
690 690
      SYSTEMTIME time;
691 691
      char buf1[11], buf2[9], buf3[5];
692 692

	
693 693
      GetSystemTime(&time);
694 694
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
695 695
                        "ddd MMM dd", buf1, 11) &&
696 696
          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
697 697
                        "HH':'mm':'ss", buf2, 9) &&
698 698
          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
699 699
                                "yyyy", buf3, 5)) {
700 700
        os << "%%CreationDate: " << buf1 << ' '
701 701
           << buf2 << ' ' << buf3 << std::endl;
702 702
      }
703 703
#endif
704 704
    }
705 705

	
706 706
    if (_autoArcWidthScale) {
707 707
      double max_w=0;
708 708
      for(ArcIt e(g);e!=INVALID;++e)
709 709
        max_w=std::max(double(_arcWidths[e]),max_w);
710 710
      //\todo better 'epsilon' would be nice here.
711 711
      if(max_w>EPSILON) {
712 712
        _arcWidthScale/=max_w;
713 713
      }
714 714
    }
715 715

	
716 716
    if (_autoNodeScale) {
717 717
      double max_s=0;
718 718
      for(NodeIt n(g);n!=INVALID;++n)
719 719
        max_s=std::max(double(_nodeSizes[n]),max_s);
720 720
      //\todo better 'epsilon' would be nice here.
721 721
      if(max_s>EPSILON) {
722 722
        _nodeScale/=max_s;
723 723
      }
724 724
    }
725 725

	
726 726
    double diag_len = 1;
727 727
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
728 728
      dim2::BoundingBox<double> bb;
729 729
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
730 730
      if (bb.empty()) {
731 731
        bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
732 732
      }
733 733
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
734 734
      if(diag_len<EPSILON) diag_len = 1;
735 735
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
736 736
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
737 737
    }
738 738

	
739 739
    dim2::BoundingBox<double> bb;
740 740
    for(NodeIt n(g);n!=INVALID;++n) {
741 741
      double ns=_nodeSizes[n]*_nodeScale;
742 742
      dim2::Point<double> p(ns,ns);
743 743
      switch(_nodeShapes[n]) {
744 744
      case CIRCLE:
745 745
      case SQUARE:
746 746
      case DIAMOND:
747 747
        bb.add(p+mycoords[n]);
748 748
        bb.add(-p+mycoords[n]);
749 749
        break;
750 750
      case MALE:
751 751
        bb.add(-p+mycoords[n]);
752 752
        bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
753 753
        break;
754 754
      case FEMALE:
755 755
        bb.add(p+mycoords[n]);
756 756
        bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
757 757
        break;
758 758
      }
759 759
    }
760 760
    if (bb.empty()) {
761 761
      bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
762 762
    }
763 763

	
764 764
    if(_scaleToA4)
765 765
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
766 766
    else {
767 767
      if(_preScale) {
768 768
        //Rescale so that BoundingBox won't be neither to big nor too small.
769 769
        while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
770 770
        while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
771 771
      }
772 772

	
773 773
      os << "%%BoundingBox: "
774 774
         << int(floor(bb.left()   * _scale - _xBorder)) << ' '
775 775
         << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
776 776
         << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
777 777
         << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
778 778
    }
779 779

	
780 780
    os << "%%EndComments\n";
781 781

	
782 782
    //x1 y1 x2 y2 x3 y3 cr cg cb w
783 783
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
784 784
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
785 785
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }"
786 786
       << " bind def\n";
787 787
    //x y r
788 788
    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath }"
789 789
       << " bind def\n";
790 790
    //x y r
791 791
    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
792 792
       << "      2 index 1 index sub 2 index 2 index add lineto\n"
793 793
       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
794 794
       << "      2 index 1 index add 2 index 2 index sub lineto\n"
795 795
       << "      closepath pop pop pop} bind def\n";
796 796
    //x y r
797 797
    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
798 798
       << "      2 index             2 index 2 index add lineto\n"
799 799
       << "      2 index 1 index sub 2 index             lineto\n"
800 800
       << "      2 index             2 index 2 index sub lineto\n"
801 801
       << "      closepath pop pop pop} bind def\n";
802 802
    // x y r cr cg cb
803 803
    os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
804 804
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
805 805
       << "   } bind def\n";
806 806
    os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
807 807
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
808 808
       << "   } bind def\n";
809 809
    os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
810 810
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
811 811
       << "   } bind def\n";
812 812
    os << "/nfemale { 0 0 0 setrgbcolor 3 index "
813 813
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
814 814
       << " 1.5 mul mul setlinewidth\n"
815 815
       << "  newpath 5 index 5 index moveto "
816 816
       << "5 index 5 index 5 index 3.01 mul sub\n"
817 817
       << "  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub"
818 818
       << " moveto\n"
819 819
       << "  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto "
820 820
       << "stroke\n"
821 821
       << "  5 index 5 index 5 index c fill\n"
822 822
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
823 823
       << "  } bind def\n";
824 824
    os << "/nmale {\n"
825 825
       << "  0 0 0 setrgbcolor 3 index "
826 826
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
827 827
       <<" 1.5 mul mul setlinewidth\n"
828 828
       << "  newpath 5 index 5 index moveto\n"
829 829
       << "  5 index 4 index 1 mul 1.5 mul add\n"
830 830
       << "  5 index 5 index 3 sqrt 1.5 mul mul add\n"
831 831
       << "  1 index 1 index lineto\n"
832 832
       << "  1 index 1 index 7 index sub moveto\n"
833 833
       << "  1 index 1 index lineto\n"
834 834
       << "  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub"
835 835
       << " lineto\n"
836 836
       << "  stroke\n"
837 837
       << "  5 index 5 index 5 index c fill\n"
838 838
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
839 839
       << "  } bind def\n";
840 840

	
841 841

	
842 842
    os << "/arrl " << _arrowLength << " def\n";
843 843
    os << "/arrw " << _arrowWidth << " def\n";
844 844
    // l dx_norm dy_norm
845 845
    os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
846 846
    //len w dx_norm dy_norm x1 y1 cr cg cb
847 847
    os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx "
848 848
       << "exch def\n"
849 849
       << "       /w exch def /len exch def\n"
850 850
      //<< "0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
851 851
       << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
852 852
       << "       len w sub arrl sub dx dy lrl\n"
853 853
       << "       arrw dy dx neg lrl\n"
854 854
       << "       dx arrl w add mul dy w 2 div arrw add mul sub\n"
855 855
       << "       dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
856 856
       << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
857 857
       << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
858 858
       << "       arrw dy dx neg lrl\n"
859 859
       << "       len w sub arrl sub neg dx dy lrl\n"
860 860
       << "       closepath fill } bind def\n";
861 861
    os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
862 862
       << "         neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
863 863

	
864 864
    os << "\ngsave\n";
865 865
    if(_scaleToA4)
866 866
      if(bb.height()>bb.width()) {
867 867
        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.height(),
868 868
                  (A4WIDTH-2*A4BORDER)/bb.width());
869 869
        os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
870 870
           << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER
871 871
           << " translate\n"
872 872
           << sc << " dup scale\n"
873 873
           << -bb.left() << ' ' << -bb.bottom() << " translate\n";
874 874
      }
875 875
      else {
876 876
        //\todo Verify centering
877 877
        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.width(),
878 878
                  (A4WIDTH-2*A4BORDER)/bb.height());
879 879
        os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
880 880
           << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER
881 881
           << " translate\n"
882 882
           << sc << " dup scale\n90 rotate\n"
883 883
           << -bb.left() << ' ' << -bb.top() << " translate\n";
884 884
        }
885 885
    else if(_scale!=1.0) os << _scale << " dup scale\n";
886 886

	
887 887
    if(_showArcs) {
888 888
      os << "%Arcs:\ngsave\n";
889 889
      if(_enableParallel) {
890 890
        std::vector<Arc> el;
891 891
        for(ArcIt e(g);e!=INVALID;++e)
892 892
          if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
893 893
             &&g.source(e)!=g.target(e))
894 894
            el.push_back(e);
895 895
        std::sort(el.begin(),el.end(),arcLess(g));
896 896

	
897 897
        typename std::vector<Arc>::iterator j;
898 898
        for(typename std::vector<Arc>::iterator i=el.begin();i!=el.end();i=j) {
899 899
          for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
900 900

	
901 901
          double sw=0;
902 902
          for(typename std::vector<Arc>::iterator e=i;e!=j;++e)
903 903
            sw+=_arcWidths[*e]*_arcWidthScale+_parArcDist;
904 904
          sw-=_parArcDist;
905 905
          sw/=-2.0;
906 906
          dim2::Point<double>
907 907
            dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
908 908
          double l=std::sqrt(dvec.normSquare());
909 909
          //\todo better 'epsilon' would be nice here.
910 910
          dim2::Point<double> d(dvec/std::max(l,EPSILON));
911
           dim2::Point<double> m;
911
          dim2::Point<double> m;
912 912
//           m=dim2::Point<double>(mycoords[g.target(*i)]+
913 913
//                                 mycoords[g.source(*i)])/2.0;
914 914

	
915 915
//            m=dim2::Point<double>(mycoords[g.source(*i)])+
916 916
//             dvec*(double(_nodeSizes[g.source(*i)])/
917 917
//                (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
918 918

	
919
           m=dim2::Point<double>(mycoords[g.source(*i)])+
919
          m=dim2::Point<double>(mycoords[g.source(*i)])+
920 920
            d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
921 921

	
922 922
          for(typename std::vector<Arc>::iterator e=i;e!=j;++e) {
923 923
            sw+=_arcWidths[*e]*_arcWidthScale/2.0;
924 924
            dim2::Point<double> mm=m+rot90(d)*sw/.75;
925 925
            if(_drawArrows) {
926 926
              int node_shape;
927 927
              dim2::Point<double> s=mycoords[g.source(*e)];
928 928
              dim2::Point<double> t=mycoords[g.target(*e)];
929 929
              double rn=_nodeSizes[g.target(*e)]*_nodeScale;
930 930
              node_shape=_nodeShapes[g.target(*e)];
931 931
              dim2::Bezier3 bez(s,mm,mm,t);
932 932
              double t1=0,t2=1;
933 933
              for(int ii=0;ii<INTERPOL_PREC;++ii)
934 934
                if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
935 935
                else t1=(t1+t2)/2;
936 936
              dim2::Point<double> apoint=bez((t1+t2)/2);
937 937
              rn = _arrowLength+_arcWidths[*e]*_arcWidthScale;
938 938
              rn*=rn;
939 939
              t2=(t1+t2)/2;t1=0;
940 940
              for(int ii=0;ii<INTERPOL_PREC;++ii)
941 941
                if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
942 942
                else t2=(t1+t2)/2;
943 943
              dim2::Point<double> linend=bez((t1+t2)/2);
944 944
              bez=bez.before((t1+t2)/2);
945 945
//               rn=_nodeSizes[g.source(*e)]*_nodeScale;
946 946
//               node_shape=_nodeShapes[g.source(*e)];
947 947
//               t1=0;t2=1;
948 948
//               for(int i=0;i<INTERPOL_PREC;++i)
949 949
//                 if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape))
950 950
//                   t1=(t1+t2)/2;
951 951
//                 else t2=(t1+t2)/2;
952 952
//               bez=bez.after((t1+t2)/2);
953 953
              os << _arcWidths[*e]*_arcWidthScale << " setlinewidth "
954 954
                 << _arcColors[*e].red() << ' '
955 955
                 << _arcColors[*e].green() << ' '
956 956
                 << _arcColors[*e].blue() << " setrgbcolor newpath\n"
957 957
                 << bez.p1.x << ' ' <<  bez.p1.y << " moveto\n"
958 958
                 << bez.p2.x << ' ' << bez.p2.y << ' '
959 959
                 << bez.p3.x << ' ' << bez.p3.y << ' '
960 960
                 << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
961 961
              dim2::Point<double> dd(rot90(linend-apoint));
962 962
              dd*=(.5*_arcWidths[*e]*_arcWidthScale+_arrowWidth)/
963 963
                std::sqrt(dd.normSquare());
964 964
              os << "newpath " << psOut(apoint) << " moveto "
965 965
                 << psOut(linend+dd) << " lineto "
966 966
                 << psOut(linend-dd) << " lineto closepath fill\n";
967 967
            }
968 968
            else {
969 969
              os << mycoords[g.source(*e)].x << ' '
970 970
                 << mycoords[g.source(*e)].y << ' '
971 971
                 << mm.x << ' ' << mm.y << ' '
972 972
                 << mycoords[g.target(*e)].x << ' '
973 973
                 << mycoords[g.target(*e)].y << ' '
974 974
                 << _arcColors[*e].red() << ' '
975 975
                 << _arcColors[*e].green() << ' '
976 976
                 << _arcColors[*e].blue() << ' '
977 977
                 << _arcWidths[*e]*_arcWidthScale << " lb\n";
978 978
            }
979 979
            sw+=_arcWidths[*e]*_arcWidthScale/2.0+_parArcDist;
980 980
          }
981 981
        }
982 982
      }
983 983
      else for(ArcIt e(g);e!=INVALID;++e)
984 984
        if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
985 985
           &&g.source(e)!=g.target(e)) {
986 986
          if(_drawArrows) {
987 987
            dim2::Point<double> d(mycoords[g.target(e)]-mycoords[g.source(e)]);
988 988
            double rn=_nodeSizes[g.target(e)]*_nodeScale;
989 989
            int node_shape=_nodeShapes[g.target(e)];
990 990
            double t1=0,t2=1;
991 991
            for(int i=0;i<INTERPOL_PREC;++i)
992 992
              if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
993 993
              else t2=(t1+t2)/2;
994 994
            double l=std::sqrt(d.normSquare());
995 995
            d/=l;
996 996

	
997 997
            os << l*(1-(t1+t2)/2) << ' '
998 998
               << _arcWidths[e]*_arcWidthScale << ' '
999 999
               << d.x << ' ' << d.y << ' '
1000 1000
               << mycoords[g.source(e)].x << ' '
1001 1001
               << mycoords[g.source(e)].y << ' '
1002 1002
               << _arcColors[e].red() << ' '
1003 1003
               << _arcColors[e].green() << ' '
1004 1004
               << _arcColors[e].blue() << " arr\n";
1005 1005
          }
1006 1006
          else os << mycoords[g.source(e)].x << ' '
1007 1007
                  << mycoords[g.source(e)].y << ' '
1008 1008
                  << mycoords[g.target(e)].x << ' '
1009 1009
                  << mycoords[g.target(e)].y << ' '
1010 1010
                  << _arcColors[e].red() << ' '
1011 1011
                  << _arcColors[e].green() << ' '
1012 1012
                  << _arcColors[e].blue() << ' '
1013 1013
                  << _arcWidths[e]*_arcWidthScale << " l\n";
1014 1014
        }
1015 1015
      os << "grestore\n";
1016 1016
    }
1017 1017
    if(_showNodes) {
1018 1018
      os << "%Nodes:\ngsave\n";
1019 1019
      for(NodeIt n(g);n!=INVALID;++n) {
1020 1020
        os << mycoords[n].x << ' ' << mycoords[n].y << ' '
1021 1021
           << _nodeSizes[n]*_nodeScale << ' '
1022 1022
           << _nodeColors[n].red() << ' '
1023 1023
           << _nodeColors[n].green() << ' '
1024 1024
           << _nodeColors[n].blue() << ' ';
1025 1025
        switch(_nodeShapes[n]) {
1026 1026
        case CIRCLE:
1027 1027
          os<< "nc";break;
1028 1028
        case SQUARE:
1029 1029
          os<< "nsq";break;
1030 1030
        case DIAMOND:
1031 1031
          os<< "ndi";break;
1032 1032
        case MALE:
1033 1033
          os<< "nmale";break;
1034 1034
        case FEMALE:
1035 1035
          os<< "nfemale";break;
1036 1036
        }
1037 1037
        os<<'\n';
1038 1038
      }
1039 1039
      os << "grestore\n";
1040 1040
    }
1041 1041
    if(_showNodeText) {
1042 1042
      os << "%Node texts:\ngsave\n";
1043 1043
      os << "/fosi " << _nodeTextSize << " def\n";
1044 1044
      os << "(Helvetica) findfont fosi scalefont setfont\n";
1045 1045
      for(NodeIt n(g);n!=INVALID;++n) {
1046 1046
        switch(_nodeTextColorType) {
1047 1047
        case DIST_COL:
1048 1048
          os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
1049 1049
          break;
1050 1050
        case DIST_BW:
1051 1051
          os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
1052 1052
          break;
1053 1053
        case CUST_COL:
1054 1054
          os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
1055 1055
          break;
1056 1056
        default:
1057 1057
          os << "0 0 0 setrgbcolor\n";
1058 1058
        }
1059 1059
        os << mycoords[n].x << ' ' << mycoords[n].y
1060 1060
           << " (" << _nodeTexts[n] << ") cshow\n";
1061 1061
      }
1062 1062
      os << "grestore\n";
1063 1063
    }
1064 1064
    if(_showNodePsText) {
1065 1065
      os << "%Node PS blocks:\ngsave\n";
1066 1066
      for(NodeIt n(g);n!=INVALID;++n)
1067 1067
        os << mycoords[n].x << ' ' << mycoords[n].y
1068 1068
           << " moveto\n" << _nodePsTexts[n] << "\n";
1069 1069
      os << "grestore\n";
1070 1070
    }
1071 1071

	
1072 1072
    os << "grestore\nshowpage\n";
1073 1073

	
1074 1074
    //CleanUp:
1075 1075
    if(_pleaseRemoveOsStream) {delete &os;}
1076 1076
  }
1077 1077

	
1078 1078
  ///\name Aliases
1079 1079
  ///These are just some aliases to other parameter setting functions.
1080 1080

	
1081 1081
  ///@{
1082 1082

	
1083 1083
  ///An alias for arcWidths()
1084 1084
  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
1085 1085
  {
1086 1086
    return arcWidths(x);
1087 1087
  }
1088 1088

	
1089 1089
  ///An alias for arcColors()
1090 1090
  template<class X> GraphToEps<ArcColorsTraits<X> >
1091 1091
  edgeColors(const X &x)
1092 1092
  {
1093 1093
    return arcColors(x);
1094 1094
  }
1095 1095

	
1096 1096
  ///An alias for arcWidthScale()
1097 1097
  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
1098 1098

	
1099 1099
  ///An alias for autoArcWidthScale()
1100 1100
  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
1101 1101
  {
1102 1102
    return autoArcWidthScale(b);
1103 1103
  }
1104 1104

	
1105 1105
  ///An alias for absoluteArcWidths()
1106 1106
  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
1107 1107
  {
1108 1108
    return absoluteArcWidths(b);
1109 1109
  }
1110 1110

	
1111 1111
  ///An alias for parArcDist()
1112 1112
  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
1113 1113

	
1114 1114
  ///An alias for hideArcs()
1115 1115
  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
1116 1116

	
1117 1117
  ///@}
1118 1118
};
1119 1119

	
1120 1120
template<class T>
1121 1121
const int GraphToEps<T>::INTERPOL_PREC = 20;
1122 1122
template<class T>
1123 1123
const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
1124 1124
template<class T>
1125 1125
const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
1126 1126
template<class T>
1127 1127
const double GraphToEps<T>::A4BORDER = 15;
1128 1128

	
1129 1129

	
1130 1130
///Generates an EPS file from a graph
1131 1131

	
1132 1132
///\ingroup eps_io
1133 1133
///Generates an EPS file from a graph.
1134 1134
///\param g Reference to the graph to be printed.
1135 1135
///\param os Reference to the output stream.
1136 1136
///By default it is <tt>std::cout</tt>.
1137 1137
///
1138 1138
///This function also has a lot of
1139 1139
///\ref named-templ-func-param "named parameters",
1140 1140
///they are declared as the members of class \ref GraphToEps. The following
1141 1141
///example shows how to use these parameters.
1142 1142
///\code
1143 1143
/// graphToEps(g,os).scale(10).coords(coords)
1144 1144
///              .nodeScale(2).nodeSizes(sizes)
1145 1145
///              .arcWidthScale(.4).run();
1146 1146
///\endcode
1147 1147
///
1148 1148
///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
1149 1149
///
1150 1150
///\warning Don't forget to put the \ref GraphToEps::run() "run()"
1151 1151
///to the end of the parameter list.
1152 1152
///\sa GraphToEps
1153 1153
///\sa graphToEps(G &g, const char *file_name)
1154 1154
template<class G>
1155 1155
GraphToEps<DefaultGraphToEpsTraits<G> >
1156 1156
graphToEps(G &g, std::ostream& os=std::cout)
1157 1157
{
1158 1158
  return
1159 1159
    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
1160 1160
}
1161 1161

	
1162 1162
///Generates an EPS file from a graph
1163 1163

	
1164 1164
///\ingroup eps_io
1165 1165
///This function does the same as
1166 1166
///\ref graphToEps(G &g,std::ostream& os)
1167 1167
///but it writes its output into the file \c file_name
1168 1168
///instead of a stream.
1169 1169
///\sa graphToEps(G &g, std::ostream& os)
1170 1170
template<class G>
1171 1171
GraphToEps<DefaultGraphToEpsTraits<G> >
1172 1172
graphToEps(G &g,const char *file_name)
1173 1173
{
1174 1174
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1175 1175
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
1176 1176
}
1177 1177

	
1178 1178
///Generates an EPS file from a graph
1179 1179

	
1180 1180
///\ingroup eps_io
1181 1181
///This function does the same as
1182 1182
///\ref graphToEps(G &g,std::ostream& os)
1183 1183
///but it writes its output into the file \c file_name
1184 1184
///instead of a stream.
1185 1185
///\sa graphToEps(G &g, std::ostream& os)
1186 1186
template<class G>
1187 1187
GraphToEps<DefaultGraphToEpsTraits<G> >
1188 1188
graphToEps(G &g,const std::string& file_name)
1189 1189
{
1190 1190
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1191 1191
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name.c_str()),true));
1192 1192
}
1193 1193

	
1194 1194
} //END OF NAMESPACE LEMON
1195 1195

	
1196 1196
#endif // LEMON_GRAPH_TO_EPS_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
#ifndef LEMON_GRAPH_UTILS_H
20 20
#define LEMON_GRAPH_UTILS_H
21 21

	
22 22
#include <iterator>
23 23
#include <vector>
24 24
#include <map>
25 25
#include <cmath>
26 26
#include <algorithm>
27 27

	
28 28
#include <lemon/bits/invalid.h>
29 29
#include <lemon/bits/utility.h>
30 30
#include <lemon/maps.h>
31 31
#include <lemon/bits/traits.h>
32 32

	
33 33
#include <lemon/bits/alteration_notifier.h>
34 34
#include <lemon/bits/default_map.h>
35 35

	
36 36
///\ingroup gutils
37 37
///\file
38 38
///\brief Graph utilities.
39 39

	
40 40
namespace lemon {
41 41

	
42 42
  /// \addtogroup gutils
43 43
  /// @{
44 44

	
45 45
  ///Creates convenience typedefs for the digraph types and iterators
46 46

	
47 47
  ///This \c \#define creates convenience typedefs for the following types
48 48
  ///of \c Digraph: \c Node,  \c NodeIt, \c Arc, \c ArcIt, \c InArcIt,
49 49
  ///\c OutArcIt, \c BoolNodeMap, \c IntNodeMap, \c DoubleNodeMap,
50 50
  ///\c BoolArcMap, \c IntArcMap, \c DoubleArcMap.
51 51
  ///
52 52
  ///\note If the graph type is a dependent type, ie. the graph type depend
53 53
  ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS()
54 54
  ///macro.
55
#define DIGRAPH_TYPEDEFS(Digraph)                                        \
56
  typedef Digraph::Node Node;                                                \
57
  typedef Digraph::NodeIt NodeIt;                                        \
58
  typedef Digraph::Arc Arc;                                                \
59
  typedef Digraph::ArcIt ArcIt;                                                \
60
  typedef Digraph::InArcIt InArcIt;                                        \
61
  typedef Digraph::OutArcIt OutArcIt;                                        \
62
  typedef Digraph::NodeMap<bool> BoolNodeMap;                                \
63
  typedef Digraph::NodeMap<int> IntNodeMap;                                \
64
  typedef Digraph::NodeMap<double> DoubleNodeMap;                        \
65
  typedef Digraph::ArcMap<bool> BoolArcMap;                                \
66
  typedef Digraph::ArcMap<int> IntArcMap;                                \
55
#define DIGRAPH_TYPEDEFS(Digraph)                                       \
56
  typedef Digraph::Node Node;                                           \
57
  typedef Digraph::NodeIt NodeIt;                                       \
58
  typedef Digraph::Arc Arc;                                             \
59
  typedef Digraph::ArcIt ArcIt;                                         \
60
  typedef Digraph::InArcIt InArcIt;                                     \
61
  typedef Digraph::OutArcIt OutArcIt;                                   \
62
  typedef Digraph::NodeMap<bool> BoolNodeMap;                           \
63
  typedef Digraph::NodeMap<int> IntNodeMap;                             \
64
  typedef Digraph::NodeMap<double> DoubleNodeMap;                       \
65
  typedef Digraph::ArcMap<bool> BoolArcMap;                             \
66
  typedef Digraph::ArcMap<int> IntArcMap;                               \
67 67
  typedef Digraph::ArcMap<double> DoubleArcMap
68 68

	
69 69
  ///Creates convenience typedefs for the digraph types and iterators
70 70

	
71 71
  ///\see DIGRAPH_TYPEDEFS
72 72
  ///
73 73
  ///\note Use this macro, if the graph type is a dependent type,
74 74
  ///ie. the graph type depend on a template parameter.
75
#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph)                                \
76
  typedef typename Digraph::Node Node;                                        \
77
  typedef typename Digraph::NodeIt NodeIt;                                \
78
  typedef typename Digraph::Arc Arc;                                        \
75
#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph)                              \
76
  typedef typename Digraph::Node Node;                                  \
77
  typedef typename Digraph::NodeIt NodeIt;                              \
78
  typedef typename Digraph::Arc Arc;                                    \
79 79
  typedef typename Digraph::ArcIt ArcIt;                                \
80
  typedef typename Digraph::InArcIt InArcIt;                                \
81
  typedef typename Digraph::OutArcIt OutArcIt;                                \
82
  typedef typename Digraph::template NodeMap<bool> BoolNodeMap;                \
83
  typedef typename Digraph::template NodeMap<int> IntNodeMap;                \
84
  typedef typename Digraph::template NodeMap<double> DoubleNodeMap;        \
85
  typedef typename Digraph::template ArcMap<bool> BoolArcMap;                \
86
  typedef typename Digraph::template ArcMap<int> IntArcMap;                \
80
  typedef typename Digraph::InArcIt InArcIt;                            \
81
  typedef typename Digraph::OutArcIt OutArcIt;                          \
82
  typedef typename Digraph::template NodeMap<bool> BoolNodeMap;         \
83
  typedef typename Digraph::template NodeMap<int> IntNodeMap;           \
84
  typedef typename Digraph::template NodeMap<double> DoubleNodeMap;     \
85
  typedef typename Digraph::template ArcMap<bool> BoolArcMap;           \
86
  typedef typename Digraph::template ArcMap<int> IntArcMap;             \
87 87
  typedef typename Digraph::template ArcMap<double> DoubleArcMap
88 88

	
89 89
  ///Creates convenience typedefs for the graph types and iterators
90 90

	
91 91
  ///This \c \#define creates the same convenience typedefs as defined
92 92
  ///by \ref DIGRAPH_TYPEDEFS(Graph) and six more, namely it creates
93 93
  ///\c Edge, \c EdgeIt, \c IncEdgeIt, \c BoolEdgeMap, \c IntEdgeMap,
94 94
  ///\c DoubleEdgeMap.
95 95
  ///
96 96
  ///\note If the graph type is a dependent type, ie. the graph type depend
97 97
  ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS()
98 98
  ///macro.
99
#define GRAPH_TYPEDEFS(Graph)                                                \
100
  DIGRAPH_TYPEDEFS(Graph);                                                \
101
  typedef Graph::Edge Edge;                                                \
102
  typedef Graph::EdgeIt EdgeIt;                                                \
103
  typedef Graph::IncEdgeIt IncEdgeIt;                                        \
104
  typedef Graph::EdgeMap<bool> BoolEdgeMap;                                \
105
  typedef Graph::EdgeMap<int> IntEdgeMap;                                \
99
#define GRAPH_TYPEDEFS(Graph)                                           \
100
  DIGRAPH_TYPEDEFS(Graph);                                              \
101
  typedef Graph::Edge Edge;                                             \
102
  typedef Graph::EdgeIt EdgeIt;                                         \
103
  typedef Graph::IncEdgeIt IncEdgeIt;                                   \
104
  typedef Graph::EdgeMap<bool> BoolEdgeMap;                             \
105
  typedef Graph::EdgeMap<int> IntEdgeMap;                               \
106 106
  typedef Graph::EdgeMap<double> DoubleEdgeMap
107 107

	
108 108
  ///Creates convenience typedefs for the graph types and iterators
109 109

	
110 110
  ///\see GRAPH_TYPEDEFS
111 111
  ///
112 112
  ///\note Use this macro, if the graph type is a dependent type,
113 113
  ///ie. the graph type depend on a template parameter.
114
#define TEMPLATE_GRAPH_TYPEDEFS(Graph)                                        \
115
  TEMPLATE_DIGRAPH_TYPEDEFS(Graph);                                        \
116
  typedef typename Graph::Edge Edge;                                        \
114
#define TEMPLATE_GRAPH_TYPEDEFS(Graph)                                  \
115
  TEMPLATE_DIGRAPH_TYPEDEFS(Graph);                                     \
116
  typedef typename Graph::Edge Edge;                                    \
117 117
  typedef typename Graph::EdgeIt EdgeIt;                                \
118
  typedef typename Graph::IncEdgeIt IncEdgeIt;                                \
119
  typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;                \
120
  typedef typename Graph::template EdgeMap<int> IntEdgeMap;                \
118
  typedef typename Graph::IncEdgeIt IncEdgeIt;                          \
119
  typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;           \
120
  typedef typename Graph::template EdgeMap<int> IntEdgeMap;             \
121 121
  typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
122 122

	
123 123
  /// \brief Function to count the items in the graph.
124 124
  ///
125 125
  /// This function counts the items (nodes, arcs etc) in the graph.
126 126
  /// The complexity of the function is O(n) because
127 127
  /// it iterates on all of the items.
128 128
  template <typename Graph, typename Item>
129 129
  inline int countItems(const Graph& g) {
130 130
    typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
131 131
    int num = 0;
132 132
    for (ItemIt it(g); it != INVALID; ++it) {
133 133
      ++num;
134 134
    }
135 135
    return num;
136 136
  }
137 137

	
138 138
  // Node counting:
139 139

	
140 140
  namespace _graph_utils_bits {
141 141

	
142 142
    template <typename Graph, typename Enable = void>
143 143
    struct CountNodesSelector {
144 144
      static int count(const Graph &g) {
145 145
        return countItems<Graph, typename Graph::Node>(g);
146 146
      }
147 147
    };
148 148

	
149 149
    template <typename Graph>
150 150
    struct CountNodesSelector<
151 151
      Graph, typename
152 152
      enable_if<typename Graph::NodeNumTag, void>::type>
153 153
    {
154 154
      static int count(const Graph &g) {
155 155
        return g.nodeNum();
156 156
      }
157 157
    };
158 158
  }
159 159

	
160 160
  /// \brief Function to count the nodes in the graph.
161 161
  ///
162 162
  /// This function counts the nodes in the graph.
163 163
  /// The complexity of the function is O(n) but for some
164 164
  /// graph structures it is specialized to run in O(1).
165 165
  ///
166 166
  /// If the graph contains a \e nodeNum() member function and a
167 167
  /// \e NodeNumTag tag then this function calls directly the member
168 168
  /// function to query the cardinality of the node set.
169 169
  template <typename Graph>
170 170
  inline int countNodes(const Graph& g) {
171 171
    return _graph_utils_bits::CountNodesSelector<Graph>::count(g);
172 172
  }
173 173

	
174 174
  // Arc counting:
175 175

	
176 176
  namespace _graph_utils_bits {
177 177

	
178 178
    template <typename Graph, typename Enable = void>
179 179
    struct CountArcsSelector {
180 180
      static int count(const Graph &g) {
181 181
        return countItems<Graph, typename Graph::Arc>(g);
182 182
      }
183 183
    };
184 184

	
185 185
    template <typename Graph>
186 186
    struct CountArcsSelector<
187 187
      Graph,
188 188
      typename enable_if<typename Graph::ArcNumTag, void>::type>
189 189
    {
190 190
      static int count(const Graph &g) {
191 191
        return g.arcNum();
192 192
      }
193 193
    };
194 194
  }
195 195

	
196 196
  /// \brief Function to count the arcs in the graph.
197 197
  ///
198 198
  /// This function counts the arcs in the graph.
199 199
  /// The complexity of the function is O(e) but for some
200 200
  /// graph structures it is specialized to run in O(1).
201 201
  ///
202 202
  /// If the graph contains a \e arcNum() member function and a
203 203
  /// \e EdgeNumTag tag then this function calls directly the member
204 204
  /// function to query the cardinality of the arc set.
205 205
  template <typename Graph>
206 206
  inline int countArcs(const Graph& g) {
207 207
    return _graph_utils_bits::CountArcsSelector<Graph>::count(g);
208 208
  }
209 209

	
210 210
  // Edge counting:
211 211
  namespace _graph_utils_bits {
212 212

	
213 213
    template <typename Graph, typename Enable = void>
214 214
    struct CountEdgesSelector {
215 215
      static int count(const Graph &g) {
216 216
        return countItems<Graph, typename Graph::Edge>(g);
217 217
      }
218 218
    };
219 219

	
220 220
    template <typename Graph>
221 221
    struct CountEdgesSelector<
222 222
      Graph,
223 223
      typename enable_if<typename Graph::EdgeNumTag, void>::type>
224 224
    {
225 225
      static int count(const Graph &g) {
226 226
        return g.edgeNum();
227 227
      }
228 228
    };
229 229
  }
230 230

	
231 231
  /// \brief Function to count the edges in the graph.
232 232
  ///
233 233
  /// This function counts the edges in the graph.
234 234
  /// The complexity of the function is O(m) but for some
235 235
  /// graph structures it is specialized to run in O(1).
236 236
  ///
237 237
  /// If the graph contains a \e edgeNum() member function and a
238 238
  /// \e EdgeNumTag tag then this function calls directly the member
239 239
  /// function to query the cardinality of the edge set.
240 240
  template <typename Graph>
241 241
  inline int countEdges(const Graph& g) {
242 242
    return _graph_utils_bits::CountEdgesSelector<Graph>::count(g);
243 243

	
244 244
  }
245 245

	
246 246

	
247 247
  template <typename Graph, typename DegIt>
248 248
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
249 249
    int num = 0;
250 250
    for (DegIt it(_g, _n); it != INVALID; ++it) {
251 251
      ++num;
252 252
    }
253 253
    return num;
254 254
  }
255 255

	
256 256
  /// \brief Function to count the number of the out-arcs from node \c n.
257 257
  ///
258 258
  /// This function counts the number of the out-arcs from node \c n
259 259
  /// in the graph.
260 260
  template <typename Graph>
261 261
  inline int countOutArcs(const Graph& _g,  const typename Graph::Node& _n) {
262 262
    return countNodeDegree<Graph, typename Graph::OutArcIt>(_g, _n);
263 263
  }
264 264

	
265 265
  /// \brief Function to count the number of the in-arcs to node \c n.
266 266
  ///
267 267
  /// This function counts the number of the in-arcs to node \c n
268 268
  /// in the graph.
269 269
  template <typename Graph>
270 270
  inline int countInArcs(const Graph& _g,  const typename Graph::Node& _n) {
271 271
    return countNodeDegree<Graph, typename Graph::InArcIt>(_g, _n);
272 272
  }
273 273

	
274 274
  /// \brief Function to count the number of the inc-edges to node \c n.
275 275
  ///
276 276
  /// This function counts the number of the inc-edges to node \c n
277 277
  /// in the graph.
278 278
  template <typename Graph>
279 279
  inline int countIncEdges(const Graph& _g,  const typename Graph::Node& _n) {
280 280
    return countNodeDegree<Graph, typename Graph::IncEdgeIt>(_g, _n);
281 281
  }
282 282

	
283 283
  namespace _graph_utils_bits {
284 284

	
285 285
    template <typename Graph, typename Enable = void>
286 286
    struct FindArcSelector {
287 287
      typedef typename Graph::Node Node;
288 288
      typedef typename Graph::Arc Arc;
289 289
      static Arc find(const Graph &g, Node u, Node v, Arc e) {
290 290
        if (e == INVALID) {
291 291
          g.firstOut(e, u);
292 292
        } else {
293 293
          g.nextOut(e);
294 294
        }
295 295
        while (e != INVALID && g.target(e) != v) {
296 296
          g.nextOut(e);
297 297
        }
298 298
        return e;
299 299
      }
300 300
    };
301 301

	
302 302
    template <typename Graph>
303 303
    struct FindArcSelector<
304 304
      Graph,
305 305
      typename enable_if<typename Graph::FindEdgeTag, void>::type>
306 306
    {
307 307
      typedef typename Graph::Node Node;
308 308
      typedef typename Graph::Arc Arc;
309 309
      static Arc find(const Graph &g, Node u, Node v, Arc prev) {
310 310
        return g.findArc(u, v, prev);
311 311
      }
312 312
    };
313 313
  }
314 314

	
315 315
  /// \brief Finds an arc between two nodes of a graph.
316 316
  ///
317 317
  /// Finds an arc from node \c u to node \c v in graph \c g.
318 318
  ///
319 319
  /// If \c prev is \ref INVALID (this is the default value), then
320 320
  /// it finds the first arc from \c u to \c v. Otherwise it looks for
321 321
  /// the next arc from \c u to \c v after \c prev.
322 322
  /// \return The found arc or \ref INVALID if there is no such an arc.
323 323
  ///
324 324
  /// Thus you can iterate through each arc from \c u to \c v as it follows.
325 325
  ///\code
326 326
  /// for(Arc e=findArc(g,u,v);e!=INVALID;e=findArc(g,u,v,e)) {
327 327
  ///   ...
328 328
  /// }
329 329
  ///\endcode
330 330
  ///
331 331
  ///\sa ArcLookUp
332 332
  ///\sa AllArcLookUp
333 333
  ///\sa DynArcLookUp
334 334
  ///\sa ConArcIt
335 335
  template <typename Graph>
336 336
  inline typename Graph::Arc
337 337
  findArc(const Graph &g, typename Graph::Node u, typename Graph::Node v,
338 338
           typename Graph::Arc prev = INVALID) {
339 339
    return _graph_utils_bits::FindArcSelector<Graph>::find(g, u, v, prev);
340 340
  }
341 341

	
342 342
  /// \brief Iterator for iterating on arcs connected the same nodes.
343 343
  ///
344 344
  /// Iterator for iterating on arcs connected the same nodes. It is
345 345
  /// higher level interface for the findArc() function. You can
346 346
  /// use it the following way:
347 347
  ///\code
348 348
  /// for (ConArcIt<Graph> it(g, src, trg); it != INVALID; ++it) {
349 349
  ///   ...
350 350
  /// }
351 351
  ///\endcode
352 352
  ///
353 353
  ///\sa findArc()
354 354
  ///\sa ArcLookUp
355 355
  ///\sa AllArcLookUp
356 356
  ///\sa DynArcLookUp
357 357
  template <typename _Graph>
358 358
  class ConArcIt : public _Graph::Arc {
359 359
  public:
360 360

	
361 361
    typedef _Graph Graph;
362 362
    typedef typename Graph::Arc Parent;
363 363

	
364 364
    typedef typename Graph::Arc Arc;
365 365
    typedef typename Graph::Node Node;
366 366

	
367 367
    /// \brief Constructor.
368 368
    ///
369 369
    /// Construct a new ConArcIt iterating on the arcs which
370 370
    /// connects the \c u and \c v node.
371 371
    ConArcIt(const Graph& g, Node u, Node v) : _graph(g) {
372 372
      Parent::operator=(findArc(_graph, u, v));
373 373
    }
374 374

	
375 375
    /// \brief Constructor.
376 376
    ///
377 377
    /// Construct a new ConArcIt which continues the iterating from
378 378
    /// the \c e arc.
379 379
    ConArcIt(const Graph& g, Arc a) : Parent(a), _graph(g) {}
380 380

	
381 381
    /// \brief Increment operator.
382 382
    ///
383 383
    /// It increments the iterator and gives back the next arc.
384 384
    ConArcIt& operator++() {
385 385
      Parent::operator=(findArc(_graph, _graph.source(*this),
386 386
                                _graph.target(*this), *this));
387 387
      return *this;
388 388
    }
389 389
  private:
390 390
    const Graph& _graph;
391 391
  };
392 392

	
393 393
  namespace _graph_utils_bits {
394 394

	
395 395
    template <typename Graph, typename Enable = void>
396 396
    struct FindEdgeSelector {
397 397
      typedef typename Graph::Node Node;
398 398
      typedef typename Graph::Edge Edge;
399 399
      static Edge find(const Graph &g, Node u, Node v, Edge e) {
400 400
        bool b;
401 401
        if (u != v) {
402 402
          if (e == INVALID) {
403 403
            g.firstInc(e, b, u);
404 404
          } else {
405 405
            b = g.u(e) == u;
406 406
            g.nextInc(e, b);
407 407
          }
408 408
          while (e != INVALID && (b ? g.v(e) : g.u(e)) != v) {
409 409
            g.nextInc(e, b);
410 410
          }
411 411
        } else {
412 412
          if (e == INVALID) {
413 413
            g.firstInc(e, b, u);
414 414
          } else {
415 415
            b = true;
416 416
            g.nextInc(e, b);
417 417
          }
418 418
          while (e != INVALID && (!b || g.v(e) != v)) {
419 419
            g.nextInc(e, b);
420 420
          }
421 421
        }
422 422
        return e;
423 423
      }
424 424
    };
425 425

	
426 426
    template <typename Graph>
427 427
    struct FindEdgeSelector<
428 428
      Graph,
429 429
      typename enable_if<typename Graph::FindEdgeTag, void>::type>
430 430
    {
431 431
      typedef typename Graph::Node Node;
432 432
      typedef typename Graph::Edge Edge;
433 433
      static Edge find(const Graph &g, Node u, Node v, Edge prev) {
434 434
        return g.findEdge(u, v, prev);
435 435
      }
436 436
    };
437 437
  }
438 438

	
439 439
  /// \brief Finds an edge between two nodes of a graph.
440 440
  ///
441 441
  /// Finds an edge from node \c u to node \c v in graph \c g.
442 442
  /// If the node \c u and node \c v is equal then each loop edge
443 443
  /// will be enumerated once.
444 444
  ///
445 445
  /// If \c prev is \ref INVALID (this is the default value), then
446 446
  /// it finds the first arc from \c u to \c v. Otherwise it looks for
447 447
  /// the next arc from \c u to \c v after \c prev.
448 448
  /// \return The found arc or \ref INVALID if there is no such an arc.
449 449
  ///
450 450
  /// Thus you can iterate through each arc from \c u to \c v as it follows.
451 451
  ///\code
452 452
  /// for(Edge e = findEdge(g,u,v); e != INVALID;
453 453
  ///     e = findEdge(g,u,v,e)) {
454 454
  ///   ...
455 455
  /// }
456 456
  ///\endcode
457 457
  ///
458 458
  ///\sa ConEdgeIt
459 459

	
460 460
  template <typename Graph>
461 461
  inline typename Graph::Edge
462 462
  findEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v,
463 463
            typename Graph::Edge p = INVALID) {
464 464
    return _graph_utils_bits::FindEdgeSelector<Graph>::find(g, u, v, p);
465 465
  }
466 466

	
467 467
  /// \brief Iterator for iterating on edges connected the same nodes.
468 468
  ///
469 469
  /// Iterator for iterating on edges connected the same nodes. It is
470 470
  /// higher level interface for the findEdge() function. You can
471 471
  /// use it the following way:
472 472
  ///\code
473 473
  /// for (ConEdgeIt<Graph> it(g, src, trg); it != INVALID; ++it) {
474 474
  ///   ...
475 475
  /// }
476 476
  ///\endcode
477 477
  ///
478 478
  ///\sa findEdge()
479 479
  template <typename _Graph>
480 480
  class ConEdgeIt : public _Graph::Edge {
481 481
  public:
482 482

	
483 483
    typedef _Graph Graph;
484 484
    typedef typename Graph::Edge Parent;
485 485

	
486 486
    typedef typename Graph::Edge Edge;
487 487
    typedef typename Graph::Node Node;
488 488

	
489 489
    /// \brief Constructor.
490 490
    ///
491 491
    /// Construct a new ConEdgeIt iterating on the edges which
492 492
    /// connects the \c u and \c v node.
493 493
    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g) {
494 494
      Parent::operator=(findEdge(_graph, u, v));
495 495
    }
496 496

	
497 497
    /// \brief Constructor.
498 498
    ///
499 499
    /// Construct a new ConEdgeIt which continues the iterating from
500 500
    /// the \c e edge.
501 501
    ConEdgeIt(const Graph& g, Edge e) : Parent(e), _graph(g) {}
502 502

	
503 503
    /// \brief Increment operator.
504 504
    ///
505 505
    /// It increments the iterator and gives back the next edge.
506 506
    ConEdgeIt& operator++() {
507 507
      Parent::operator=(findEdge(_graph, _graph.u(*this),
508 508
                                 _graph.v(*this), *this));
509 509
      return *this;
510 510
    }
511 511
  private:
512 512
    const Graph& _graph;
513 513
  };
514 514

	
515 515
  namespace _graph_utils_bits {
516 516

	
517 517
    template <typename Digraph, typename Item, typename RefMap>
518 518
    class MapCopyBase {
519 519
    public:
520 520
      virtual void copy(const Digraph& from, const RefMap& refMap) = 0;
521 521

	
522 522
      virtual ~MapCopyBase() {}
523 523
    };
524 524

	
525 525
    template <typename Digraph, typename Item, typename RefMap,
526 526
              typename ToMap, typename FromMap>
527 527
    class MapCopy : public MapCopyBase<Digraph, Item, RefMap> {
528 528
    public:
529 529

	
530 530
      MapCopy(ToMap& tmap, const FromMap& map)
531 531
        : _tmap(tmap), _map(map) {}
532 532

	
533 533
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
534 534
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
535 535
        for (ItemIt it(digraph); it != INVALID; ++it) {
536 536
          _tmap.set(refMap[it], _map[it]);
537 537
        }
538 538
      }
539 539

	
540 540
    private:
541 541
      ToMap& _tmap;
542 542
      const FromMap& _map;
543 543
    };
544 544

	
545 545
    template <typename Digraph, typename Item, typename RefMap, typename It>
546 546
    class ItemCopy : public MapCopyBase<Digraph, Item, RefMap> {
547 547
    public:
548 548

	
549 549
      ItemCopy(It& it, const Item& item) : _it(it), _item(item) {}
550 550

	
551 551
      virtual void copy(const Digraph&, const RefMap& refMap) {
552 552
        _it = refMap[_item];
553 553
      }
554 554

	
555 555
    private:
556 556
      It& _it;
557 557
      Item _item;
558 558
    };
559 559

	
560 560
    template <typename Digraph, typename Item, typename RefMap, typename Ref>
561 561
    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
562 562
    public:
563 563

	
564 564
      RefCopy(Ref& map) : _map(map) {}
565 565

	
566 566
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
567 567
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
568 568
        for (ItemIt it(digraph); it != INVALID; ++it) {
569 569
          _map.set(it, refMap[it]);
570 570
        }
571 571
      }
572 572

	
573 573
    private:
574 574
      Ref& _map;
575 575
    };
576 576

	
577 577
    template <typename Digraph, typename Item, typename RefMap,
578 578
              typename CrossRef>
579 579
    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
580 580
    public:
581 581

	
582 582
      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
583 583

	
584 584
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
585 585
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
586 586
        for (ItemIt it(digraph); it != INVALID; ++it) {
587 587
          _cmap.set(refMap[it], it);
588 588
        }
589 589
      }
590 590

	
591 591
    private:
592 592
      CrossRef& _cmap;
593 593
    };
594 594

	
595 595
    template <typename Digraph, typename Enable = void>
596 596
    struct DigraphCopySelector {
597 597
      template <typename From, typename NodeRefMap, typename ArcRefMap>
598 598
      static void copy(Digraph &to, const From& from,
599 599
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
600 600
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
601 601
          nodeRefMap[it] = to.addNode();
602 602
        }
603 603
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
604 604
          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
605 605
                                    nodeRefMap[from.target(it)]);
606 606
        }
607 607
      }
608 608
    };
609 609

	
610 610
    template <typename Digraph>
611 611
    struct DigraphCopySelector<
612 612
      Digraph,
613 613
      typename enable_if<typename Digraph::BuildTag, void>::type>
614 614
    {
615 615
      template <typename From, typename NodeRefMap, typename ArcRefMap>
616 616
      static void copy(Digraph &to, const From& from,
617 617
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
618 618
        to.build(from, nodeRefMap, arcRefMap);
619 619
      }
620 620
    };
621 621

	
622 622
    template <typename Graph, typename Enable = void>
623 623
    struct GraphCopySelector {
624 624
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
625 625
      static void copy(Graph &to, const From& from,
626 626
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
627 627
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
628 628
          nodeRefMap[it] = to.addNode();
629 629
        }
630 630
        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
631 631
          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
632 632
                                      nodeRefMap[from.v(it)]);
633 633
        }
634 634
      }
635 635
    };
636 636

	
637 637
    template <typename Graph>
638 638
    struct GraphCopySelector<
639 639
      Graph,
640 640
      typename enable_if<typename Graph::BuildTag, void>::type>
641 641
    {
642 642
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
643 643
      static void copy(Graph &to, const From& from,
644 644
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
645 645
        to.build(from, nodeRefMap, edgeRefMap);
646 646
      }
647 647
    };
648 648

	
649 649
  }
650 650

	
651 651
  /// \brief Class to copy a digraph.
652 652
  ///
653 653
  /// Class to copy a digraph to another digraph (duplicate a digraph). The
654 654
  /// simplest way of using it is through the \c copyDigraph() function.
655 655
  ///
656 656
  /// This class not just make a copy of a graph, but it can create
657 657
  /// references and cross references between the nodes and arcs of
658 658
  /// the two graphs, it can copy maps for use with the newly created
659 659
  /// graph and copy nodes and arcs.
660 660
  ///
661 661
  /// To make a copy from a graph, first an instance of DigraphCopy
662 662
  /// should be created, then the data belongs to the graph should
663 663
  /// assigned to copy. In the end, the \c run() member should be
664 664
  /// called.
665 665
  ///
666 666
  /// The next code copies a graph with several data:
667 667
  ///\code
668 668
  ///  DigraphCopy<NewGraph, OrigGraph> dc(new_graph, orig_graph);
669 669
  ///  // create a reference for the nodes
670 670
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
671 671
  ///  dc.nodeRef(nr);
672 672
  ///  // create a cross reference (inverse) for the arcs
673 673
  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
674 674
  ///  dc.arcCrossRef(acr);
675 675
  ///  // copy an arc map
676 676
  ///  OrigGraph::ArcMap<double> oamap(orig_graph);
677 677
  ///  NewGraph::ArcMap<double> namap(new_graph);
678 678
  ///  dc.arcMap(namap, oamap);
679 679
  ///  // copy a node
680 680
  ///  OrigGraph::Node on;
681 681
  ///  NewGraph::Node nn;
682 682
  ///  dc.node(nn, on);
683 683
  ///  // Executions of copy
684 684
  ///  dc.run();
685 685
  ///\endcode
686 686
  template <typename To, typename From>
687 687
  class DigraphCopy {
688 688
  private:
689 689

	
690 690
    typedef typename From::Node Node;
691 691
    typedef typename From::NodeIt NodeIt;
692 692
    typedef typename From::Arc Arc;
693 693
    typedef typename From::ArcIt ArcIt;
694 694

	
695 695
    typedef typename To::Node TNode;
696 696
    typedef typename To::Arc TArc;
697 697

	
698 698
    typedef typename From::template NodeMap<TNode> NodeRefMap;
699 699
    typedef typename From::template ArcMap<TArc> ArcRefMap;
700 700

	
701 701

	
702 702
  public:
703 703

	
704 704

	
705 705
    /// \brief Constructor for the DigraphCopy.
706 706
    ///
707 707
    /// It copies the content of the \c _from digraph into the
708 708
    /// \c _to digraph.
709 709
    DigraphCopy(To& to, const From& from)
710 710
      : _from(from), _to(to) {}
711 711

	
712 712
    /// \brief Destructor of the DigraphCopy
713 713
    ///
714 714
    /// Destructor of the DigraphCopy
715 715
    ~DigraphCopy() {
716 716
      for (int i = 0; i < int(_node_maps.size()); ++i) {
717 717
        delete _node_maps[i];
718 718
      }
719 719
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
720 720
        delete _arc_maps[i];
721 721
      }
722 722

	
723 723
    }
724 724

	
725 725
    /// \brief Copies the node references into the given map.
726 726
    ///
727 727
    /// Copies the node references into the given map. The parameter
728 728
    /// should be a map, which key type is the Node type of the source
729 729
    /// graph, while the value type is the Node type of the
730 730
    /// destination graph.
731 731
    template <typename NodeRef>
732 732
    DigraphCopy& nodeRef(NodeRef& map) {
733 733
      _node_maps.push_back(new _graph_utils_bits::RefCopy<From, Node,
734 734
                           NodeRefMap, NodeRef>(map));
735 735
      return *this;
736 736
    }
737 737

	
738 738
    /// \brief Copies the node cross references into the given map.
739 739
    ///
740 740
    ///  Copies the node cross references (reverse references) into
741 741
    ///  the given map. The parameter should be a map, which key type
742 742
    ///  is the Node type of the destination graph, while the value type is
743 743
    ///  the Node type of the source graph.
744 744
    template <typename NodeCrossRef>
745 745
    DigraphCopy& nodeCrossRef(NodeCrossRef& map) {
746 746
      _node_maps.push_back(new _graph_utils_bits::CrossRefCopy<From, Node,
747 747
                           NodeRefMap, NodeCrossRef>(map));
748 748
      return *this;
749 749
    }
750 750

	
751 751
    /// \brief Make copy of the given map.
752 752
    ///
753 753
    /// Makes copy of the given map for the newly created digraph.
754 754
    /// The new map's key type is the destination graph's node type,
755 755
    /// and the copied map's key type is the source graph's node type.
756 756
    template <typename ToMap, typename FromMap>
757 757
    DigraphCopy& nodeMap(ToMap& tmap, const FromMap& map) {
758 758
      _node_maps.push_back(new _graph_utils_bits::MapCopy<From, Node,
759 759
                           NodeRefMap, ToMap, FromMap>(tmap, map));
760 760
      return *this;
761 761
    }
762 762

	
763 763
    /// \brief Make a copy of the given node.
764 764
    ///
765 765
    /// Make a copy of the given node.
766 766
    DigraphCopy& node(TNode& tnode, const Node& snode) {
767 767
      _node_maps.push_back(new _graph_utils_bits::ItemCopy<From, Node,
768 768
                           NodeRefMap, TNode>(tnode, snode));
769 769
      return *this;
770 770
    }
771 771

	
772 772
    /// \brief Copies the arc references into the given map.
773 773
    ///
774 774
    /// Copies the arc references into the given map.
775 775
    template <typename ArcRef>
776 776
    DigraphCopy& arcRef(ArcRef& map) {
777 777
      _arc_maps.push_back(new _graph_utils_bits::RefCopy<From, Arc,
778 778
                          ArcRefMap, ArcRef>(map));
779 779
      return *this;
780 780
    }
781 781

	
782 782
    /// \brief Copies the arc cross references into the given map.
783 783
    ///
784 784
    ///  Copies the arc cross references (reverse references) into
785 785
    ///  the given map.
786 786
    template <typename ArcCrossRef>
787 787
    DigraphCopy& arcCrossRef(ArcCrossRef& map) {
788 788
      _arc_maps.push_back(new _graph_utils_bits::CrossRefCopy<From, Arc,
789 789
                          ArcRefMap, ArcCrossRef>(map));
790 790
      return *this;
791 791
    }
792 792

	
793 793
    /// \brief Make copy of the given map.
794 794
    ///
795 795
    /// Makes copy of the given map for the newly created digraph.
796 796
    /// The new map's key type is the to digraph's arc type,
797 797
    /// and the copied map's key type is the from digraph's arc
798 798
    /// type.
799 799
    template <typename ToMap, typename FromMap>
800 800
    DigraphCopy& arcMap(ToMap& tmap, const FromMap& map) {
801 801
      _arc_maps.push_back(new _graph_utils_bits::MapCopy<From, Arc,
802 802
                          ArcRefMap, ToMap, FromMap>(tmap, map));
803 803
      return *this;
804 804
    }
805 805

	
806 806
    /// \brief Make a copy of the given arc.
807 807
    ///
808 808
    /// Make a copy of the given arc.
809 809
    DigraphCopy& arc(TArc& tarc, const Arc& sarc) {
810 810
      _arc_maps.push_back(new _graph_utils_bits::ItemCopy<From, Arc,
811 811
                          ArcRefMap, TArc>(tarc, sarc));
812 812
      return *this;
813 813
    }
814 814

	
815 815
    /// \brief Executes the copies.
816 816
    ///
817 817
    /// Executes the copies.
818 818
    void run() {
819 819
      NodeRefMap nodeRefMap(_from);
820 820
      ArcRefMap arcRefMap(_from);
821 821
      _graph_utils_bits::DigraphCopySelector<To>::
822 822
        copy(_to, _from, nodeRefMap, arcRefMap);
823 823
      for (int i = 0; i < int(_node_maps.size()); ++i) {
824 824
        _node_maps[i]->copy(_from, nodeRefMap);
825 825
      }
826 826
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
827 827
        _arc_maps[i]->copy(_from, arcRefMap);
828 828
      }
829 829
    }
830 830

	
831 831
  protected:
832 832

	
833 833

	
834 834
    const From& _from;
835 835
    To& _to;
836 836

	
837 837
    std::vector<_graph_utils_bits::MapCopyBase<From, Node, NodeRefMap>* >
838 838
    _node_maps;
839 839

	
840 840
    std::vector<_graph_utils_bits::MapCopyBase<From, Arc, ArcRefMap>* >
841 841
    _arc_maps;
842 842

	
843 843
  };
844 844

	
845 845
  /// \brief Copy a digraph to another digraph.
846 846
  ///
847 847
  /// Copy a digraph to another digraph. The complete usage of the
848 848
  /// function is detailed in the DigraphCopy class, but a short
849 849
  /// example shows a basic work:
850 850
  ///\code
851 851
  /// copyDigraph(trg, src).nodeRef(nr).arcCrossRef(ecr).run();
852 852
  ///\endcode
853 853
  ///
854 854
  /// After the copy the \c nr map will contain the mapping from the
855 855
  /// nodes of the \c from digraph to the nodes of the \c to digraph and
856 856
  /// \c ecr will contain the mapping from the arcs of the \c to digraph
857 857
  /// to the arcs of the \c from digraph.
858 858
  ///
859 859
  /// \see DigraphCopy
860 860
  template <typename To, typename From>
861 861
  DigraphCopy<To, From> copyDigraph(To& to, const From& from) {
862 862
    return DigraphCopy<To, From>(to, from);
863 863
  }
864 864

	
865 865
  /// \brief Class to copy a graph.
866 866
  ///
867 867
  /// Class to copy a graph to another graph (duplicate a graph). The
868 868
  /// simplest way of using it is through the \c copyGraph() function.
869 869
  ///
870 870
  /// This class not just make a copy of a graph, but it can create
871 871
  /// references and cross references between the nodes, edges and arcs of
872 872
  /// the two graphs, it can copy maps for use with the newly created
873 873
  /// graph and copy nodes, edges and arcs.
874 874
  ///
875 875
  /// To make a copy from a graph, first an instance of GraphCopy
876 876
  /// should be created, then the data belongs to the graph should
877 877
  /// assigned to copy. In the end, the \c run() member should be
878 878
  /// called.
879 879
  ///
880 880
  /// The next code copies a graph with several data:
881 881
  ///\code
882 882
  ///  GraphCopy<NewGraph, OrigGraph> dc(new_graph, orig_graph);
883 883
  ///  // create a reference for the nodes
884 884
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
885 885
  ///  dc.nodeRef(nr);
886 886
  ///  // create a cross reference (inverse) for the edges
887 887
  ///  NewGraph::EdgeMap<OrigGraph::Arc> ecr(new_graph);
888 888
  ///  dc.edgeCrossRef(ecr);
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 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/graph_utils.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
         : _value(value), _converter(converter) {}
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
            _use_nodes(false), _use_arcs(false),
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
            _use_nodes(false), _use_arcs(false),
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
790 790
    /// could not be read due to lack of node name resolving.
791 791
    /// Therefore \c skipArcs() function should also be used, or
792 792
    /// \c useNodes() should be used to specify the label of the nodes.
793 793
    DigraphReader& skipNodes() {
794 794
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
795 795
      _skip_nodes = true;
796 796
      return *this;
797 797
    }
798 798

	
799 799
    /// \brief Skips the reading of arc section
800 800
    ///
801 801
    /// Omit the reading of the arc section. This implies that each arc
802 802
    /// map reading rule will be abandoned, and the arcs of the graph
803 803
    /// will not be constructed.
804 804
    DigraphReader& skipArcs() {
805 805
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
806 806
      _skip_arcs = true;
807 807
      return *this;
808 808
    }
809 809

	
810 810
    /// @}
811 811

	
812 812
  private:
813 813

	
814 814
    bool readLine() {
815 815
      std::string str;
816 816
      while(++line_num, std::getline(*_is, str)) {
817 817
        line.clear(); line.str(str);
818 818
        char c;
819 819
        if (line >> std::ws >> c && c != '#') {
820 820
          line.putback(c);
821 821
          return true;
822 822
        }
823 823
      }
824 824
      return false;
825 825
    }
826 826

	
827 827
    bool readSuccess() {
828 828
      return static_cast<bool>(*_is);
829 829
    }
830 830

	
831 831
    void skipSection() {
832 832
      char c;
833 833
      while (readSuccess() && line >> c && c != '@') {
834 834
        readLine();
835 835
      }
836 836
      line.putback(c);
837 837
    }
838 838

	
839 839
    void readNodes() {
840 840

	
841 841
      std::vector<int> map_index(_node_maps.size());
842 842
      int map_num, label_index;
843 843

	
844 844
      char c;
845 845
      if (!readLine() || !(line >> c) || c == '@') {
846 846
        if (readSuccess() && line) line.putback(c);
847 847
        if (!_node_maps.empty())
848 848
          throw DataFormatError("Cannot find map names");
849 849
        return;
850 850
      }
851 851
      line.putback(c);
852 852

	
853 853
      {
854 854
        std::map<std::string, int> maps;
855 855

	
856 856
        std::string map;
857 857
        int index = 0;
858 858
        while (_reader_bits::readToken(line, map)) {
859 859
          if (maps.find(map) != maps.end()) {
860 860
            std::ostringstream msg;
861 861
            msg << "Multiple occurence of node map: " << map;
862 862
            throw DataFormatError(msg.str().c_str());
863 863
          }
864 864
          maps.insert(std::make_pair(map, index));
865 865
          ++index;
866 866
        }
867 867

	
868 868
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
869 869
          std::map<std::string, int>::iterator jt =
870 870
            maps.find(_node_maps[i].first);
871 871
          if (jt == maps.end()) {
872 872
            std::ostringstream msg;
873 873
            msg << "Map not found in file: " << _node_maps[i].first;
874 874
            throw DataFormatError(msg.str().c_str());
875 875
          }
876 876
          map_index[i] = jt->second;
877 877
        }
878 878

	
879 879
        {
880 880
          std::map<std::string, int>::iterator jt = maps.find("label");
881 881
          if (jt != maps.end()) {
882 882
            label_index = jt->second;
883 883
          } else {
884 884
            label_index = -1;
885 885
          }
886 886
        }
887 887
        map_num = maps.size();
888 888
      }
889 889

	
890 890
      while (readLine() && line >> c && c != '@') {
891 891
        line.putback(c);
892 892

	
893 893
        std::vector<std::string> tokens(map_num);
894 894
        for (int i = 0; i < map_num; ++i) {
895 895
          if (!_reader_bits::readToken(line, tokens[i])) {
896 896
            std::ostringstream msg;
897 897
            msg << "Column not found (" << i + 1 << ")";
898 898
            throw DataFormatError(msg.str().c_str());
899 899
          }
900 900
        }
901 901
        if (line >> std::ws >> c)
902 902
          throw DataFormatError("Extra character on the end of line");
903 903

	
904 904
        Node n;
905 905
        if (!_use_nodes) {
906 906
          n = _digraph.addNode();
907 907
          if (label_index != -1)
908 908
            _node_index.insert(std::make_pair(tokens[label_index], n));
909 909
        } else {
910 910
          if (label_index == -1)
911 911
            throw DataFormatError("Label map not found in file");
912 912
          typename std::map<std::string, Node>::iterator it =
913 913
            _node_index.find(tokens[label_index]);
914 914
          if (it == _node_index.end()) {
915 915
            std::ostringstream msg;
916 916
            msg << "Node with label not found: " << tokens[label_index];
917 917
            throw DataFormatError(msg.str().c_str());
918 918
          }
919 919
          n = it->second;
920 920
        }
921 921

	
922 922
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
923 923
          _node_maps[i].second->set(n, tokens[map_index[i]]);
924 924
        }
925 925

	
926 926
      }
927 927
      if (readSuccess()) {
928 928
        line.putback(c);
929 929
      }
930 930
    }
931 931

	
932 932
    void readArcs() {
933 933

	
934 934
      std::vector<int> map_index(_arc_maps.size());
935 935
      int map_num, label_index;
936 936

	
937 937
      char c;
938 938
      if (!readLine() || !(line >> c) || c == '@') {
939 939
        if (readSuccess() && line) line.putback(c);
940 940
        if (!_arc_maps.empty())
941 941
          throw DataFormatError("Cannot find map names");
942 942
        return;
943 943
      }
944 944
      line.putback(c);
945 945

	
946 946
      {
947 947
        std::map<std::string, int> maps;
948 948

	
949 949
        std::string map;
950 950
        int index = 0;
951 951
        while (_reader_bits::readToken(line, map)) {
952 952
          if (maps.find(map) != maps.end()) {
953 953
            std::ostringstream msg;
954 954
            msg << "Multiple occurence of arc map: " << map;
955 955
            throw DataFormatError(msg.str().c_str());
956 956
          }
957 957
          maps.insert(std::make_pair(map, index));
958 958
          ++index;
959 959
        }
960 960

	
961 961
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
962 962
          std::map<std::string, int>::iterator jt =
963 963
            maps.find(_arc_maps[i].first);
964 964
          if (jt == maps.end()) {
965 965
            std::ostringstream msg;
966 966
            msg << "Map not found in file: " << _arc_maps[i].first;
967 967
            throw DataFormatError(msg.str().c_str());
968 968
          }
969 969
          map_index[i] = jt->second;
970 970
        }
971 971

	
972 972
        {
973 973
          std::map<std::string, int>::iterator jt = maps.find("label");
974 974
          if (jt != maps.end()) {
975 975
            label_index = jt->second;
976 976
          } else {
977 977
            label_index = -1;
978 978
          }
979 979
        }
980 980
        map_num = maps.size();
981 981
      }
982 982

	
983 983
      while (readLine() && line >> c && c != '@') {
984 984
        line.putback(c);
985 985

	
986 986
        std::string source_token;
987 987
        std::string target_token;
988 988

	
989 989
        if (!_reader_bits::readToken(line, source_token))
990 990
          throw DataFormatError("Source not found");
991 991

	
992 992
        if (!_reader_bits::readToken(line, target_token))
993 993
          throw DataFormatError("Target not found");
994 994

	
995 995
        std::vector<std::string> tokens(map_num);
996 996
        for (int i = 0; i < map_num; ++i) {
997 997
          if (!_reader_bits::readToken(line, tokens[i])) {
998 998
            std::ostringstream msg;
999 999
            msg << "Column not found (" << i + 1 << ")";
1000 1000
            throw DataFormatError(msg.str().c_str());
1001 1001
          }
1002 1002
        }
1003 1003
        if (line >> std::ws >> c)
1004 1004
          throw DataFormatError("Extra character on the end of line");
1005 1005

	
1006 1006
        Arc a;
1007 1007
        if (!_use_arcs) {
1008 1008

	
1009 1009
          typename NodeIndex::iterator it;
1010 1010

	
1011 1011
          it = _node_index.find(source_token);
1012 1012
          if (it == _node_index.end()) {
1013 1013
            std::ostringstream msg;
1014 1014
            msg << "Item not found: " << source_token;
1015 1015
            throw DataFormatError(msg.str().c_str());
1016 1016
          }
1017 1017
          Node source = it->second;
1018 1018

	
1019 1019
          it = _node_index.find(target_token);
1020 1020
          if (it == _node_index.end()) {
1021 1021
            std::ostringstream msg;
1022 1022
            msg << "Item not found: " << target_token;
1023 1023
            throw DataFormatError(msg.str().c_str());
1024 1024
          }
1025 1025
          Node target = it->second;
1026 1026

	
1027 1027
          a = _digraph.addArc(source, target);
1028 1028
          if (label_index != -1)
1029 1029
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1030 1030
        } else {
1031 1031
          if (label_index == -1)
1032 1032
            throw DataFormatError("Label map not found in file");
1033 1033
          typename std::map<std::string, Arc>::iterator it =
1034 1034
            _arc_index.find(tokens[label_index]);
1035 1035
          if (it == _arc_index.end()) {
1036 1036
            std::ostringstream msg;
1037 1037
            msg << "Arc with label not found: " << tokens[label_index];
1038 1038
            throw DataFormatError(msg.str().c_str());
1039 1039
          }
1040 1040
          a = it->second;
1041 1041
        }
1042 1042

	
1043 1043
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1044 1044
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1045 1045
        }
1046 1046

	
1047 1047
      }
1048 1048
      if (readSuccess()) {
1049 1049
        line.putback(c);
1050 1050
      }
1051 1051
    }
1052 1052

	
1053 1053
    void readAttributes() {
1054 1054

	
1055 1055
      std::set<std::string> read_attr;
1056 1056

	
1057 1057
      char c;
1058 1058
      while (readLine() && line >> c && c != '@') {
1059 1059
        line.putback(c);
1060 1060

	
1061 1061
        std::string attr, token;
1062 1062
        if (!_reader_bits::readToken(line, attr))
1063 1063
          throw DataFormatError("Attribute name not found");
1064 1064
        if (!_reader_bits::readToken(line, token))
1065 1065
          throw DataFormatError("Attribute value not found");
1066 1066
        if (line >> c)
1067 1067
          throw DataFormatError("Extra character on the end of line");
1068 1068

	
1069 1069
        {
1070 1070
          std::set<std::string>::iterator it = read_attr.find(attr);
1071 1071
          if (it != read_attr.end()) {
1072 1072
            std::ostringstream msg;
1073 1073
            msg << "Multiple occurence of attribute " << attr;
1074 1074
            throw DataFormatError(msg.str().c_str());
1075 1075
          }
1076 1076
          read_attr.insert(attr);
1077 1077
        }
1078 1078

	
1079 1079
        {
1080 1080
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1081 1081
          while (it != _attributes.end() && it->first == attr) {
1082 1082
            it->second->set(token);
1083 1083
            ++it;
1084 1084
          }
1085 1085
        }
1086 1086

	
1087 1087
      }
1088 1088
      if (readSuccess()) {
1089 1089
        line.putback(c);
1090 1090
      }
1091 1091
      for (typename Attributes::iterator it = _attributes.begin();
1092 1092
           it != _attributes.end(); ++it) {
1093 1093
        if (read_attr.find(it->first) == read_attr.end()) {
1094 1094
          std::ostringstream msg;
1095 1095
          msg << "Attribute not found in file: " << it->first;
1096 1096
          throw DataFormatError(msg.str().c_str());
1097 1097
        }
1098 1098
      }
1099 1099
    }
1100 1100

	
1101 1101
  public:
1102 1102

	
1103 1103
    /// \name Execution of the reader
1104 1104
    /// @{
1105 1105

	
1106 1106
    /// \brief Start the batch processing
1107 1107
    ///
1108 1108
    /// This function starts the batch processing
1109 1109
    void run() {
1110 1110
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1111 1111
      if (!*_is) {
1112 1112
        throw DataFormatError("Cannot find file");
1113 1113
      }
1114 1114

	
1115 1115
      bool nodes_done = _skip_nodes;
1116 1116
      bool arcs_done = _skip_arcs;
1117 1117
      bool attributes_done = false;
1118 1118

	
1119 1119
      line_num = 0;
1120 1120
      readLine();
1121 1121
      skipSection();
1122 1122

	
1123 1123
      while (readSuccess()) {
1124 1124
        try {
1125 1125
          char c;
1126 1126
          std::string section, caption;
1127 1127
          line >> c;
1128 1128
          _reader_bits::readToken(line, section);
1129 1129
          _reader_bits::readToken(line, caption);
1130 1130

	
1131 1131
          if (line >> c)
1132 1132
            throw DataFormatError("Extra character on the end of line");
1133 1133

	
1134 1134
          if (section == "nodes" && !nodes_done) {
1135 1135
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1136 1136
              readNodes();
1137 1137
              nodes_done = true;
1138 1138
            }
1139 1139
          } else if ((section == "arcs" || section == "edges") &&
1140 1140
                     !arcs_done) {
1141 1141
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1142 1142
              readArcs();
1143 1143
              arcs_done = true;
1144 1144
            }
1145 1145
          } else if (section == "attributes" && !attributes_done) {
1146 1146
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1147 1147
              readAttributes();
1148 1148
              attributes_done = true;
1149 1149
            }
1150 1150
          } else {
1151 1151
            readLine();
1152 1152
            skipSection();
1153 1153
          }
1154 1154
        } catch (DataFormatError& error) {
1155 1155
          error.line(line_num);
1156 1156
          throw;
1157 1157
        }
1158 1158
      }
1159 1159

	
1160 1160
      if (!nodes_done) {
1161 1161
        throw DataFormatError("Section @nodes not found");
1162 1162
      }
1163 1163

	
1164 1164
      if (!arcs_done) {
1165 1165
        throw DataFormatError("Section @arcs not found");
1166 1166
      }
1167 1167

	
1168 1168
      if (!attributes_done && !_attributes.empty()) {
1169 1169
        throw DataFormatError("Section @attributes not found");
1170 1170
      }
1171 1171

	
1172 1172
    }
1173 1173

	
1174 1174
    /// @}
1175 1175

	
1176 1176
  };
1177 1177

	
1178 1178
  /// \brief Return a \ref DigraphReader class
1179 1179
  ///
1180 1180
  /// This function just returns a \ref DigraphReader class.
1181 1181
  /// \relates DigraphReader
1182 1182
  template <typename Digraph>
1183 1183
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1184 1184
    DigraphReader<Digraph> tmp(is, digraph);
1185 1185
    return tmp;
1186 1186
  }
1187 1187

	
1188 1188
  /// \brief Return a \ref DigraphReader class
1189 1189
  ///
1190 1190
  /// This function just returns a \ref DigraphReader class.
1191 1191
  /// \relates DigraphReader
1192 1192
  template <typename Digraph>
1193 1193
  DigraphReader<Digraph> digraphReader(const std::string& fn,
1194 1194
                                       Digraph& digraph) {
1195 1195
    DigraphReader<Digraph> tmp(fn, digraph);
1196 1196
    return tmp;
1197 1197
  }
1198 1198

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

	
1209 1209
  template <typename Graph>
1210 1210
  class GraphReader;
1211 1211

	
1212 1212
  template <typename Graph>
1213 1213
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph);
1214 1214

	
1215 1215
  template <typename Graph>
1216 1216
  GraphReader<Graph> graphReader(const std::string& fn, Graph& graph);
1217 1217

	
1218 1218
  template <typename Graph>
1219 1219
  GraphReader<Graph> graphReader(const char *fn, Graph& graph);
1220 1220

	
1221 1221
  /// \ingroup lemon_io
1222 1222
  ///
1223 1223
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1224 1224
  ///
1225 1225
  /// This utility reads an \ref lgf-format "LGF" file.
1226 1226
  ///
1227 1227
  /// It can be used almost the same way as \c DigraphReader.
1228 1228
  /// The only difference is that this class can handle edges and
1229 1229
  /// edge maps as well as arcs and arc maps.
1230 1230
  ///
1231 1231
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1232 1232
  /// edge maps. However, if there are two maps with the same name
1233 1233
  /// prefixed with \c '+' and \c '-', then these can be read into an
1234 1234
  /// arc map.  Similarly, an attribute can be read into an arc, if
1235 1235
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1236 1236
  template <typename _Graph>
1237 1237
  class GraphReader {
1238 1238
  public:
1239 1239

	
1240 1240
    typedef _Graph Graph;
1241 1241
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1242 1242

	
1243 1243
  private:
1244 1244

	
1245 1245
    std::istream* _is;
1246 1246
    bool local_is;
1247 1247

	
1248 1248
    Graph& _graph;
1249 1249

	
1250 1250
    std::string _nodes_caption;
1251 1251
    std::string _edges_caption;
1252 1252
    std::string _attributes_caption;
1253 1253

	
1254 1254
    typedef std::map<std::string, Node> NodeIndex;
1255 1255
    NodeIndex _node_index;
1256 1256
    typedef std::map<std::string, Edge> EdgeIndex;
1257 1257
    EdgeIndex _edge_index;
1258 1258

	
1259 1259
    typedef std::vector<std::pair<std::string,
1260 1260
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1261 1261
    NodeMaps _node_maps;
1262 1262

	
1263 1263
    typedef std::vector<std::pair<std::string,
1264 1264
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1265 1265
    EdgeMaps _edge_maps;
1266 1266

	
1267 1267
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1268 1268
      Attributes;
1269 1269
    Attributes _attributes;
1270 1270

	
1271 1271
    bool _use_nodes;
1272 1272
    bool _use_edges;
1273 1273

	
1274 1274
    bool _skip_nodes;
1275 1275
    bool _skip_edges;
1276 1276

	
1277 1277
    int line_num;
1278 1278
    std::istringstream line;
1279 1279

	
1280 1280
  public:
1281 1281

	
1282 1282
    /// \brief Constructor
1283 1283
    ///
1284 1284
    /// Construct an undirected graph reader, which reads from the given
1285 1285
    /// input stream.
1286 1286
    GraphReader(std::istream& is, Graph& graph)
1287 1287
      : _is(&is), local_is(false), _graph(graph),
1288 1288
        _use_nodes(false), _use_edges(false),
1289 1289
        _skip_nodes(false), _skip_edges(false) {}
1290 1290

	
1291 1291
    /// \brief Constructor
1292 1292
    ///
1293 1293
    /// Construct an undirected graph reader, which reads from the given
1294 1294
    /// file.
1295 1295
    GraphReader(const std::string& fn, Graph& graph)
1296 1296
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1297
            _use_nodes(false), _use_edges(false),
1297
        _use_nodes(false), _use_edges(false),
1298 1298
        _skip_nodes(false), _skip_edges(false) {}
1299 1299

	
1300 1300
    /// \brief Constructor
1301 1301
    ///
1302 1302
    /// Construct an undirected graph reader, which reads from the given
1303 1303
    /// file.
1304 1304
    GraphReader(const char* fn, Graph& graph)
1305 1305
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1306
            _use_nodes(false), _use_edges(false),
1306
        _use_nodes(false), _use_edges(false),
1307 1307
        _skip_nodes(false), _skip_edges(false) {}
1308 1308

	
1309 1309
    /// \brief Destructor
1310 1310
    ~GraphReader() {
1311 1311
      for (typename NodeMaps::iterator it = _node_maps.begin();
1312 1312
           it != _node_maps.end(); ++it) {
1313 1313
        delete it->second;
1314 1314
      }
1315 1315

	
1316 1316
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1317 1317
           it != _edge_maps.end(); ++it) {
1318 1318
        delete it->second;
1319 1319
      }
1320 1320

	
1321 1321
      for (typename Attributes::iterator it = _attributes.begin();
1322 1322
           it != _attributes.end(); ++it) {
1323 1323
        delete it->second;
1324 1324
      }
1325 1325

	
1326 1326
      if (local_is) {
1327 1327
        delete _is;
1328 1328
      }
1329 1329

	
1330 1330
    }
1331 1331

	
1332 1332
  private:
1333 1333
    friend GraphReader<Graph> graphReader<>(std::istream& is, Graph& graph);
1334 1334
    friend GraphReader<Graph> graphReader<>(const std::string& fn,
1335 1335
                                            Graph& graph);
1336 1336
    friend GraphReader<Graph> graphReader<>(const char *fn, Graph& graph);
1337 1337

	
1338 1338
    GraphReader(GraphReader& other)
1339 1339
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1340 1340
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1341 1341
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1342 1342

	
1343 1343
      other._is = 0;
1344 1344
      other.local_is = false;
1345 1345

	
1346 1346
      _node_index.swap(other._node_index);
1347 1347
      _edge_index.swap(other._edge_index);
1348 1348

	
1349 1349
      _node_maps.swap(other._node_maps);
1350 1350
      _edge_maps.swap(other._edge_maps);
1351 1351
      _attributes.swap(other._attributes);
1352 1352

	
1353 1353
      _nodes_caption = other._nodes_caption;
1354 1354
      _edges_caption = other._edges_caption;
1355 1355
      _attributes_caption = other._attributes_caption;
1356 1356

	
1357 1357
    }
1358 1358

	
1359 1359
    GraphReader& operator=(const GraphReader&);
1360 1360

	
1361 1361
  public:
1362 1362

	
1363 1363
    /// \name Reading rules
1364 1364
    /// @{
1365 1365

	
1366 1366
    /// \brief Node map reading rule
1367 1367
    ///
1368 1368
    /// Add a node map reading rule to the reader.
1369 1369
    template <typename Map>
1370 1370
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1371 1371
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1372 1372
      _reader_bits::MapStorageBase<Node>* storage =
1373 1373
        new _reader_bits::MapStorage<Node, Map>(map);
1374 1374
      _node_maps.push_back(std::make_pair(caption, storage));
1375 1375
      return *this;
1376 1376
    }
1377 1377

	
1378 1378
    /// \brief Node map reading rule
1379 1379
    ///
1380 1380
    /// Add a node map reading rule with specialized converter to the
1381 1381
    /// reader.
1382 1382
    template <typename Map, typename Converter>
1383 1383
    GraphReader& nodeMap(const std::string& caption, Map& map,
1384 1384
                           const Converter& converter = Converter()) {
1385 1385
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1386 1386
      _reader_bits::MapStorageBase<Node>* storage =
1387 1387
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1388 1388
      _node_maps.push_back(std::make_pair(caption, storage));
1389 1389
      return *this;
1390 1390
    }
1391 1391

	
1392 1392
    /// \brief Edge map reading rule
1393 1393
    ///
1394 1394
    /// Add an edge map reading rule to the reader.
1395 1395
    template <typename Map>
1396 1396
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1397 1397
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1398 1398
      _reader_bits::MapStorageBase<Edge>* storage =
1399 1399
        new _reader_bits::MapStorage<Edge, Map>(map);
1400 1400
      _edge_maps.push_back(std::make_pair(caption, storage));
1401 1401
      return *this;
1402 1402
    }
1403 1403

	
1404 1404
    /// \brief Edge map reading rule
1405 1405
    ///
1406 1406
    /// Add an edge map reading rule with specialized converter to the
1407 1407
    /// reader.
1408 1408
    template <typename Map, typename Converter>
1409 1409
    GraphReader& edgeMap(const std::string& caption, Map& map,
1410 1410
                          const Converter& converter = Converter()) {
1411 1411
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1412 1412
      _reader_bits::MapStorageBase<Edge>* storage =
1413 1413
        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1414 1414
      _edge_maps.push_back(std::make_pair(caption, storage));
1415 1415
      return *this;
1416 1416
    }
1417 1417

	
1418 1418
    /// \brief Arc map reading rule
1419 1419
    ///
1420 1420
    /// Add an arc map reading rule to the reader.
1421 1421
    template <typename Map>
1422 1422
    GraphReader& arcMap(const std::string& caption, Map& map) {
1423 1423
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1424 1424
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1425 1425
        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1426 1426
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1427 1427
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1428 1428
        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1429 1429
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1430 1430
      return *this;
1431 1431
    }
1432 1432

	
1433 1433
    /// \brief Arc map reading rule
1434 1434
    ///
1435 1435
    /// Add an arc map reading rule with specialized converter to the
1436 1436
    /// reader.
1437 1437
    template <typename Map, typename Converter>
1438 1438
    GraphReader& arcMap(const std::string& caption, Map& map,
1439 1439
                          const Converter& converter = Converter()) {
1440 1440
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1441 1441
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1442 1442
        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1443 1443
        (_graph, map, converter);
1444 1444
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1445 1445
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1446 1446
        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1447 1447
        (_graph, map, converter);
1448 1448
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1449 1449
      return *this;
1450 1450
    }
1451 1451

	
1452 1452
    /// \brief Attribute reading rule
1453 1453
    ///
1454 1454
    /// Add an attribute reading rule to the reader.
1455 1455
    template <typename Value>
1456 1456
    GraphReader& attribute(const std::string& caption, Value& value) {
1457 1457
      _reader_bits::ValueStorageBase* storage =
1458 1458
        new _reader_bits::ValueStorage<Value>(value);
1459 1459
      _attributes.insert(std::make_pair(caption, storage));
1460 1460
      return *this;
1461 1461
    }
1462 1462

	
1463 1463
    /// \brief Attribute reading rule
1464 1464
    ///
1465 1465
    /// Add an attribute reading rule with specialized converter to the
1466 1466
    /// reader.
1467 1467
    template <typename Value, typename Converter>
1468 1468
    GraphReader& attribute(const std::string& caption, Value& value,
1469 1469
                             const Converter& converter = Converter()) {
1470 1470
      _reader_bits::ValueStorageBase* storage =
1471 1471
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1472 1472
      _attributes.insert(std::make_pair(caption, storage));
1473 1473
      return *this;
1474 1474
    }
1475 1475

	
1476 1476
    /// \brief Node reading rule
1477 1477
    ///
1478 1478
    /// Add a node reading rule to reader.
1479 1479
    GraphReader& node(const std::string& caption, Node& node) {
1480 1480
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1481 1481
      Converter converter(_node_index);
1482 1482
      _reader_bits::ValueStorageBase* storage =
1483 1483
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1484 1484
      _attributes.insert(std::make_pair(caption, storage));
1485 1485
      return *this;
1486 1486
    }
1487 1487

	
1488 1488
    /// \brief Edge reading rule
1489 1489
    ///
1490 1490
    /// Add an edge reading rule to reader.
1491 1491
    GraphReader& edge(const std::string& caption, Edge& edge) {
1492 1492
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1493 1493
      Converter converter(_edge_index);
1494 1494
      _reader_bits::ValueStorageBase* storage =
1495 1495
        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1496 1496
      _attributes.insert(std::make_pair(caption, storage));
1497 1497
      return *this;
1498 1498
    }
1499 1499

	
1500 1500
    /// \brief Arc reading rule
1501 1501
    ///
1502 1502
    /// Add an arc reading rule to reader.
1503 1503
    GraphReader& arc(const std::string& caption, Arc& arc) {
1504 1504
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1505 1505
      Converter converter(_graph, _edge_index);
1506 1506
      _reader_bits::ValueStorageBase* storage =
1507 1507
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1508 1508
      _attributes.insert(std::make_pair(caption, storage));
1509 1509
      return *this;
1510 1510
    }
1511 1511

	
1512 1512
    /// @}
1513 1513

	
1514 1514
    /// \name Select section by name
1515 1515
    /// @{
1516 1516

	
1517 1517
    /// \brief Set \c \@nodes section to be read
1518 1518
    ///
1519 1519
    /// Set \c \@nodes section to be read.
1520 1520
    GraphReader& nodes(const std::string& caption) {
1521 1521
      _nodes_caption = caption;
1522 1522
      return *this;
1523 1523
    }
1524 1524

	
1525 1525
    /// \brief Set \c \@edges section to be read
1526 1526
    ///
1527 1527
    /// Set \c \@edges section to be read.
1528 1528
    GraphReader& edges(const std::string& caption) {
1529 1529
      _edges_caption = caption;
1530 1530
      return *this;
1531 1531
    }
1532 1532

	
1533 1533
    /// \brief Set \c \@attributes section to be read
1534 1534
    ///
1535 1535
    /// Set \c \@attributes section to be read.
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
    ///
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 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/graph_utils.h>
38 38

	
39 39
namespace lemon {
40 40

	
41 41
  namespace _writer_bits {
42 42

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
306 306
  }
307 307

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

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

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

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

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

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

	
374 374
  private:
375 375

	
376 376

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

	
380 380
    const Digraph& _digraph;
381 381

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

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

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

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

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

	
403 403
    bool _skip_nodes;
404 404
    bool _skip_arcs;
405 405

	
406 406
  public:
407 407

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

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

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

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

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

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

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

	
454 454
  private:
455 455

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

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

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

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

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

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

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

	
484 484
  public:
485 485

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
637 637
    /// @}
638 638

	
639 639
  private:
640 640

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
831 831
  public:
832 832

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

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

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

	
860 860
    /// @}
861 861
  };
862 862

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

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

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

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

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

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

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

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

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

	
930 930
  private:
931 931

	
932 932

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

	
936 936
    Graph& _graph;
937 937

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

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

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

	
951 951
    typedef std::vector<std::pair<std::string,
952 952
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
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_LIST_GRAPH_H
20 20
#define LEMON_LIST_GRAPH_H
21 21

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

	
26 26
#include <lemon/bits/graph_extender.h>
27 27

	
28 28
#include <vector>
29 29
#include <list>
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  class ListDigraphBase {
34 34

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

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

	
47 47
    std::vector<NodeT> nodes;
48 48

	
49 49
    int first_node;
50 50

	
51 51
    int first_free_node;
52 52

	
53 53
    std::vector<ArcT> arcs;
54 54

	
55 55
    int first_free_arc;
56 56

	
57 57
  public:
58 58

	
59 59
    typedef ListDigraphBase Digraph;
60 60

	
61 61
    class Node {
62 62
      friend class ListDigraphBase;
63 63
    protected:
64 64

	
65 65
      int id;
66 66
      explicit Node(int pid) { id = pid;}
67 67

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

	
76 76
    class Arc {
77 77
      friend class ListDigraphBase;
78 78
    protected:
79 79

	
80 80
      int id;
81 81
      explicit Arc(int pid) { id = pid;}
82 82

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

	
91 91

	
92 92

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

	
97 97

	
98 98
    int maxNodeId() const { return nodes.size()-1; }
99 99
    int maxArcId() const { return arcs.size()-1; }
100 100

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

	
104 104

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

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

	
113 113

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

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

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

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

	
148 148

	
149 149
    static int id(Node v) { return v.id; }
150 150
    static int id(Arc e) { return e.id; }
151 151

	
152 152
    static Node nodeFromId(int id) { return Node(id);}
153 153
    static Arc arcFromId(int id) { return Arc(id);}
154 154

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

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

	
165 165
    Node addNode() {
166 166
      int n;
167 167

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

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

	
181 181
      nodes[n].first_in = nodes[n].first_out = -1;
182 182

	
183 183
      return Node(n);
184 184
    }
185 185

	
186 186
    Arc addArc(Node u, Node v) {
187 187
      int n;
188 188

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

	
197 197
      arcs[n].source = u.id;
198 198
      arcs[n].target = v.id;
199 199

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

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

	
210 210
      arcs[n].prev_in = arcs[n].prev_out = -1;
211 211

	
212 212
      nodes[u.id].first_out = nodes[v.id].first_in = n;
213 213

	
214 214
      return Arc(n);
215 215
    }
216 216

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

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

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

	
230 230
      nodes[n].next = first_free_node;
231 231
      first_free_node = n;
232 232
      nodes[n].prev = -2;
233 233

	
234 234
    }
235 235

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

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

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

	
249 249

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

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

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

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

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

	
303 303
  };
304 304

	
305 305
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
306 306

	
307 307
  /// \addtogroup graphs
308 308
  /// @{
309 309

	
310 310
  ///A general directed graph structure.
311 311

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

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

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

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

	
341 341
    typedef ExtendedListDigraphBase Parent;
342 342

	
343 343
    /// Constructor
344 344

	
345 345
    /// Constructor.
346 346
    ///
347 347
    ListDigraph() {}
348 348

	
349 349
    ///Add a new node to the digraph.
350 350

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

	
355 355
    ///Add a new arc to the digraph.
356 356

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

	
364 364
    /// Node validity check
365 365

	
366 366
    /// This function gives back true if the given node is valid,
367 367
    /// ie. it is a real node of the graph.
368 368
    ///
369 369
    /// \warning A Node pointing to a removed item
370 370
    /// could become valid again later if new nodes are
371 371
    /// added to the graph.
372 372
    bool valid(Node n) const { return Parent::valid(n); }
373 373

	
374 374
    /// Arc validity check
375 375

	
376 376
    /// This function gives back true if the given arc is valid,
377 377
    /// ie. it is a real arc of the graph.
378 378
    ///
379 379
    /// \warning An Arc pointing to a removed item
380 380
    /// could become valid again later if new nodes are
381 381
    /// added to the graph.
382 382
    bool valid(Arc a) const { return Parent::valid(a); }
383 383

	
384 384
    /// Change the target of \c e to \c n
385 385

	
386 386
    /// Change the target of \c e to \c n
387 387
    ///
388 388
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
389 389
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
390 390
    ///invalidated.
391 391
    ///
392 392
    ///\warning This functionality cannot be used together with the Snapshot
393 393
    ///feature.
394 394
    void changeTarget(Arc e, Node n) {
395 395
      Parent::changeTarget(e,n);
396 396
    }
397 397
    /// Change the source of \c e to \c n
398 398

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

	
411 411
    /// Invert the direction of an arc.
412 412

	
413 413
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
414 414
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
415 415
    ///invalidated.
416 416
    ///
417 417
    ///\warning This functionality cannot be used together with the Snapshot
418 418
    ///feature.
419 419
    void reverseArc(Arc e) {
420 420
      Node t=target(e);
421 421
      changeTarget(e,source(e));
422 422
      changeSource(e,t);
423 423
    }
424 424

	
425 425
    /// Reserve memory for nodes.
426 426

	
427 427
    /// Using this function it is possible to avoid the superfluous memory
428 428
    /// allocation: if you know that the digraph you want to build will
429 429
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
430 430
    /// then it is worth reserving space for this amount before starting
431 431
    /// to build the digraph.
432 432
    /// \sa reserveArc
433 433
    void reserveNode(int n) { nodes.reserve(n); };
434 434

	
435 435
    /// Reserve memory for arcs.
436 436

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

	
445 445
    ///Contract two nodes.
446 446

	
447 447
    ///This function contracts two nodes.
448 448
    ///Node \p b will be removed but instead of deleting
449 449
    ///incident arcs, they will be joined to \p a.
450 450
    ///The last parameter \p r controls whether to remove loops. \c true
451 451
    ///means that loops will be removed.
452 452
    ///
453 453
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
454 454
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
455 455
    ///may be invalidated.
456 456
    ///
457 457
    ///\warning This functionality cannot be used together with the Snapshot
458 458
    ///feature.
459 459
    void contract(Node a, Node b, bool r = true)
460 460
    {
461 461
      for(OutArcIt e(*this,b);e!=INVALID;) {
462 462
        OutArcIt f=e;
463 463
        ++f;
464 464
        if(r && target(e)==a) erase(e);
465 465
        else changeSource(e,a);
466 466
        e=f;
467 467
      }
468 468
      for(InArcIt e(*this,b);e!=INVALID;) {
469 469
        InArcIt f=e;
470 470
        ++f;
471 471
        if(r && source(e)==a) erase(e);
472 472
        else changeTarget(e,a);
473 473
        e=f;
474 474
      }
475 475
      erase(b);
476 476
    }
477 477

	
478 478
    ///Split a node.
479 479

	
480 480
    ///This function splits a node. First a new node is added to the digraph,
481 481
    ///then the source of each outgoing arc of \c n is moved to this new node.
482 482
    ///If \c connect is \c true (this is the default value), then a new arc
483 483
    ///from \c n to the newly created node is also added.
484 484
    ///\return The newly created node.
485 485
    ///
486 486
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
487 487
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
488 488
    ///be invalidated.
489 489
    ///
490 490
    ///\warning This functionality cannot be used together with the
491 491
    ///Snapshot feature.
492 492
    ///
493 493
    ///\todo It could be implemented in a bit faster way.
494 494
    Node split(Node n, bool connect = true) {
495 495
      Node b = addNode();
496 496
      for(OutArcIt e(*this,n);e!=INVALID;) {
497
         OutArcIt f=e;
497
        OutArcIt f=e;
498 498
        ++f;
499 499
        changeSource(e,b);
500 500
        e=f;
501 501
      }
502 502
      if (connect) addArc(n,b);
503 503
      return b;
504 504
    }
505 505

	
506 506
    ///Split an arc.
507 507

	
508 508
    ///This function splits an arc. First a new node \c b is added to
509 509
    ///the digraph, then the original arc is re-targeted to \c
510 510
    ///b. Finally an arc from \c b to the original target is added.
511 511
    ///
512 512
    ///\return The newly created node.
513 513
    ///
514 514
    ///\warning This functionality cannot be used together with the
515 515
    ///Snapshot feature.
516 516
    Node split(Arc e) {
517 517
      Node b = addNode();
518 518
      addArc(b,target(e));
519 519
      changeTarget(e,b);
520 520
      return b;
521 521
    }
522 522

	
523 523
    /// \brief Class to make a snapshot of the digraph and restore
524 524
    /// it later.
525 525
    ///
526 526
    /// Class to make a snapshot of the digraph and restore it later.
527 527
    ///
528 528
    /// The newly added nodes and arcs can be removed using the
529 529
    /// restore() function.
530 530
    ///
531 531
    /// \warning Arc and node deletions and other modifications (e.g.
532 532
    /// contracting, splitting, reversing arcs or nodes) cannot be
533 533
    /// restored. These events invalidate the snapshot.
534 534
    class Snapshot {
535 535
    protected:
536 536

	
537 537
      typedef Parent::NodeNotifier NodeNotifier;
538 538

	
539 539
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
540 540
      public:
541 541

	
542 542
        NodeObserverProxy(Snapshot& _snapshot)
543 543
          : snapshot(_snapshot) {}
544 544

	
545 545
        using NodeNotifier::ObserverBase::attach;
546 546
        using NodeNotifier::ObserverBase::detach;
547 547
        using NodeNotifier::ObserverBase::attached;
548 548

	
549 549
      protected:
550 550

	
551 551
        virtual void add(const Node& node) {
552 552
          snapshot.addNode(node);
553 553
        }
554 554
        virtual void add(const std::vector<Node>& nodes) {
555 555
          for (int i = nodes.size() - 1; i >= 0; ++i) {
556 556
            snapshot.addNode(nodes[i]);
557 557
          }
558 558
        }
559 559
        virtual void erase(const Node& node) {
560 560
          snapshot.eraseNode(node);
561 561
        }
562 562
        virtual void erase(const std::vector<Node>& nodes) {
563 563
          for (int i = 0; i < int(nodes.size()); ++i) {
564 564
            snapshot.eraseNode(nodes[i]);
565 565
          }
566 566
        }
567 567
        virtual void build() {
568 568
          Node node;
569 569
          std::vector<Node> nodes;
570 570
          for (notifier()->first(node); node != INVALID;
571 571
               notifier()->next(node)) {
572 572
            nodes.push_back(node);
573 573
          }
574 574
          for (int i = nodes.size() - 1; i >= 0; --i) {
575 575
            snapshot.addNode(nodes[i]);
576 576
          }
577 577
        }
578 578
        virtual void clear() {
579 579
          Node node;
580 580
          for (notifier()->first(node); node != INVALID;
581 581
               notifier()->next(node)) {
582 582
            snapshot.eraseNode(node);
583 583
          }
584 584
        }
585 585

	
586 586
        Snapshot& snapshot;
587 587
      };
588 588

	
589 589
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
590 590
      public:
591 591

	
592 592
        ArcObserverProxy(Snapshot& _snapshot)
593 593
          : snapshot(_snapshot) {}
594 594

	
595 595
        using ArcNotifier::ObserverBase::attach;
596 596
        using ArcNotifier::ObserverBase::detach;
597 597
        using ArcNotifier::ObserverBase::attached;
598 598

	
599 599
      protected:
600 600

	
601 601
        virtual void add(const Arc& arc) {
602 602
          snapshot.addArc(arc);
603 603
        }
604 604
        virtual void add(const std::vector<Arc>& arcs) {
605 605
          for (int i = arcs.size() - 1; i >= 0; ++i) {
606 606
            snapshot.addArc(arcs[i]);
607 607
          }
608 608
        }
609 609
        virtual void erase(const Arc& arc) {
610 610
          snapshot.eraseArc(arc);
611 611
        }
612 612
        virtual void erase(const std::vector<Arc>& arcs) {
613 613
          for (int i = 0; i < int(arcs.size()); ++i) {
614 614
            snapshot.eraseArc(arcs[i]);
615 615
          }
616 616
        }
617 617
        virtual void build() {
618 618
          Arc arc;
619 619
          std::vector<Arc> arcs;
620 620
          for (notifier()->first(arc); arc != INVALID;
621 621
               notifier()->next(arc)) {
622 622
            arcs.push_back(arc);
623 623
          }
624 624
          for (int i = arcs.size() - 1; i >= 0; --i) {
625 625
            snapshot.addArc(arcs[i]);
626 626
          }
627 627
        }
628 628
        virtual void clear() {
629 629
          Arc arc;
630 630
          for (notifier()->first(arc); arc != INVALID;
631 631
               notifier()->next(arc)) {
632 632
            snapshot.eraseArc(arc);
633 633
          }
634 634
        }
635 635

	
636 636
        Snapshot& snapshot;
637 637
      };
638 638

	
639 639
      ListDigraph *digraph;
640 640

	
641 641
      NodeObserverProxy node_observer_proxy;
642 642
      ArcObserverProxy arc_observer_proxy;
643 643

	
644 644
      std::list<Node> added_nodes;
645 645
      std::list<Arc> added_arcs;
646 646

	
647 647

	
648 648
      void addNode(const Node& node) {
649 649
        added_nodes.push_front(node);
650 650
      }
651 651
      void eraseNode(const Node& node) {
652 652
        std::list<Node>::iterator it =
653 653
          std::find(added_nodes.begin(), added_nodes.end(), node);
654 654
        if (it == added_nodes.end()) {
655 655
          clear();
656 656
          arc_observer_proxy.detach();
657 657
          throw NodeNotifier::ImmediateDetach();
658 658
        } else {
659 659
          added_nodes.erase(it);
660 660
        }
661 661
      }
662 662

	
663 663
      void addArc(const Arc& arc) {
664 664
        added_arcs.push_front(arc);
665 665
      }
666 666
      void eraseArc(const Arc& arc) {
667 667
        std::list<Arc>::iterator it =
668 668
          std::find(added_arcs.begin(), added_arcs.end(), arc);
669 669
        if (it == added_arcs.end()) {
670 670
          clear();
671 671
          node_observer_proxy.detach();
672 672
          throw ArcNotifier::ImmediateDetach();
673 673
        } else {
674 674
          added_arcs.erase(it);
675 675
        }
676 676
      }
677 677

	
678 678
      void attach(ListDigraph &_digraph) {
679 679
        digraph = &_digraph;
680 680
        node_observer_proxy.attach(digraph->notifier(Node()));
681 681
        arc_observer_proxy.attach(digraph->notifier(Arc()));
682 682
      }
683 683

	
684 684
      void detach() {
685 685
        node_observer_proxy.detach();
686 686
        arc_observer_proxy.detach();
687 687
      }
688 688

	
689 689
      bool attached() const {
690 690
        return node_observer_proxy.attached();
691 691
      }
692 692

	
693 693
      void clear() {
694 694
        added_nodes.clear();
695 695
        added_arcs.clear();
696 696
      }
697 697

	
698 698
    public:
699 699

	
700 700
      /// \brief Default constructor.
701 701
      ///
702 702
      /// Default constructor.
703 703
      /// To actually make a snapshot you must call save().
704 704
      Snapshot()
705 705
        : digraph(0), node_observer_proxy(*this),
706 706
          arc_observer_proxy(*this) {}
707 707

	
708 708
      /// \brief Constructor that immediately makes a snapshot.
709 709
      ///
710 710
      /// This constructor immediately makes a snapshot of the digraph.
711 711
      /// \param _digraph The digraph we make a snapshot of.
712 712
      Snapshot(ListDigraph &_digraph)
713 713
        : node_observer_proxy(*this),
714 714
          arc_observer_proxy(*this) {
715 715
        attach(_digraph);
716 716
      }
717 717

	
718 718
      /// \brief Make a snapshot.
719 719
      ///
720 720
      /// Make a snapshot of the digraph.
721 721
      ///
722 722
      /// This function can be called more than once. In case of a repeated
723 723
      /// call, the previous snapshot gets lost.
724 724
      /// \param _digraph The digraph we make the snapshot of.
725 725
      void save(ListDigraph &_digraph) {
726 726
        if (attached()) {
727 727
          detach();
728 728
          clear();
729 729
        }
730 730
        attach(_digraph);
731 731
      }
732 732

	
733 733
      /// \brief Undo the changes until the last snapshot.
734 734
      //
735 735
      /// Undo the changes until the last snapshot created by save().
736 736
      void restore() {
737 737
        detach();
738 738
        for(std::list<Arc>::iterator it = added_arcs.begin();
739 739
            it != added_arcs.end(); ++it) {
740 740
          digraph->erase(*it);
741 741
        }
742 742
        for(std::list<Node>::iterator it = added_nodes.begin();
743 743
            it != added_nodes.end(); ++it) {
744 744
          digraph->erase(*it);
745 745
        }
746 746
        clear();
747 747
      }
748 748

	
749 749
      /// \brief Gives back true when the snapshot is valid.
750 750
      ///
751 751
      /// Gives back true when the snapshot is valid.
752 752
      bool valid() const {
753 753
        return attached();
754 754
      }
755 755
    };
756 756

	
757 757
  };
758 758

	
759 759
  ///@}
760 760

	
761 761
  class ListGraphBase {
762 762

	
763 763
  protected:
764 764

	
765 765
    struct NodeT {
766 766
      int first_out;
767 767
      int prev, next;
768 768
    };
769 769

	
770 770
    struct ArcT {
771 771
      int target;
772 772
      int prev_out, next_out;
773 773
    };
774 774

	
775 775
    std::vector<NodeT> nodes;
776 776

	
777 777
    int first_node;
778 778

	
779 779
    int first_free_node;
780 780

	
781 781
    std::vector<ArcT> arcs;
782 782

	
783 783
    int first_free_arc;
784 784

	
785 785
  public:
786 786

	
787 787
    typedef ListGraphBase Digraph;
788 788

	
789 789
    class Node;
790 790
    class Arc;
791 791
    class Edge;
792 792

	
793 793
    class Node {
794 794
      friend class ListGraphBase;
795 795
    protected:
796 796

	
797 797
      int id;
798 798
      explicit Node(int pid) { id = pid;}
799 799

	
800 800
    public:
801 801
      Node() {}
802 802
      Node (Invalid) { id = -1; }
803 803
      bool operator==(const Node& node) const {return id == node.id;}
804 804
      bool operator!=(const Node& node) const {return id != node.id;}
805 805
      bool operator<(const Node& node) const {return id < node.id;}
806 806
    };
807 807

	
808 808
    class Edge {
809 809
      friend class ListGraphBase;
810 810
    protected:
811 811

	
812 812
      int id;
813 813
      explicit Edge(int pid) { id = pid;}
814 814

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

	
823 823
    class Arc {
824 824
      friend class ListGraphBase;
825 825
    protected:
826 826

	
827 827
      int id;
828 828
      explicit Arc(int pid) { id = pid;}
829 829

	
830 830
    public:
831 831
      operator Edge() const { return edgeFromId(id / 2); }
832 832

	
833 833
      Arc() {}
834 834
      Arc (Invalid) { id = -1; }
835 835
      bool operator==(const Arc& arc) const {return id == arc.id;}
836 836
      bool operator!=(const Arc& arc) const {return id != arc.id;}
837 837
      bool operator<(const Arc& arc) const {return id < arc.id;}
838 838
    };
839 839

	
840 840

	
841 841

	
842 842
    ListGraphBase()
843 843
      : nodes(), first_node(-1),
844 844
        first_free_node(-1), arcs(), first_free_arc(-1) {}
845 845

	
846 846

	
847 847
    int maxNodeId() const { return nodes.size()-1; }
848 848
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
849 849
    int maxArcId() const { return arcs.size()-1; }
850 850

	
851 851
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
852 852
    Node target(Arc e) const { return Node(arcs[e.id].target); }
853 853

	
854 854
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
855 855
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
856 856

	
857 857
    static bool direction(Arc e) {
858 858
      return (e.id & 1) == 1;
859 859
    }
860 860

	
861 861
    static Arc direct(Edge e, bool d) {
862 862
      return Arc(e.id * 2 + (d ? 1 : 0));
863 863
    }
864 864

	
865 865
    void first(Node& node) const {
866 866
      node.id = first_node;
867 867
    }
868 868

	
869 869
    void next(Node& node) const {
870 870
      node.id = nodes[node.id].next;
871 871
    }
872 872

	
873 873
    void first(Arc& e) const {
874 874
      int n = first_node;
875 875
      while (n != -1 && nodes[n].first_out == -1) {
876 876
        n = nodes[n].next;
877 877
      }
878 878
      e.id = (n == -1) ? -1 : nodes[n].first_out;
879 879
    }
880 880

	
881 881
    void next(Arc& e) const {
882 882
      if (arcs[e.id].next_out != -1) {
883 883
        e.id = arcs[e.id].next_out;
884 884
      } else {
885 885
        int n = nodes[arcs[e.id ^ 1].target].next;
886 886
        while(n != -1 && nodes[n].first_out == -1) {
887 887
          n = nodes[n].next;
888 888
        }
889 889
        e.id = (n == -1) ? -1 : nodes[n].first_out;
890 890
      }
891 891
    }
892 892

	
893 893
    void first(Edge& e) const {
894 894
      int n = first_node;
895 895
      while (n != -1) {
896 896
        e.id = nodes[n].first_out;
897 897
        while ((e.id & 1) != 1) {
898 898
          e.id = arcs[e.id].next_out;
899 899
        }
900 900
        if (e.id != -1) {
901 901
          e.id /= 2;
902 902
          return;
903 903
        }
904 904
        n = nodes[n].next;
905 905
      }
906 906
      e.id = -1;
907 907
    }
908 908

	
909 909
    void next(Edge& e) const {
910 910
      int n = arcs[e.id * 2].target;
911 911
      e.id = arcs[(e.id * 2) | 1].next_out;
912 912
      while ((e.id & 1) != 1) {
913 913
        e.id = arcs[e.id].next_out;
914 914
      }
915 915
      if (e.id != -1) {
916 916
        e.id /= 2;
917 917
        return;
918 918
      }
919 919
      n = nodes[n].next;
920 920
      while (n != -1) {
921 921
        e.id = nodes[n].first_out;
922 922
        while ((e.id & 1) != 1) {
923 923
          e.id = arcs[e.id].next_out;
924 924
        }
925 925
        if (e.id != -1) {
926 926
          e.id /= 2;
927 927
          return;
928 928
        }
929 929
        n = nodes[n].next;
930 930
      }
931 931
      e.id = -1;
932 932
    }
933 933

	
934 934
    void firstOut(Arc &e, const Node& v) const {
935 935
      e.id = nodes[v.id].first_out;
936 936
    }
937 937
    void nextOut(Arc &e) const {
938 938
      e.id = arcs[e.id].next_out;
939 939
    }
940 940

	
941 941
    void firstIn(Arc &e, const Node& v) const {
942 942
      e.id = ((nodes[v.id].first_out) ^ 1);
943 943
      if (e.id == -2) e.id = -1;
944 944
    }
945 945
    void nextIn(Arc &e) const {
946 946
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
947 947
      if (e.id == -2) e.id = -1;
948 948
    }
949 949

	
950 950
    void firstInc(Edge &e, bool& d, const Node& v) const {
951 951
      int a = nodes[v.id].first_out;
952 952
      if (a != -1 ) {
953 953
        e.id = a / 2;
954 954
        d = ((a & 1) == 1);
955 955
      } else {
956 956
        e.id = -1;
957 957
        d = true;
958 958
      }
959 959
    }
960 960
    void nextInc(Edge &e, bool& d) const {
961 961
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
962 962
      if (a != -1 ) {
963 963
        e.id = a / 2;
964 964
        d = ((a & 1) == 1);
965 965
      } else {
966 966
        e.id = -1;
967 967
        d = true;
968 968
      }
969 969
    }
970 970

	
971 971
    static int id(Node v) { return v.id; }
972 972
    static int id(Arc e) { return e.id; }
973 973
    static int id(Edge e) { return e.id; }
974 974

	
975 975
    static Node nodeFromId(int id) { return Node(id);}
976 976
    static Arc arcFromId(int id) { return Arc(id);}
977 977
    static Edge edgeFromId(int id) { return Edge(id);}
978 978

	
979 979
    bool valid(Node n) const {
980 980
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
981 981
        nodes[n.id].prev != -2;
982 982
    }
983 983

	
984 984
    bool valid(Arc a) const {
985 985
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
986 986
        arcs[a.id].prev_out != -2;
987 987
    }
988 988

	
989 989
    bool valid(Edge e) const {
990 990
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
991 991
        arcs[2 * e.id].prev_out != -2;
992 992
    }
993 993

	
994 994
    Node addNode() {
995 995
      int n;
996 996

	
997 997
      if(first_free_node==-1) {
998 998
        n = nodes.size();
999 999
        nodes.push_back(NodeT());
1000 1000
      } else {
1001 1001
        n = first_free_node;
1002 1002
        first_free_node = nodes[n].next;
1003 1003
      }
1004 1004

	
1005 1005
      nodes[n].next = first_node;
1006 1006
      if (first_node != -1) nodes[first_node].prev = n;
1007 1007
      first_node = n;
1008 1008
      nodes[n].prev = -1;
1009 1009

	
1010 1010
      nodes[n].first_out = -1;
1011 1011

	
1012 1012
      return Node(n);
1013 1013
    }
1014 1014

	
1015 1015
    Edge addEdge(Node u, Node v) {
1016 1016
      int n;
1017 1017

	
1018 1018
      if (first_free_arc == -1) {
1019 1019
        n = arcs.size();
1020 1020
        arcs.push_back(ArcT());
1021 1021
        arcs.push_back(ArcT());
1022 1022
      } else {
1023 1023
        n = first_free_arc;
1024 1024
        first_free_arc = arcs[n].next_out;
1025 1025
      }
1026 1026

	
1027 1027
      arcs[n].target = u.id;
1028 1028
      arcs[n | 1].target = v.id;
1029 1029

	
1030 1030
      arcs[n].next_out = nodes[v.id].first_out;
1031 1031
      if (nodes[v.id].first_out != -1) {
1032 1032
        arcs[nodes[v.id].first_out].prev_out = n;
1033 1033
      }
1034 1034
      arcs[n].prev_out = -1;
1035 1035
      nodes[v.id].first_out = n;
1036 1036

	
1037 1037
      arcs[n | 1].next_out = nodes[u.id].first_out;
1038 1038
      if (nodes[u.id].first_out != -1) {
1039 1039
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1040 1040
      }
1041 1041
      arcs[n | 1].prev_out = -1;
1042 1042
      nodes[u.id].first_out = (n | 1);
1043 1043

	
1044 1044
      return Edge(n / 2);
1045 1045
    }
1046 1046

	
1047 1047
    void erase(const Node& node) {
1048 1048
      int n = node.id;
1049 1049

	
1050 1050
      if(nodes[n].next != -1) {
1051 1051
        nodes[nodes[n].next].prev = nodes[n].prev;
1052 1052
      }
1053 1053

	
1054 1054
      if(nodes[n].prev != -1) {
1055 1055
        nodes[nodes[n].prev].next = nodes[n].next;
1056 1056
      } else {
1057 1057
        first_node = nodes[n].next;
1058 1058
      }
1059 1059

	
1060 1060
      nodes[n].next = first_free_node;
1061 1061
      first_free_node = n;
1062 1062
      nodes[n].prev = -2;
1063 1063
    }
1064 1064

	
1065 1065
    void erase(const Edge& edge) {
1066 1066
      int n = edge.id * 2;
1067 1067

	
1068 1068
      if (arcs[n].next_out != -1) {
1069 1069
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1070 1070
      }
1071 1071

	
1072 1072
      if (arcs[n].prev_out != -1) {
1073 1073
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1074 1074
      } else {
1075 1075
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1076 1076
      }
1077 1077

	
1078 1078
      if (arcs[n | 1].next_out != -1) {
1079 1079
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1080 1080
      }
1081 1081

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

	
1088 1088
      arcs[n].next_out = first_free_arc;
1089 1089
      first_free_arc = n;
1090 1090
      arcs[n].prev_out = -2;
1091 1091
      arcs[n | 1].prev_out = -2;
1092 1092

	
1093 1093
    }
1094 1094

	
1095 1095
    void clear() {
1096 1096
      arcs.clear();
1097 1097
      nodes.clear();
1098 1098
      first_node = first_free_node = first_free_arc = -1;
1099 1099
    }
1100 1100

	
1101 1101
  protected:
1102 1102

	
1103 1103
    void changeTarget(Edge e, Node n) {
1104 1104
      if(arcs[2 * e.id].next_out != -1) {
1105 1105
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1106 1106
      }
1107 1107
      if(arcs[2 * e.id].prev_out != -1) {
1108 1108
        arcs[arcs[2 * e.id].prev_out].next_out =
1109 1109
          arcs[2 * e.id].next_out;
1110 1110
      } else {
1111 1111
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1112 1112
          arcs[2 * e.id].next_out;
1113 1113
      }
1114 1114

	
1115 1115
      if (nodes[n.id].first_out != -1) {
1116 1116
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1117 1117
      }
1118 1118
      arcs[(2 * e.id) | 1].target = n.id;
1119 1119
      arcs[2 * e.id].prev_out = -1;
1120 1120
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1121 1121
      nodes[n.id].first_out = 2 * e.id;
1122 1122
    }
1123 1123

	
1124 1124
    void changeSource(Edge e, Node n) {
1125 1125
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1126 1126
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1127 1127
          arcs[(2 * e.id) | 1].prev_out;
1128 1128
      }
1129 1129
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1130 1130
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1131 1131
          arcs[(2 * e.id) | 1].next_out;
1132 1132
      } else {
1133 1133
        nodes[arcs[2 * e.id].target].first_out =
1134 1134
          arcs[(2 * e.id) | 1].next_out;
1135 1135
      }
1136 1136

	
1137 1137
      if (nodes[n.id].first_out != -1) {
1138 1138
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1139 1139
      }
1140 1140
      arcs[2 * e.id].target = n.id;
1141 1141
      arcs[(2 * e.id) | 1].prev_out = -1;
1142 1142
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1143 1143
      nodes[n.id].first_out = ((2 * e.id) | 1);
1144 1144
    }
1145 1145

	
1146 1146
  };
1147 1147

	
1148 1148
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1149 1149

	
1150 1150

	
1151 1151
  /// \addtogroup graphs
1152 1152
  /// @{
1153 1153

	
1154 1154
  ///A general undirected graph structure.
1155 1155

	
1156 1156
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1157 1157
  ///implementation based on static linked lists that are stored in
1158 1158
  ///\c std::vector structures.
1159 1159
  ///
1160 1160
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1161 1161
  ///also provides several useful additional functionalities.
1162 1162
  ///Most of the member functions and nested classes are documented
1163 1163
  ///only in the concept class.
1164 1164
  ///
1165 1165
  ///An important extra feature of this graph implementation is that
1166 1166
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1167 1167
  ///
1168 1168
  ///\sa concepts::Graph
1169 1169

	
1170 1170
  class ListGraph : public ExtendedListGraphBase {
1171 1171
  private:
1172 1172
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1173 1173

	
1174 1174
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1175 1175
    ///
1176 1176
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1177 1177
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1178 1178
    ///Use copyGraph() instead.
1179 1179

	
1180 1180
    ///Assignment of ListGraph to another one is \e not allowed.
1181 1181
    ///Use copyGraph() instead.
1182 1182
    void operator=(const ListGraph &) {}
1183 1183
  public:
1184 1184
    /// Constructor
1185 1185

	
1186 1186
    /// Constructor.
1187 1187
    ///
1188 1188
    ListGraph() {}
1189 1189

	
1190 1190
    typedef ExtendedListGraphBase Parent;
1191 1191

	
1192 1192
    typedef Parent::OutArcIt IncEdgeIt;
1193 1193

	
1194 1194
    /// \brief Add a new node to the graph.
1195 1195
    ///
1196 1196
    /// Add a new node to the graph.
1197 1197
    /// \return the new node.
1198 1198
    Node addNode() { return Parent::addNode(); }
1199 1199

	
1200 1200
    /// \brief Add a new edge to the graph.
1201 1201
    ///
1202 1202
    /// Add a new edge to the graph with source node \c s
1203 1203
    /// and target node \c t.
1204 1204
    /// \return the new edge.
1205 1205
    Edge addEdge(const Node& s, const Node& t) {
1206 1206
      return Parent::addEdge(s, t);
1207 1207
    }
1208 1208
    /// Node validity check
1209 1209

	
1210 1210
    /// This function gives back true if the given node is valid,
1211 1211
    /// ie. it is a real node of the graph.
1212 1212
    ///
1213 1213
    /// \warning A Node pointing to a removed item
1214 1214
    /// could become valid again later if new nodes are
1215 1215
    /// added to the graph.
1216 1216
    bool valid(Node n) const { return Parent::valid(n); }
1217 1217
    /// Arc validity check
1218 1218

	
1219 1219
    /// This function gives back true if the given arc is valid,
1220 1220
    /// ie. it is a real arc of the graph.
1221 1221
    ///
1222 1222
    /// \warning An Arc pointing to a removed item
1223 1223
    /// could become valid again later if new edges are
1224 1224
    /// added to the graph.
1225 1225
    bool valid(Arc a) const { return Parent::valid(a); }
1226 1226
    /// Edge validity check
1227 1227

	
1228 1228
    /// This function gives back true if the given edge is valid,
1229 1229
    /// ie. it is a real arc of the graph.
1230 1230
    ///
1231 1231
    /// \warning A Edge pointing to a removed item
1232 1232
    /// could become valid again later if new edges are
1233 1233
    /// added to the graph.
1234 1234
    bool valid(Edge e) const { return Parent::valid(e); }
1235 1235
    /// \brief Change the source of \c e to \c n
1236 1236
    ///
1237 1237
    /// This function changes the source of \c e to \c n.
1238 1238
    ///
1239 1239
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1240 1240
    ///referencing the changed arc remain
1241 1241
    ///valid. However <tt>OutArcIt</tt>s are invalidated.
1242 1242
    ///
1243 1243
    ///\warning This functionality cannot be used together with the
1244 1244
    ///Snapshot feature.
1245 1245
    void changeSource(Edge e, Node n) {
1246 1246
      Parent::changeSource(e,n);
1247 1247
    }
1248 1248
    /// \brief Change the target of \c e to \c n
1249 1249
    ///
1250 1250
    /// This function changes the target of \c e to \c n.
1251 1251
    ///
1252 1252
    /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
1253 1253
    /// valid. However the other iterators may be invalidated.
1254 1254
    ///
1255 1255
    ///\warning This functionality cannot be used together with the
1256 1256
    ///Snapshot feature.
1257 1257
    void changeTarget(Edge e, Node n) {
1258 1258
      Parent::changeTarget(e,n);
1259 1259
    }
1260 1260
    /// \brief Change the source of \c e to \c n
1261 1261
    ///
1262 1262
    /// This function changes the source of \c e to \c n.
1263 1263
    /// It also changes the proper node of the represented edge.
1264 1264
    ///
1265 1265
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
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
#include <iostream>
20 20
#include <fstream>
21 21
#include <string>
22 22
#include <vector>
23 23

	
24 24
#include <lemon/concept_check.h>
25 25
#include <lemon/concepts/heap.h>
26 26

	
27 27
#include <lemon/smart_graph.h>
28 28

	
29 29
#include <lemon/lgf_reader.h>
30 30
#include <lemon/dijkstra.h>
31 31
#include <lemon/maps.h>
32 32

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

	
35 35
#include "test_tools.h"
36 36

	
37 37
using namespace lemon;
38 38
using namespace lemon::concepts;
39 39

	
40 40
typedef ListDigraph Digraph;
41 41
DIGRAPH_TYPEDEFS(Digraph);
42 42

	
43 43
char test_lgf[] =
44 44
  "@nodes\n"
45 45
  "label\n"
46 46
  "0\n"
47 47
  "1\n"
48 48
  "2\n"
49 49
  "3\n"
50 50
  "4\n"
51 51
  "5\n"
52 52
  "6\n"
53 53
  "7\n"
54 54
  "8\n"
55 55
  "9\n"
56 56
  "@arcs\n"
57
  "                label        capacity\n"
58
  "0        5        0        94\n"
59
  "3        9        1        11\n"
60
  "8        7        2        83\n"
61
  "1        2        3        94\n"
62
  "5        7        4        35\n"
63
  "7        4        5        84\n"
64
  "9        5        6        38\n"
65
  "0        4        7        96\n"
66
  "6        7        8        6\n"
67
  "3        1        9        27\n"
68
  "5        2        10        77\n"
69
  "5        6        11        69\n"
70
  "6        5        12        41\n"
71
  "4        6        13        70\n"
72
  "3        2        14        45\n"
73
  "7        9        15        93\n"
74
  "5        9        16        50\n"
75
  "9        0        17        94\n"
76
  "9        6        18        67\n"
77
  "0        9        19        86\n"
57
  "                label   capacity\n"
58
  "0       5       0       94\n"
59
  "3       9       1       11\n"
60
  "8       7       2       83\n"
61
  "1       2       3       94\n"
62
  "5       7       4       35\n"
63
  "7       4       5       84\n"
64
  "9       5       6       38\n"
65
  "0       4       7       96\n"
66
  "6       7       8       6\n"
67
  "3       1       9       27\n"
68
  "5       2       10      77\n"
69
  "5       6       11      69\n"
70
  "6       5       12      41\n"
71
  "4       6       13      70\n"
72
  "3       2       14      45\n"
73
  "7       9       15      93\n"
74
  "5       9       16      50\n"
75
  "9       0       17      94\n"
76
  "9       6       18      67\n"
77
  "0       9       19      86\n"
78 78
  "@attributes\n"
79 79
  "source 3\n";
80 80

	
81 81
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
82 82
int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
83 83

	
84 84
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
85 85

	
86 86
template <typename Heap>
87 87
void heapSortTest() {
88 88
  RangeMap<int> map(test_len, -1);
89 89

	
90 90
  Heap heap(map);
91 91

	
92 92
  std::vector<int> v(test_len);
93 93

	
94 94
  for (int i = 0; i < test_len; ++i) {
95 95
    v[i] = test_seq[i];
96 96
    heap.push(i, v[i]);
97 97
  }
98 98
  std::sort(v.begin(), v.end());
99 99
  for (int i = 0; i < test_len; ++i) {
100 100
    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
101 101
    heap.pop();
102 102
  }
103 103
}
104 104

	
105 105
template <typename Heap>
106 106
void heapIncreaseTest() {
107 107
  RangeMap<int> map(test_len, -1);
108 108

	
109 109
  Heap heap(map);
110 110

	
111 111
  std::vector<int> v(test_len);
112 112

	
113 113
  for (int i = 0; i < test_len; ++i) {
114 114
    v[i] = test_seq[i];
115 115
    heap.push(i, v[i]);
116 116
  }
117 117
  for (int i = 0; i < test_len; ++i) {
118 118
    v[i] += test_inc[i];
119 119
    heap.increase(i, v[i]);
120 120
  }
121 121
  std::sort(v.begin(), v.end());
122 122
  for (int i = 0; i < test_len; ++i) {
123 123
    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
124 124
    heap.pop();
125 125
  }
126 126
}
127 127

	
128 128

	
129 129

	
130 130
template <typename Heap>
131 131
void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
132 132
                      Node source) {
133 133

	
134 134
  typename Dijkstra<Digraph, IntArcMap>::template DefStandardHeap<Heap>::
135 135
    Create dijkstra(digraph, length);
136 136

	
137 137
  dijkstra.run(source);
138 138

	
139 139
  for(ArcIt a(digraph); a != INVALID; ++a) {
140 140
    Node s = digraph.source(a);
141 141
    Node t = digraph.target(a);
142 142
    if (dijkstra.reached(s)) {
143 143
      check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
144
                   "Error in a shortest path tree!");
144
             "Error in a shortest path tree!");
145 145
    }
146 146
  }
147 147

	
148 148
  for(NodeIt n(digraph); n != INVALID; ++n) {
149 149
    if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
150 150
      Arc a = dijkstra.predArc(n);
151 151
      Node s = digraph.source(a);
152 152
      check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
153 153
             "Error in a shortest path tree!");
154 154
    }
155 155
  }
156 156

	
157 157
}
158 158

	
159 159
int main() {
160 160

	
161 161
  typedef int Item;
162 162
  typedef int Prio;
163 163
  typedef RangeMap<int> ItemIntMap;
164 164

	
165 165
  Digraph digraph;
166 166
  IntArcMap length(digraph);
167 167
  Node source;
168 168

	
169 169
  std::istringstream input(test_lgf);
170 170
  digraphReader(input, digraph).
171 171
    arcMap("capacity", length).
172 172
    node("source", source).
173 173
    run();
174 174

	
175 175
  {
176 176
    typedef BinHeap<Prio, ItemIntMap> IntHeap;
177 177
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
178 178
    heapSortTest<IntHeap>();
179 179
    heapIncreaseTest<IntHeap>();
180 180

	
181 181
    typedef BinHeap<Prio, IntNodeMap > NodeHeap;
182 182
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
183 183
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
184 184
  }
185 185

	
186 186
  return 0;
187 187
}
0 comments (0 inline)