gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge bugfixes #211, #212, #215, #229 and #230
0 11 1
merge 1.0
2 files changed with 252 insertions and 400 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1
#cmakedefine HAVE_LONG_LONG 1
... ...
 No newline at end of file
Ignore white space 6 line context
1 1
syntax: glob
2 2
*.obj
3 3
*.orig
4 4
*.rej
5 5
*~
6 6
*.o
7 7
*.log
8 8
*.lo
9 9
*.tar.*
10 10
*.bak
11 11
Makefile.in
12 12
aclocal.m4
13 13
config.h.in
14 14
configure
15 15
Makefile
16 16
config.h
17 17
config.log
18 18
config.status
19 19
libtool
20 20
stamp-h1
21 21
lemon/lemon.pc
22 22
lemon/libemon.la
23 23
lemon/stamp-h2
24 24
doc/Doxyfile
25
cmake/cmake.version
25 26
.dirstamp
26 27
.libs/*
27 28
.deps/*
28 29
demo/*.eps
29 30

	
30 31
syntax: regexp
31 32
(.*/)?\#[^/]*\#$
32 33
(.*/)?\.\#[^/]*$
33 34
^doc/html/.*
34 35
^doc/.*\.tag
35 36
^autom4te.cache/.*
36 37
^build-aux/.*
37 38
^objs.*/.*
38 39
^test/[a-z_]*$
39 40
^demo/.*_demo$
40 41
^build/.*
41 42
^doc/gen-images/.*
42 43
CMakeFiles
43 44
DartTestfile.txt
44 45
cmake_install.cmake
45 46
CMakeCache.txt
Ignore white space 6 line context
1 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2 2

	
3 3
IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
4 4
  INCLUDE(${CMAKE_SOURCE_DIR}/cmake/version.cmake)
5 5
ELSE(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
6 6
  SET(PROJECT_NAME "LEMON")
7 7
  SET(PROJECT_VERSION "hg-tip" CACHE STRING "LEMON version string.")
8 8
ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
9 9

	
10 10
PROJECT(${PROJECT_NAME})
11 11

	
12 12
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
13 13

	
14 14
IF(MSVC)
15 15
  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250 /wd4355 /wd4800 /wd4996")
16 16
# Suppressed warnings:
17 17
# C4250: 'class1' : inherits 'class2::member' via dominance
18 18
# C4355: 'this' : used in base member initializer list
19 19
# C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
20 20
# C4996: 'function': was declared deprecated
21 21
ENDIF(MSVC)
22 22

	
23 23
INCLUDE(FindDoxygen)
24 24
INCLUDE(FindGhostscript)
25 25

	
26
INCLUDE(CheckTypeSize)
27
CHECK_TYPE_SIZE("long long" LONG_LONG)
28

	
26 29
ENABLE_TESTING()
27 30

	
28 31
ADD_SUBDIRECTORY(lemon)
29 32
ADD_SUBDIRECTORY(demo)
30 33
ADD_SUBDIRECTORY(doc)
31 34
ADD_SUBDIRECTORY(test)
32 35

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

	
40 43
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
41 44

	
42 45
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
43 46
    "${PROJECT_NAME} ${PROJECT_VERSION}")
44 47
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
45 48
    "${PROJECT_NAME} ${PROJECT_VERSION}")
46 49

	
47 50
  SET(CPACK_COMPONENTS_ALL headers library html_documentation)
48 51

	
49 52
  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
50 53
  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
51 54
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
52 55

	
53 56
  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
54 57
    "C++ header files")
55 58
  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
56 59
    "DLL and import library")
57 60
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
58 61
    "Doxygen generated documentation")
59 62

	
60 63
  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
61 64

	
62 65
  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
63 66
  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
64 67
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
65 68

	
66 69
  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
67 70
    "Components needed to develop software using LEMON")
68 71
  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
69 72
    "Documentation of LEMON")
70 73

	
71 74
  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
72 75

	
73 76
  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
74 77
  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
75 78
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
76 79

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

	
94 97
  INCLUDE(CPack)
95 98
ENDIF(WIN32)
Ignore white space 6 line context
1 1
dnl Process this file with autoconf to produce a configure script.
2 2

	
3 3
dnl Version information.
4 4
m4_define([lemon_version_number],
5 5
	[m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
6 6
dnl m4_define([lemon_version_number], [])
7 7
m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
8 8
m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
9 9
m4_define([lemon_version], [ifelse(lemon_version_number(),
10 10
			   [],
11 11
			   [lemon_hg_path().lemon_hg_revision()],
12 12
			   [lemon_version_number()])])
13 13

	
14 14
AC_PREREQ([2.59])
15 15
AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
16 16
AC_CONFIG_AUX_DIR([build-aux])
17 17
AC_CONFIG_MACRO_DIR([m4])
18 18
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
19 19
AC_CONFIG_SRCDIR([lemon/list_graph.h])
20 20
AC_CONFIG_HEADERS([config.h lemon/config.h])
21 21

	
22 22
lx_cmdline_cxxflags_set=${CXXFLAGS+set}
23 23

	
24 24
dnl Do compilation tests using the C++ compiler.
25 25
AC_LANG([C++])
26 26

	
27
dnl Check the existence of long long type.
28
AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
29
if test x"$long_long_found" = x"yes"; then
30
  AC_DEFINE([HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
31
fi
32

	
27 33
dnl Checks for programs.
28 34
AC_PROG_CXX
29 35
AC_PROG_CXXCPP
30 36
AC_PROG_INSTALL
31 37
AC_DISABLE_SHARED
32 38
AC_PROG_LIBTOOL
33 39

	
34 40
AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
35 41
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
36 42

	
37 43
dnl Detect Intel compiler.
38 44
AC_MSG_CHECKING([whether we are using the Intel C++ compiler])
39 45
AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER
40 46
choke me
41 47
#endif], [ICC=[yes]], [ICC=[no]])
42 48
if test x"$ICC" = x"yes"; then
43 49
  AC_MSG_RESULT([yes])
44 50
else
45 51
  AC_MSG_RESULT([no])
46 52
fi
47 53

	
48 54
dnl Set custom compiler flags when using g++.
49 55
if test x"$lx_cmdline_cxxflags_set" != x"set" -a "$GXX" = yes -a "$ICC" = no; then
50 56
  CXXFLAGS="$CXXFLAGS -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
51 57
fi
52 58

	
53 59
dnl Checks for libraries.
54 60
#LX_CHECK_GLPK
55 61
#LX_CHECK_CPLEX
56 62
#LX_CHECK_SOPLEX
57 63

	
58 64
dnl Disable/enable building the demo programs.
59 65
AC_ARG_ENABLE([demo],
60 66
AS_HELP_STRING([--enable-demo], [build the demo programs])
61 67
AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
62 68
              [], [enable_demo=no])
63 69
AC_MSG_CHECKING([whether to build the demo programs])
64 70
if test x"$enable_demo" != x"no"; then
65 71
  AC_MSG_RESULT([yes])
66 72
else
67 73
  AC_MSG_RESULT([no])
68 74
fi
69 75
AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
70 76

	
71 77
dnl Disable/enable building the binary tools.
72 78
AC_ARG_ENABLE([tools],
73 79
AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
74 80
AS_HELP_STRING([--disable-tools], [do not build additional tools]),
75 81
              [], [enable_tools=yes])
76 82
AC_MSG_CHECKING([whether to build the additional tools])
77 83
if test x"$enable_tools" != x"no"; then
78 84
  AC_MSG_RESULT([yes])
79 85
else
80 86
  AC_MSG_RESULT([no])
81 87
fi
82 88
AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
83 89

	
84 90
dnl Checks for header files.
85 91
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
86 92

	
87 93
dnl Checks for typedefs, structures, and compiler characteristics.
88 94
AC_C_CONST
89 95
AC_C_INLINE
90 96
AC_TYPE_SIZE_T
91 97
AC_HEADER_TIME
92 98
AC_STRUCT_TM
93 99

	
94 100
dnl Checks for library functions.
95 101
AC_HEADER_STDC
96 102
AC_CHECK_FUNCS(gettimeofday times ctime_r)
97 103

	
98 104
dnl Add dependencies on files generated by configure.
99 105
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
100 106
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
101 107

	
102 108
AC_CONFIG_FILES([
103 109
Makefile
104 110
cmake/version.cmake
105 111
doc/Doxyfile
106 112
lemon/lemon.pc
107 113
])
108 114

	
109 115
AC_OUTPUT
110 116

	
111 117
echo
112 118
echo '****************************** SUMMARY ******************************'
113 119
echo
114 120
echo Package version............... : $PACKAGE-$VERSION
115 121
echo
116 122
echo C++ compiler.................. : $CXX
117 123
echo C++ compiles flags............ : $CXXFLAGS
118 124
echo
125
echo Compiler supports long long... : $long_long_found
126
echo
119 127
#echo GLPK support.................. : $lx_glpk_found
120 128
#echo CPLEX support................. : $lx_cplex_found
121 129
#echo SOPLEX support................ : $lx_soplex_found
122 130
#echo
123 131
echo Build demo programs........... : $enable_demo
124 132
echo Build additional tools........ : $enable_tools
125 133
echo
126 134
echo The packace will be installed in
127 135
echo -n '  '
128 136
echo $prefix.
129 137
echo
130 138
echo '*********************************************************************'
131 139

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

	
19 19
#ifndef LEMON_BITS_DEFAULT_MAP_H
20 20
#define LEMON_BITS_DEFAULT_MAP_H
21 21

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

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

	
30 30
namespace lemon {
31 31

	
32 32

	
33 33
  //#ifndef LEMON_USE_DEBUG_MAP
34 34

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

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

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

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

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

	
62 62

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

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

	
74 74

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

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

	
86 86

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

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

	
98 98

	
99
#if defined __GNUC__ && !defined __STRICT_ANSI__
99
#if defined HAVE_LONG_LONG
100 100

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

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

	
112 112
#endif
113 113

	
114 114

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

	
121 121

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

	
128 128

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

	
135 135

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

	
142 142
// #else
143 143

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

	
149 149
// #endif
150 150

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

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

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

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

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

	
176 176
  };
177 177

	
178 178
}
179 179

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

	
19 19
///\file
20 20
///\brief Some basic non-inline functions and static global data.
21 21

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

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

	
39 47
#include <cmath>
40 48
#include <sstream>
41 49

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

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

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

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

	
84 92
    std::string getWinFormattedDate()
85 93
    {
86 94
      std::ostringstream os;
87 95
#ifdef WIN32
88 96
      SYSTEMTIME time;
89 97
      GetSystemTime(&time);
90
#if defined(_MSC_VER) && (_MSC_VER < 1500)
91
      LPWSTR buf1, buf2, buf3;
92
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
93
                        L"ddd MMM dd", buf1, 11) &&
94
          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
95
                        L"HH':'mm':'ss", buf2, 9) &&
96
          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
97
                        L"yyyy", buf3, 5)) {
98
      char buf1[11], buf2[9], buf3[5];
99
	  if (GetDateFormat(MY_LOCALE, 0, &time,
100
                        ("ddd MMM dd"), buf1, 11) &&
101
          GetTimeFormat(MY_LOCALE, 0, &time,
102
                        ("HH':'mm':'ss"), buf2, 9) &&
103
          GetDateFormat(MY_LOCALE, 0, &time,
104
                        ("yyyy"), buf3, 5)) {
98 105
        os << buf1 << ' ' << buf2 << ' ' << buf3;
99 106
      }
100
#else
101
      char buf1[11], buf2[9], buf3[5];
102
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
103
                        "ddd MMM dd", buf1, 11) &&
104
          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
105
                        "HH':'mm':'ss", buf2, 9) &&
106
          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
107
                        "yyyy", buf3, 5)) {
108
        os << buf1 << ' ' << buf2 << ' ' << buf3;
109
      }
110
#endif
111 107
      else os << "unknown";
112 108
#else
113 109
      timeval tv;
114 110
      gettimeofday(&tv, 0);
115 111

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

	
123 119
    int getWinRndSeed()
124 120
    {
125 121
#ifdef WIN32
126 122
      FILETIME time;
127 123
      GetSystemTimeAsFileTime(&time);
128 124
      return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
129 125
#else
130 126
      timeval tv;
131 127
      gettimeofday(&tv, 0);
132 128
      return getpid() + tv.tv_sec + tv.tv_usec;
133 129
#endif
134 130
    }
135 131
  }
136 132
}
Ignore white space 6 line context
1 1
/* Define to 1 if you have CPLEX. */
2 2
#undef HAVE_CPLEX
3 3

	
4 4
/* Define to 1 if you have GLPK. */
5 5
#undef HAVE_GLPK
6

	
7
/* Define to 1 if you have long long */
8
#undef HAVE_LONG_LONG
Ignore white space 6 line context
... ...
@@ -137,712 +137,689 @@
137 137

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
332 332
      Functor _functor;
333 333

	
334 334
    public:
335 335

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

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

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

	
364 364
      Functor _functor;
365 365

	
366 366
    public:
367 367

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

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

	
388 388
  }
389 389

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

	
393
  /// \brief Return a \ref DigraphReader class
394
  ///
395
  /// This function just returns a \ref DigraphReader class.
396
  /// \relates DigraphReader
397 393
  template <typename Digraph>
398
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
399
                                       std::istream& is = std::cin) {
400
    DigraphReader<Digraph> tmp(digraph, is);
401
    return tmp;
402
  }
403

	
404
  /// \brief Return a \ref DigraphReader class
405
  ///
406
  /// This function just returns a \ref DigraphReader class.
407
  /// \relates DigraphReader
394
  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
395
                                       std::istream& is = std::cin);
408 396
  template <typename Digraph>
409
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
410
                                       const std::string& fn) {
411
    DigraphReader<Digraph> tmp(digraph, fn);
412
    return tmp;
413
  }
414

	
415
  /// \brief Return a \ref DigraphReader class
416
  ///
417
  /// This function just returns a \ref DigraphReader class.
418
  /// \relates DigraphReader
397
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
419 398
  template <typename Digraph>
420
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
421
    DigraphReader<Digraph> tmp(digraph, fn);
422
    return tmp;
423
  }
399
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
424 400

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

	
479 455
    typedef _Digraph Digraph;
480 456
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
481 457

	
482 458
  private:
483 459

	
484 460

	
485 461
    std::istream* _is;
486 462
    bool local_is;
487 463
    std::string _filename;
488 464

	
489 465
    Digraph& _digraph;
490 466

	
491 467
    std::string _nodes_caption;
492 468
    std::string _arcs_caption;
493 469
    std::string _attributes_caption;
494 470

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

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

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

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

	
512 488
    bool _use_nodes;
513 489
    bool _use_arcs;
514 490

	
515 491
    bool _skip_nodes;
516 492
    bool _skip_arcs;
517 493

	
518 494
    int line_num;
519 495
    std::istringstream line;
520 496

	
521 497
  public:
522 498

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

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

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

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

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

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

	
579 555
      if (local_is) {
580 556
        delete _is;
581 557
      }
582 558

	
583 559
    }
584 560

	
585 561
  private:
586 562

	
587
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
588
                                                  std::istream& is);
589
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
590
                                                  const std::string& fn);
591
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
592
                                                  const char *fn);
563
    template <typename DGR>
564
    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
565
    template <typename DGR>
566
    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
567
                                            const std::string& fn);
568
    template <typename DGR>
569
    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
593 570

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

	
599 576
      other._is = 0;
600 577
      other.local_is = false;
601 578

	
602 579
      _node_index.swap(other._node_index);
603 580
      _arc_index.swap(other._arc_index);
604 581

	
605 582
      _node_maps.swap(other._node_maps);
606 583
      _arc_maps.swap(other._arc_maps);
607 584
      _attributes.swap(other._attributes);
608 585

	
609 586
      _nodes_caption = other._nodes_caption;
610 587
      _arcs_caption = other._arcs_caption;
611 588
      _attributes_caption = other._attributes_caption;
612 589

	
613 590
    }
614 591

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

	
617 594
  public:
618 595

	
619 596
    /// \name Reading rules
620 597
    /// @{
621 598

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

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

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

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

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

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

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

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

	
722 699
    /// @}
723 700

	
724 701
    /// \name Select section by name
725 702
    /// @{
726 703

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

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

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

	
751 728
    /// @}
752 729

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

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

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

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

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

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

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

	
847 824
    /// @}
848 825

	
... ...
@@ -959,674 +936,685 @@
959 936
        }
960 937

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

	
965 942
      }
966 943
      if (readSuccess()) {
967 944
        line.putback(c);
968 945
      }
969 946
    }
970 947

	
971 948
    void readArcs() {
972 949

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

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

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

	
988 965
        std::string map;
989 966
        int index = 0;
990 967
        while (_reader_bits::readToken(line, map)) {
991 968
          if (maps.find(map) != maps.end()) {
992 969
            std::ostringstream msg;
993 970
            msg << "Multiple occurence of arc map: " << map;
994 971
            throw FormatError(msg.str());
995 972
          }
996 973
          maps.insert(std::make_pair(map, index));
997 974
          ++index;
998 975
        }
999 976

	
1000 977
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1001 978
          std::map<std::string, int>::iterator jt =
1002 979
            maps.find(_arc_maps[i].first);
1003 980
          if (jt == maps.end()) {
1004 981
            std::ostringstream msg;
1005 982
            msg << "Map not found: " << _arc_maps[i].first;
1006 983
            throw FormatError(msg.str());
1007 984
          }
1008 985
          map_index[i] = jt->second;
1009 986
        }
1010 987

	
1011 988
        {
1012 989
          std::map<std::string, int>::iterator jt = maps.find("label");
1013 990
          if (jt != maps.end()) {
1014 991
            label_index = jt->second;
1015 992
          } else {
1016 993
            label_index = -1;
1017 994
          }
1018 995
        }
1019 996
        map_num = maps.size();
1020 997
      }
1021 998

	
1022 999
      while (readLine() && line >> c && c != '@') {
1023 1000
        line.putback(c);
1024 1001

	
1025 1002
        std::string source_token;
1026 1003
        std::string target_token;
1027 1004

	
1028 1005
        if (!_reader_bits::readToken(line, source_token))
1029 1006
          throw FormatError("Source not found");
1030 1007

	
1031 1008
        if (!_reader_bits::readToken(line, target_token))
1032 1009
          throw FormatError("Target not found");
1033 1010

	
1034 1011
        std::vector<std::string> tokens(map_num);
1035 1012
        for (int i = 0; i < map_num; ++i) {
1036 1013
          if (!_reader_bits::readToken(line, tokens[i])) {
1037 1014
            std::ostringstream msg;
1038 1015
            msg << "Column not found (" << i + 1 << ")";
1039 1016
            throw FormatError(msg.str());
1040 1017
          }
1041 1018
        }
1042 1019
        if (line >> std::ws >> c)
1043 1020
          throw FormatError("Extra character at the end of line");
1044 1021

	
1045 1022
        Arc a;
1046 1023
        if (!_use_arcs) {
1047 1024

	
1048 1025
          typename NodeIndex::iterator it;
1049 1026

	
1050 1027
          it = _node_index.find(source_token);
1051 1028
          if (it == _node_index.end()) {
1052 1029
            std::ostringstream msg;
1053 1030
            msg << "Item not found: " << source_token;
1054 1031
            throw FormatError(msg.str());
1055 1032
          }
1056 1033
          Node source = it->second;
1057 1034

	
1058 1035
          it = _node_index.find(target_token);
1059 1036
          if (it == _node_index.end()) {
1060 1037
            std::ostringstream msg;
1061 1038
            msg << "Item not found: " << target_token;
1062 1039
            throw FormatError(msg.str());
1063 1040
          }
1064 1041
          Node target = it->second;
1065 1042

	
1066 1043
          a = _digraph.addArc(source, target);
1067 1044
          if (label_index != -1)
1068 1045
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1069 1046
        } else {
1070 1047
          if (label_index == -1)
1071 1048
            throw FormatError("Label map not found");
1072 1049
          typename std::map<std::string, Arc>::iterator it =
1073 1050
            _arc_index.find(tokens[label_index]);
1074 1051
          if (it == _arc_index.end()) {
1075 1052
            std::ostringstream msg;
1076 1053
            msg << "Arc with label not found: " << tokens[label_index];
1077 1054
            throw FormatError(msg.str());
1078 1055
          }
1079 1056
          a = it->second;
1080 1057
        }
1081 1058

	
1082 1059
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1083 1060
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1084 1061
        }
1085 1062

	
1086 1063
      }
1087 1064
      if (readSuccess()) {
1088 1065
        line.putback(c);
1089 1066
      }
1090 1067
    }
1091 1068

	
1092 1069
    void readAttributes() {
1093 1070

	
1094 1071
      std::set<std::string> read_attr;
1095 1072

	
1096 1073
      char c;
1097 1074
      while (readLine() && line >> c && c != '@') {
1098 1075
        line.putback(c);
1099 1076

	
1100 1077
        std::string attr, token;
1101 1078
        if (!_reader_bits::readToken(line, attr))
1102 1079
          throw FormatError("Attribute name not found");
1103 1080
        if (!_reader_bits::readToken(line, token))
1104 1081
          throw FormatError("Attribute value not found");
1105 1082
        if (line >> c)
1106 1083
          throw FormatError("Extra character at the end of line");
1107 1084

	
1108 1085
        {
1109 1086
          std::set<std::string>::iterator it = read_attr.find(attr);
1110 1087
          if (it != read_attr.end()) {
1111 1088
            std::ostringstream msg;
1112 1089
            msg << "Multiple occurence of attribute: " << attr;
1113 1090
            throw FormatError(msg.str());
1114 1091
          }
1115 1092
          read_attr.insert(attr);
1116 1093
        }
1117 1094

	
1118 1095
        {
1119 1096
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1120 1097
          while (it != _attributes.end() && it->first == attr) {
1121 1098
            it->second->set(token);
1122 1099
            ++it;
1123 1100
          }
1124 1101
        }
1125 1102

	
1126 1103
      }
1127 1104
      if (readSuccess()) {
1128 1105
        line.putback(c);
1129 1106
      }
1130 1107
      for (typename Attributes::iterator it = _attributes.begin();
1131 1108
           it != _attributes.end(); ++it) {
1132 1109
        if (read_attr.find(it->first) == read_attr.end()) {
1133 1110
          std::ostringstream msg;
1134 1111
          msg << "Attribute not found: " << it->first;
1135 1112
          throw FormatError(msg.str());
1136 1113
        }
1137 1114
      }
1138 1115
    }
1139 1116

	
1140 1117
  public:
1141 1118

	
1142 1119
    /// \name Execution of the reader
1143 1120
    /// @{
1144 1121

	
1145 1122
    /// \brief Start the batch processing
1146 1123
    ///
1147 1124
    /// This function starts the batch processing
1148 1125
    void run() {
1149 1126
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1150 1127

	
1151 1128
      bool nodes_done = _skip_nodes;
1152 1129
      bool arcs_done = _skip_arcs;
1153 1130
      bool attributes_done = false;
1154 1131

	
1155 1132
      line_num = 0;
1156 1133
      readLine();
1157 1134
      skipSection();
1158 1135

	
1159 1136
      while (readSuccess()) {
1160 1137
        try {
1161 1138
          char c;
1162 1139
          std::string section, caption;
1163 1140
          line >> c;
1164 1141
          _reader_bits::readToken(line, section);
1165 1142
          _reader_bits::readToken(line, caption);
1166 1143

	
1167 1144
          if (line >> c)
1168 1145
            throw FormatError("Extra character at the end of line");
1169 1146

	
1170 1147
          if (section == "nodes" && !nodes_done) {
1171 1148
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1172 1149
              readNodes();
1173 1150
              nodes_done = true;
1174 1151
            }
1175 1152
          } else if ((section == "arcs" || section == "edges") &&
1176 1153
                     !arcs_done) {
1177 1154
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1178 1155
              readArcs();
1179 1156
              arcs_done = true;
1180 1157
            }
1181 1158
          } else if (section == "attributes" && !attributes_done) {
1182 1159
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1183 1160
              readAttributes();
1184 1161
              attributes_done = true;
1185 1162
            }
1186 1163
          } else {
1187 1164
            readLine();
1188 1165
            skipSection();
1189 1166
          }
1190 1167
        } catch (FormatError& error) {
1191 1168
          error.line(line_num);
1192 1169
          error.file(_filename);
1193 1170
          throw;
1194 1171
        }
1195 1172
      }
1196 1173

	
1197 1174
      if (!nodes_done) {
1198 1175
        throw FormatError("Section @nodes not found");
1199 1176
      }
1200 1177

	
1201 1178
      if (!arcs_done) {
1202 1179
        throw FormatError("Section @arcs not found");
1203 1180
      }
1204 1181

	
1205 1182
      if (!attributes_done && !_attributes.empty()) {
1206 1183
        throw FormatError("Section @attributes not found");
1207 1184
      }
1208 1185

	
1209 1186
    }
1210 1187

	
1211 1188
    /// @}
1212 1189

	
1213 1190
  };
1214 1191

	
1192
  /// \brief Return a \ref DigraphReader class
1193
  ///
1194
  /// This function just returns a \ref DigraphReader class.
1195
  /// \relates DigraphReader
1196
  template <typename Digraph>
1197
  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
1198
    DigraphReader<Digraph> tmp(digraph, is);
1199
    return tmp;
1200
  }
1201

	
1202
  /// \brief Return a \ref DigraphReader class
1203
  ///
1204
  /// This function just returns a \ref DigraphReader class.
1205
  /// \relates DigraphReader
1206
  template <typename Digraph>
1207
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
1208
                                       const std::string& fn) {
1209
    DigraphReader<Digraph> tmp(digraph, fn);
1210
    return tmp;
1211
  }
1212

	
1213
  /// \brief Return a \ref DigraphReader class
1214
  ///
1215
  /// This function just returns a \ref DigraphReader class.
1216
  /// \relates DigraphReader
1217
  template <typename Digraph>
1218
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
1219
    DigraphReader<Digraph> tmp(digraph, fn);
1220
    return tmp;
1221
  }
1222

	
1215 1223
  template <typename Graph>
1216 1224
  class GraphReader;
1217

	
1218
  /// \brief Return a \ref GraphReader class
1219
  ///
1220
  /// This function just returns a \ref GraphReader class.
1221
  /// \relates GraphReader
1225
 
1222 1226
  template <typename Graph>
1223
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
1224
    GraphReader<Graph> tmp(graph, is);
1225
    return tmp;
1226
  }
1227

	
1228
  /// \brief Return a \ref GraphReader class
1229
  ///
1230
  /// This function just returns a \ref GraphReader class.
1231
  /// \relates GraphReader
1227
  GraphReader<Graph> graphReader(Graph& graph, 
1228
                                 std::istream& is = std::cin);
1232 1229
  template <typename Graph>
1233
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
1234
    GraphReader<Graph> tmp(graph, fn);
1235
    return tmp;
1236
  }
1237

	
1238
  /// \brief Return a \ref GraphReader class
1239
  ///
1240
  /// This function just returns a \ref GraphReader class.
1241
  /// \relates GraphReader
1230
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1242 1231
  template <typename Graph>
1243
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
1244
    GraphReader<Graph> tmp(graph, fn);
1245
    return tmp;
1246
  }
1232
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1247 1233

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

	
1267 1253
    typedef _Graph Graph;
1268 1254
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1269 1255

	
1270 1256
  private:
1271 1257

	
1272 1258
    std::istream* _is;
1273 1259
    bool local_is;
1274 1260
    std::string _filename;
1275 1261

	
1276 1262
    Graph& _graph;
1277 1263

	
1278 1264
    std::string _nodes_caption;
1279 1265
    std::string _edges_caption;
1280 1266
    std::string _attributes_caption;
1281 1267

	
1282 1268
    typedef std::map<std::string, Node> NodeIndex;
1283 1269
    NodeIndex _node_index;
1284 1270
    typedef std::map<std::string, Edge> EdgeIndex;
1285 1271
    EdgeIndex _edge_index;
1286 1272

	
1287 1273
    typedef std::vector<std::pair<std::string,
1288 1274
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1289 1275
    NodeMaps _node_maps;
1290 1276

	
1291 1277
    typedef std::vector<std::pair<std::string,
1292 1278
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1293 1279
    EdgeMaps _edge_maps;
1294 1280

	
1295 1281
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1296 1282
      Attributes;
1297 1283
    Attributes _attributes;
1298 1284

	
1299 1285
    bool _use_nodes;
1300 1286
    bool _use_edges;
1301 1287

	
1302 1288
    bool _skip_nodes;
1303 1289
    bool _skip_edges;
1304 1290

	
1305 1291
    int line_num;
1306 1292
    std::istringstream line;
1307 1293

	
1308 1294
  public:
1309 1295

	
1310 1296
    /// \brief Constructor
1311 1297
    ///
1312 1298
    /// Construct an undirected graph reader, which reads from the given
1313 1299
    /// input stream.
1314 1300
    GraphReader(Graph& graph, std::istream& is = std::cin)
1315 1301
      : _is(&is), local_is(false), _graph(graph),
1316 1302
        _use_nodes(false), _use_edges(false),
1317 1303
        _skip_nodes(false), _skip_edges(false) {}
1318 1304

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

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

	
1349 1335
    /// \brief Destructor
1350 1336
    ~GraphReader() {
1351 1337
      for (typename NodeMaps::iterator it = _node_maps.begin();
1352 1338
           it != _node_maps.end(); ++it) {
1353 1339
        delete it->second;
1354 1340
      }
1355 1341

	
1356 1342
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1357 1343
           it != _edge_maps.end(); ++it) {
1358 1344
        delete it->second;
1359 1345
      }
1360 1346

	
1361 1347
      for (typename Attributes::iterator it = _attributes.begin();
1362 1348
           it != _attributes.end(); ++it) {
1363 1349
        delete it->second;
1364 1350
      }
1365 1351

	
1366 1352
      if (local_is) {
1367 1353
        delete _is;
1368 1354
      }
1369 1355

	
1370 1356
    }
1371 1357

	
1372 1358
  private:
1373
    friend GraphReader<Graph> graphReader<>(Graph& graph, std::istream& is);
1374
    friend GraphReader<Graph> graphReader<>(Graph& graph,
1375
                                            const std::string& fn);
1376
    friend GraphReader<Graph> graphReader<>(Graph& graph, const char *fn);
1359
    template <typename GR>
1360
    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
1361
    template <typename GR>
1362
    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
1363
    template <typename GR>
1364
    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
1377 1365

	
1378 1366
    GraphReader(GraphReader& other)
1379 1367
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1380 1368
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1381 1369
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1382 1370

	
1383 1371
      other._is = 0;
1384 1372
      other.local_is = false;
1385 1373

	
1386 1374
      _node_index.swap(other._node_index);
1387 1375
      _edge_index.swap(other._edge_index);
1388 1376

	
1389 1377
      _node_maps.swap(other._node_maps);
1390 1378
      _edge_maps.swap(other._edge_maps);
1391 1379
      _attributes.swap(other._attributes);
1392 1380

	
1393 1381
      _nodes_caption = other._nodes_caption;
1394 1382
      _edges_caption = other._edges_caption;
1395 1383
      _attributes_caption = other._attributes_caption;
1396 1384

	
1397 1385
    }
1398 1386

	
1399 1387
    GraphReader& operator=(const GraphReader&);
1400 1388

	
1401 1389
  public:
1402 1390

	
1403 1391
    /// \name Reading rules
1404 1392
    /// @{
1405 1393

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

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

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

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

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

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

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

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

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

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

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

	
1552 1540
    /// @}
1553 1541

	
1554 1542
    /// \name Select section by name
1555 1543
    /// @{
1556 1544

	
1557 1545
    /// \brief Set \c \@nodes section to be read
1558 1546
    ///
1559 1547
    /// Set \c \@nodes section to be read.
1560 1548
    GraphReader& nodes(const std::string& caption) {
1561 1549
      _nodes_caption = caption;
1562 1550
      return *this;
1563 1551
    }
1564 1552

	
1565 1553
    /// \brief Set \c \@edges section to be read
1566 1554
    ///
1567 1555
    /// Set \c \@edges section to be read.
1568 1556
    GraphReader& edges(const std::string& caption) {
1569 1557
      _edges_caption = caption;
1570 1558
      return *this;
1571 1559
    }
1572 1560

	
1573 1561
    /// \brief Set \c \@attributes section to be read
1574 1562
    ///
1575 1563
    /// Set \c \@attributes section to be read.
1576 1564
    GraphReader& attributes(const std::string& caption) {
1577 1565
      _attributes_caption = caption;
1578 1566
      return *this;
1579 1567
    }
1580 1568

	
1581 1569
    /// @}
1582 1570

	
1583 1571
    /// \name Using previously constructed node or edge set
1584 1572
    /// @{
1585 1573

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

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

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

	
1792 1780
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1793 1781
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1794 1782
        }
1795 1783

	
1796 1784
      }
1797 1785
      if (readSuccess()) {
1798 1786
        line.putback(c);
1799 1787
      }
1800 1788
    }
1801 1789

	
1802 1790
    void readEdges() {
1803 1791

	
1804 1792
      std::vector<int> map_index(_edge_maps.size());
1805 1793
      int map_num, label_index;
1806 1794

	
1807 1795
      char c;
1808 1796
      if (!readLine() || !(line >> c) || c == '@') {
1809 1797
        if (readSuccess() && line) line.putback(c);
1810 1798
        if (!_edge_maps.empty())
1811 1799
          throw FormatError("Cannot find map names");
1812 1800
        return;
1813 1801
      }
1814 1802
      line.putback(c);
1815 1803

	
1816 1804
      {
1817 1805
        std::map<std::string, int> maps;
1818 1806

	
1819 1807
        std::string map;
1820 1808
        int index = 0;
1821 1809
        while (_reader_bits::readToken(line, map)) {
1822 1810
          if (maps.find(map) != maps.end()) {
1823 1811
            std::ostringstream msg;
1824 1812
            msg << "Multiple occurence of edge map: " << map;
1825 1813
            throw FormatError(msg.str());
1826 1814
          }
1827 1815
          maps.insert(std::make_pair(map, index));
1828 1816
          ++index;
1829 1817
        }
1830 1818

	
1831 1819
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1832 1820
          std::map<std::string, int>::iterator jt =
1833 1821
            maps.find(_edge_maps[i].first);
1834 1822
          if (jt == maps.end()) {
1835 1823
            std::ostringstream msg;
1836 1824
            msg << "Map not found: " << _edge_maps[i].first;
1837 1825
            throw FormatError(msg.str());
1838 1826
          }
1839 1827
          map_index[i] = jt->second;
1840 1828
        }
1841 1829

	
1842 1830
        {
1843 1831
          std::map<std::string, int>::iterator jt = maps.find("label");
1844 1832
          if (jt != maps.end()) {
1845 1833
            label_index = jt->second;
1846 1834
          } else {
1847 1835
            label_index = -1;
1848 1836
          }
1849 1837
        }
1850 1838
        map_num = maps.size();
1851 1839
      }
1852 1840

	
1853 1841
      while (readLine() && line >> c && c != '@') {
1854 1842
        line.putback(c);
1855 1843

	
1856 1844
        std::string source_token;
1857 1845
        std::string target_token;
1858 1846

	
1859 1847
        if (!_reader_bits::readToken(line, source_token))
1860 1848
          throw FormatError("Node u not found");
1861 1849

	
1862 1850
        if (!_reader_bits::readToken(line, target_token))
1863 1851
          throw FormatError("Node v not found");
1864 1852

	
1865 1853
        std::vector<std::string> tokens(map_num);
1866 1854
        for (int i = 0; i < map_num; ++i) {
1867 1855
          if (!_reader_bits::readToken(line, tokens[i])) {
1868 1856
            std::ostringstream msg;
1869 1857
            msg << "Column not found (" << i + 1 << ")";
1870 1858
            throw FormatError(msg.str());
1871 1859
          }
1872 1860
        }
1873 1861
        if (line >> std::ws >> c)
1874 1862
          throw FormatError("Extra character at the end of line");
1875 1863

	
1876 1864
        Edge e;
1877 1865
        if (!_use_edges) {
1878 1866

	
1879 1867
          typename NodeIndex::iterator it;
1880 1868

	
1881 1869
          it = _node_index.find(source_token);
1882 1870
          if (it == _node_index.end()) {
1883 1871
            std::ostringstream msg;
1884 1872
            msg << "Item not found: " << source_token;
1885 1873
            throw FormatError(msg.str());
1886 1874
          }
1887 1875
          Node source = it->second;
1888 1876

	
1889 1877
          it = _node_index.find(target_token);
1890 1878
          if (it == _node_index.end()) {
1891 1879
            std::ostringstream msg;
1892 1880
            msg << "Item not found: " << target_token;
1893 1881
            throw FormatError(msg.str());
1894 1882
          }
1895 1883
          Node target = it->second;
1896 1884

	
1897 1885
          e = _graph.addEdge(source, target);
1898 1886
          if (label_index != -1)
1899 1887
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1900 1888
        } else {
1901 1889
          if (label_index == -1)
1902 1890
            throw FormatError("Label map not found");
1903 1891
          typename std::map<std::string, Edge>::iterator it =
1904 1892
            _edge_index.find(tokens[label_index]);
1905 1893
          if (it == _edge_index.end()) {
1906 1894
            std::ostringstream msg;
1907 1895
            msg << "Edge with label not found: " << tokens[label_index];
1908 1896
            throw FormatError(msg.str());
1909 1897
          }
1910 1898
          e = it->second;
1911 1899
        }
1912 1900

	
1913 1901
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1914 1902
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1915 1903
        }
1916 1904

	
1917 1905
      }
1918 1906
      if (readSuccess()) {
1919 1907
        line.putback(c);
1920 1908
      }
1921 1909
    }
1922 1910

	
1923 1911
    void readAttributes() {
1924 1912

	
1925 1913
      std::set<std::string> read_attr;
1926 1914

	
1927 1915
      char c;
1928 1916
      while (readLine() && line >> c && c != '@') {
1929 1917
        line.putback(c);
1930 1918

	
1931 1919
        std::string attr, token;
1932 1920
        if (!_reader_bits::readToken(line, attr))
1933 1921
          throw FormatError("Attribute name not found");
1934 1922
        if (!_reader_bits::readToken(line, token))
1935 1923
          throw FormatError("Attribute value not found");
1936 1924
        if (line >> c)
1937 1925
          throw FormatError("Extra character at the end of line");
1938 1926

	
1939 1927
        {
1940 1928
          std::set<std::string>::iterator it = read_attr.find(attr);
1941 1929
          if (it != read_attr.end()) {
1942 1930
            std::ostringstream msg;
1943 1931
            msg << "Multiple occurence of attribute: " << attr;
1944 1932
            throw FormatError(msg.str());
1945 1933
          }
1946 1934
          read_attr.insert(attr);
1947 1935
        }
1948 1936

	
1949 1937
        {
1950 1938
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1951 1939
          while (it != _attributes.end() && it->first == attr) {
1952 1940
            it->second->set(token);
1953 1941
            ++it;
1954 1942
          }
1955 1943
        }
1956 1944

	
1957 1945
      }
1958 1946
      if (readSuccess()) {
1959 1947
        line.putback(c);
1960 1948
      }
1961 1949
      for (typename Attributes::iterator it = _attributes.begin();
1962 1950
           it != _attributes.end(); ++it) {
1963 1951
        if (read_attr.find(it->first) == read_attr.end()) {
1964 1952
          std::ostringstream msg;
1965 1953
          msg << "Attribute not found: " << it->first;
1966 1954
          throw FormatError(msg.str());
1967 1955
        }
1968 1956
      }
1969 1957
    }
1970 1958

	
1971 1959
  public:
1972 1960

	
1973 1961
    /// \name Execution of the reader
1974 1962
    /// @{
1975 1963

	
1976 1964
    /// \brief Start the batch processing
1977 1965
    ///
1978 1966
    /// This function starts the batch processing
1979 1967
    void run() {
1980 1968

	
1981 1969
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1982 1970

	
1983 1971
      bool nodes_done = _skip_nodes;
1984 1972
      bool edges_done = _skip_edges;
1985 1973
      bool attributes_done = false;
1986 1974

	
1987 1975
      line_num = 0;
1988 1976
      readLine();
1989 1977
      skipSection();
1990 1978

	
1991 1979
      while (readSuccess()) {
1992 1980
        try {
1993 1981
          char c;
1994 1982
          std::string section, caption;
1995 1983
          line >> c;
1996 1984
          _reader_bits::readToken(line, section);
1997 1985
          _reader_bits::readToken(line, caption);
1998 1986

	
1999 1987
          if (line >> c)
2000 1988
            throw FormatError("Extra character at the end of line");
2001 1989

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

	
2029 2017
      if (!nodes_done) {
2030 2018
        throw FormatError("Section @nodes not found");
2031 2019
      }
2032 2020

	
2033 2021
      if (!edges_done) {
2034 2022
        throw FormatError("Section @edges not found");
2035 2023
      }
2036 2024

	
2037 2025
      if (!attributes_done && !_attributes.empty()) {
2038 2026
        throw FormatError("Section @attributes not found");
2039 2027
      }
2040 2028

	
2041 2029
    }
2042 2030

	
2043 2031
    /// @}
2044 2032

	
2045 2033
  };
2046 2034

	
2035
  /// \brief Return a \ref GraphReader class
2036
  ///
2037
  /// This function just returns a \ref GraphReader class.
2038
  /// \relates GraphReader
2039
  template <typename Graph>
2040
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
2041
    GraphReader<Graph> tmp(graph, is);
2042
    return tmp;
2043
  }
2044

	
2045
  /// \brief Return a \ref GraphReader class
2046
  ///
2047
  /// This function just returns a \ref GraphReader class.
2048
  /// \relates GraphReader
2049
  template <typename Graph>
2050
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
2051
    GraphReader<Graph> tmp(graph, fn);
2052
    return tmp;
2053
  }
2054

	
2055
  /// \brief Return a \ref GraphReader class
2056
  ///
2057
  /// This function just returns a \ref GraphReader class.
2058
  /// \relates GraphReader
2059
  template <typename Graph>
2060
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2061
    GraphReader<Graph> tmp(graph, fn);
2062
    return tmp;
2063
  }
2064

	
2047 2065
  class SectionReader;
2048 2066

	
2049 2067
  SectionReader sectionReader(std::istream& is);
2050 2068
  SectionReader sectionReader(const std::string& fn);
2051 2069
  SectionReader sectionReader(const char* fn);
2052 2070

	
2053 2071
  /// \ingroup lemon_io
2054 2072
  ///
2055 2073
  /// \brief Section reader class
2056 2074
  ///
2057 2075
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2058 2076
  /// which contain any data in arbitrary format. Such sections can be
2059 2077
  /// read with this class. A reading rule can be added to the class
2060 2078
  /// with two different functions. With the \c sectionLines() function a
2061 2079
  /// functor can process the section line-by-line, while with the \c
2062 2080
  /// sectionStream() member the section can be read from an input
2063 2081
  /// stream.
2064 2082
  class SectionReader {
2065 2083
  private:
2066 2084

	
2067 2085
    std::istream* _is;
2068 2086
    bool local_is;
2069 2087
    std::string _filename;
2070 2088

	
2071 2089
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2072 2090
    Sections _sections;
2073 2091

	
2074 2092
    int line_num;
2075 2093
    std::istringstream line;
2076 2094

	
2077 2095
  public:
2078 2096

	
2079 2097
    /// \brief Constructor
2080 2098
    ///
2081 2099
    /// Construct a section reader, which reads from the given input
2082 2100
    /// stream.
2083 2101
    SectionReader(std::istream& is)
2084 2102
      : _is(&is), local_is(false) {}
2085 2103

	
2086 2104
    /// \brief Constructor
2087 2105
    ///
2088 2106
    /// Construct a section reader, which reads from the given file.
2089 2107
    SectionReader(const std::string& fn)
2090 2108
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2091 2109
        _filename(fn) {
2092 2110
      if (!(*_is)) {
2093 2111
        delete _is;
2094 2112
        throw IoError("Cannot open file", fn);
2095 2113
      }
2096 2114
    }
2097 2115

	
2098 2116
    /// \brief Constructor
2099 2117
    ///
2100 2118
    /// Construct a section reader, which reads from the given file.
2101 2119
    SectionReader(const char* fn)
2102 2120
      : _is(new std::ifstream(fn)), local_is(true),
2103 2121
        _filename(fn) {
2104 2122
      if (!(*_is)) {
2105 2123
        delete _is;
2106 2124
        throw IoError("Cannot open file", fn);
2107 2125
      }
2108 2126
    }
2109 2127

	
2110 2128
    /// \brief Destructor
2111 2129
    ~SectionReader() {
2112 2130
      for (Sections::iterator it = _sections.begin();
2113 2131
           it != _sections.end(); ++it) {
2114 2132
        delete it->second;
2115 2133
      }
2116 2134

	
2117 2135
      if (local_is) {
2118 2136
        delete _is;
2119 2137
      }
2120 2138

	
2121 2139
    }
2122 2140

	
2123 2141
  private:
2124 2142

	
2125 2143
    friend SectionReader sectionReader(std::istream& is);
2126 2144
    friend SectionReader sectionReader(const std::string& fn);
2127 2145
    friend SectionReader sectionReader(const char* fn);
2128 2146

	
2129 2147
    SectionReader(SectionReader& other)
2130 2148
      : _is(other._is), local_is(other.local_is) {
2131 2149

	
2132 2150
      other._is = 0;
2133 2151
      other.local_is = false;
2134 2152

	
2135 2153
      _sections.swap(other._sections);
2136 2154
    }
2137 2155

	
2138 2156
    SectionReader& operator=(const SectionReader&);
2139 2157

	
2140 2158
  public:
2141 2159

	
2142 2160
    /// \name Section readers
2143 2161
    /// @{
2144 2162

	
2145 2163
    /// \brief Add a section processor with line oriented reading
2146 2164
    ///
2147 2165
    /// The first parameter is the type descriptor of the section, the
2148 2166
    /// second is a functor, which takes just one \c std::string
2149 2167
    /// parameter. At the reading process, each line of the section
2150 2168
    /// will be given to the functor object. However, the empty lines
2151 2169
    /// and the comment lines are filtered out, and the leading
2152 2170
    /// whitespaces are trimmed from each processed string.
2153 2171
    ///
2154 2172
    /// For example let's see a section, which contain several
2155 2173
    /// integers, which should be inserted into a vector.
2156 2174
    ///\code
2157 2175
    ///  @numbers
2158 2176
    ///  12 45 23
2159 2177
    ///  4
2160 2178
    ///  23 6
2161 2179
    ///\endcode
2162 2180
    ///
2163 2181
    /// The functor is implemented as a struct:
2164 2182
    ///\code
2165 2183
    ///  struct NumberSection {
2166 2184
    ///    std::vector<int>& _data;
2167 2185
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2168 2186
    ///    void operator()(const std::string& line) {
2169 2187
    ///      std::istringstream ls(line);
2170 2188
    ///      int value;
2171 2189
    ///      while (ls >> value) _data.push_back(value);
2172 2190
    ///    }
2173 2191
    ///  };
2174 2192
    ///
2175 2193
    ///  // ...
2176 2194
    ///
2177 2195
    ///  reader.sectionLines("numbers", NumberSection(vec));
2178 2196
    ///\endcode
2179 2197
    template <typename Functor>
2180 2198
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2181 2199
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2182 2200
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2183 2201
                   "Multiple reading of section.");
2184 2202
      _sections.insert(std::make_pair(type,
2185 2203
        new _reader_bits::LineSection<Functor>(functor)));
2186 2204
      return *this;
2187 2205
    }
2188 2206

	
2189 2207

	
2190 2208
    /// \brief Add a section processor with stream oriented reading
2191 2209
    ///
2192 2210
    /// The first parameter is the type of the section, the second is
2193 2211
    /// a functor, which takes an \c std::istream& and an \c int&
2194 2212
    /// parameter, the latter regard to the line number of stream. The
2195 2213
    /// functor can read the input while the section go on, and the
2196 2214
    /// line number should be modified accordingly.
2197 2215
    template <typename Functor>
2198 2216
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2199 2217
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2200 2218
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2201 2219
                   "Multiple reading of section.");
2202 2220
      _sections.insert(std::make_pair(type,
2203 2221
         new _reader_bits::StreamSection<Functor>(functor)));
2204 2222
      return *this;
2205 2223
    }
2206 2224

	
2207 2225
    /// @}
2208 2226

	
2209 2227
  private:
2210 2228

	
2211 2229
    bool readLine() {
2212 2230
      std::string str;
2213 2231
      while(++line_num, std::getline(*_is, str)) {
2214 2232
        line.clear(); line.str(str);
2215 2233
        char c;
2216 2234
        if (line >> std::ws >> c && c != '#') {
2217 2235
          line.putback(c);
2218 2236
          return true;
2219 2237
        }
2220 2238
      }
2221 2239
      return false;
2222 2240
    }
2223 2241

	
2224 2242
    bool readSuccess() {
2225 2243
      return static_cast<bool>(*_is);
2226 2244
    }
2227 2245

	
2228 2246
    void skipSection() {
2229 2247
      char c;
2230 2248
      while (readSuccess() && line >> c && c != '@') {
2231 2249
        readLine();
2232 2250
      }
2233 2251
      if (readSuccess()) {
2234 2252
        line.putback(c);
2235 2253
      }
2236 2254
    }
2237 2255

	
2238 2256
  public:
2239 2257

	
2240 2258

	
2241 2259
    /// \name Execution of the reader
2242 2260
    /// @{
2243 2261

	
2244 2262
    /// \brief Start the batch processing
2245 2263
    ///
2246 2264
    /// This function starts the batch processing.
2247 2265
    void run() {
2248 2266

	
2249 2267
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2250 2268

	
2251 2269
      std::set<std::string> extra_sections;
2252 2270

	
2253 2271
      line_num = 0;
2254 2272
      readLine();
2255 2273
      skipSection();
2256 2274

	
2257 2275
      while (readSuccess()) {
2258 2276
        try {
2259 2277
          char c;
2260 2278
          std::string section, caption;
2261 2279
          line >> c;
2262 2280
          _reader_bits::readToken(line, section);
2263 2281
          _reader_bits::readToken(line, caption);
2264 2282

	
2265 2283
          if (line >> c)
2266 2284
            throw FormatError("Extra character at the end of line");
2267 2285

	
2268 2286
          if (extra_sections.find(section) != extra_sections.end()) {
2269 2287
            std::ostringstream msg;
2270 2288
            msg << "Multiple occurence of section: " << section;
2271 2289
            throw FormatError(msg.str());
2272 2290
          }
2273 2291
          Sections::iterator it = _sections.find(section);
2274 2292
          if (it != _sections.end()) {
2275 2293
            extra_sections.insert(section);
2276 2294
            it->second->process(*_is, line_num);
2277 2295
          }
2278 2296
          readLine();
2279 2297
          skipSection();
2280 2298
        } catch (FormatError& error) {
2281 2299
          error.line(line_num);
2282 2300
          error.file(_filename);
2283 2301
          throw;
2284 2302
        }
2285 2303
      }
2286 2304
      for (Sections::iterator it = _sections.begin();
2287 2305
           it != _sections.end(); ++it) {
2288 2306
        if (extra_sections.find(it->first) == extra_sections.end()) {
2289 2307
          std::ostringstream os;
2290 2308
          os << "Cannot find section: " << it->first;
2291 2309
          throw FormatError(os.str());
2292 2310
        }
2293 2311
      }
2294 2312
    }
2295 2313

	
2296 2314
    /// @}
2297 2315

	
2298 2316
  };
2299 2317

	
2300 2318
  /// \brief Return a \ref SectionReader class
2301 2319
  ///
2302 2320
  /// This function just returns a \ref SectionReader class.
Ignore white space 6 line context
... ...
@@ -97,1655 +97,1681 @@
97 97

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
319 319
      Functor _functor;
320 320

	
321 321
    public:
322 322

	
323 323
      LineSection(const Functor& functor) : _functor(functor) {}
324 324
      virtual ~LineSection() {}
325 325

	
326 326
      virtual void process(std::ostream& os) {
327 327
        std::string line;
328 328
        while (!(line = _functor()).empty()) os << line << std::endl;
329 329
      }
330 330
    };
331 331

	
332 332
    template <typename Functor>
333 333
    class StreamSection : public Section {
334 334
    private:
335 335

	
336 336
      Functor _functor;
337 337

	
338 338
    public:
339 339

	
340 340
      StreamSection(const Functor& functor) : _functor(functor) {}
341 341
      virtual ~StreamSection() {}
342 342

	
343 343
      virtual void process(std::ostream& os) {
344 344
        _functor(os);
345 345
      }
346 346
    };
347 347

	
348 348
  }
349 349

	
350 350
  template <typename Digraph>
351 351
  class DigraphWriter;
352 352

	
353
  /// \brief Return a \ref DigraphWriter class
354
  ///
355
  /// This function just returns a \ref DigraphWriter class.
356
  /// \relates DigraphWriter
357 353
  template <typename Digraph>
358 354
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
359
                                       std::ostream& os = std::cout) {
360
    DigraphWriter<Digraph> tmp(digraph, os);
361
    return tmp;
362
  }
363

	
364
  /// \brief Return a \ref DigraphWriter class
365
  ///
366
  /// This function just returns a \ref DigraphWriter class.
367
  /// \relates DigraphWriter
355
                                       std::ostream& os = std::cout);
368 356
  template <typename Digraph>
369 357
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
370
                                       const std::string& fn) {
371
    DigraphWriter<Digraph> tmp(digraph, fn);
372
    return tmp;
373
  }
358
                                       const std::string& fn);
374 359

	
375
  /// \brief Return a \ref DigraphWriter class
376
  ///
377
  /// This function just returns a \ref DigraphWriter class.
378
  /// \relates DigraphWriter
379 360
  template <typename Digraph>
380 361
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
381
                                       const char* fn) {
382
    DigraphWriter<Digraph> tmp(digraph, fn);
383
    return tmp;
384
  }
362
                                       const char* fn);
363

	
385 364

	
386 365
  /// \ingroup lemon_io
387 366
  ///
388 367
  /// \brief \ref lgf-format "LGF" writer for directed graphs
389 368
  ///
390 369
  /// This utility writes an \ref lgf-format "LGF" file.
391 370
  ///
392 371
  /// The writing method does a batch processing. The user creates a
393 372
  /// writer object, then various writing rules can be added to the
394 373
  /// writer, and eventually the writing is executed with the \c run()
395 374
  /// member function. A map writing rule can be added to the writer
396 375
  /// with the \c nodeMap() or \c arcMap() members. An optional
397 376
  /// converter parameter can also be added as a standard functor
398 377
  /// converting from the value type of the map to \c std::string. If it
399 378
  /// is set, it will determine how the value type of the map is written to
400 379
  /// the output stream. If the functor is not set, then a default
401 380
  /// conversion will be used. The \c attribute(), \c node() and \c
402 381
  /// arc() functions are used to add attribute writing rules.
403 382
  ///
404 383
  ///\code
405 384
  /// DigraphWriter<Digraph>(digraph, std::cout).
406 385
  ///   nodeMap("coordinates", coord_map).
407 386
  ///   nodeMap("size", size).
408 387
  ///   nodeMap("title", title).
409 388
  ///   arcMap("capacity", cap_map).
410 389
  ///   node("source", src).
411 390
  ///   node("target", trg).
412 391
  ///   attribute("caption", caption).
413 392
  ///   run();
414 393
  ///\endcode
415 394
  ///
416 395
  ///
417 396
  /// By default, the writer does not write additional captions to the
418 397
  /// sections, but they can be give as an optional parameter of
419 398
  /// the \c nodes(), \c arcs() or \c
420 399
  /// attributes() functions.
421 400
  ///
422 401
  /// The \c skipNodes() and \c skipArcs() functions forbid the
423 402
  /// writing of the sections. If two arc sections should be written
424 403
  /// to the output, it can be done in two passes, the first pass
425 404
  /// writes the node section and the first arc section, then the
426 405
  /// second pass skips the node section and writes just the arc
427 406
  /// section to the stream. The output stream can be retrieved with
428 407
  /// the \c ostream() function, hence the second pass can append its
429 408
  /// output to the output of the first pass.
430 409
  template <typename _Digraph>
431 410
  class DigraphWriter {
432 411
  public:
433 412

	
434 413
    typedef _Digraph Digraph;
435 414
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
436 415

	
437 416
  private:
438 417

	
439 418

	
440 419
    std::ostream* _os;
441 420
    bool local_os;
442 421

	
443 422
    const Digraph& _digraph;
444 423

	
445 424
    std::string _nodes_caption;
446 425
    std::string _arcs_caption;
447 426
    std::string _attributes_caption;
448 427

	
449 428
    typedef std::map<Node, std::string> NodeIndex;
450 429
    NodeIndex _node_index;
451 430
    typedef std::map<Arc, std::string> ArcIndex;
452 431
    ArcIndex _arc_index;
453 432

	
454 433
    typedef std::vector<std::pair<std::string,
455 434
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
456 435
    NodeMaps _node_maps;
457 436

	
458 437
    typedef std::vector<std::pair<std::string,
459 438
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
460 439
    ArcMaps _arc_maps;
461 440

	
462 441
    typedef std::vector<std::pair<std::string,
463 442
      _writer_bits::ValueStorageBase*> > Attributes;
464 443
    Attributes _attributes;
465 444

	
466 445
    bool _skip_nodes;
467 446
    bool _skip_arcs;
468 447

	
469 448
  public:
470 449

	
471 450
    /// \brief Constructor
472 451
    ///
473 452
    /// Construct a directed graph writer, which writes to the given
474 453
    /// output stream.
475 454
    DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
476 455
      : _os(&os), local_os(false), _digraph(digraph),
477 456
        _skip_nodes(false), _skip_arcs(false) {}
478 457

	
479 458
    /// \brief Constructor
480 459
    ///
481 460
    /// Construct a directed graph writer, which writes to the given
482 461
    /// output file.
483 462
    DigraphWriter(const Digraph& digraph, const std::string& fn)
484 463
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
485 464
        _skip_nodes(false), _skip_arcs(false) {
486 465
      if (!(*_os)) {
487 466
        delete _os;
488 467
        throw IoError("Cannot write file", fn);
489 468
      }
490 469
    }
491 470

	
492 471
    /// \brief Constructor
493 472
    ///
494 473
    /// Construct a directed graph writer, which writes to the given
495 474
    /// output file.
496 475
    DigraphWriter(const Digraph& digraph, const char* fn)
497 476
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
498 477
        _skip_nodes(false), _skip_arcs(false) {
499 478
      if (!(*_os)) {
500 479
        delete _os;
501 480
        throw IoError("Cannot write file", fn);
502 481
      }
503 482
    }
504 483

	
505 484
    /// \brief Destructor
506 485
    ~DigraphWriter() {
507 486
      for (typename NodeMaps::iterator it = _node_maps.begin();
508 487
           it != _node_maps.end(); ++it) {
509 488
        delete it->second;
510 489
      }
511 490

	
512 491
      for (typename ArcMaps::iterator it = _arc_maps.begin();
513 492
           it != _arc_maps.end(); ++it) {
514 493
        delete it->second;
515 494
      }
516 495

	
517 496
      for (typename Attributes::iterator it = _attributes.begin();
518 497
           it != _attributes.end(); ++it) {
519 498
        delete it->second;
520 499
      }
521 500

	
522 501
      if (local_os) {
523 502
        delete _os;
524 503
      }
525 504
    }
526 505

	
527 506
  private:
528 507

	
529
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
530
                                                  std::ostream& os);
531
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
532
                                                  const std::string& fn);
533
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
534
                                                  const char *fn);
508
    template <typename DGR>
509
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
510
                                            std::ostream& os);
511
    template <typename DGR>
512
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
513
                                            const std::string& fn);
514
    template <typename DGR>
515
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
516
                                            const char *fn);
535 517

	
536 518
    DigraphWriter(DigraphWriter& other)
537 519
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
538 520
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
539 521

	
540 522
      other._os = 0;
541 523
      other.local_os = false;
542 524

	
543 525
      _node_index.swap(other._node_index);
544 526
      _arc_index.swap(other._arc_index);
545 527

	
546 528
      _node_maps.swap(other._node_maps);
547 529
      _arc_maps.swap(other._arc_maps);
548 530
      _attributes.swap(other._attributes);
549 531

	
550 532
      _nodes_caption = other._nodes_caption;
551 533
      _arcs_caption = other._arcs_caption;
552 534
      _attributes_caption = other._attributes_caption;
553 535
    }
554 536

	
555 537
    DigraphWriter& operator=(const DigraphWriter&);
556 538

	
557 539
  public:
558 540

	
559 541
    /// \name Writing rules
560 542
    /// @{
561 543

	
562 544
    /// \brief Node map writing rule
563 545
    ///
564 546
    /// Add a node map writing rule to the writer.
565 547
    template <typename Map>
566 548
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
567 549
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
568 550
      _writer_bits::MapStorageBase<Node>* storage =
569 551
        new _writer_bits::MapStorage<Node, Map>(map);
570 552
      _node_maps.push_back(std::make_pair(caption, storage));
571 553
      return *this;
572 554
    }
573 555

	
574 556
    /// \brief Node map writing rule
575 557
    ///
576 558
    /// Add a node map writing rule with specialized converter to the
577 559
    /// writer.
578 560
    template <typename Map, typename Converter>
579 561
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
580 562
                           const Converter& converter = Converter()) {
581 563
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
582 564
      _writer_bits::MapStorageBase<Node>* storage =
583 565
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
584 566
      _node_maps.push_back(std::make_pair(caption, storage));
585 567
      return *this;
586 568
    }
587 569

	
588 570
    /// \brief Arc map writing rule
589 571
    ///
590 572
    /// Add an arc map writing rule to the writer.
591 573
    template <typename Map>
592 574
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
593 575
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
594 576
      _writer_bits::MapStorageBase<Arc>* storage =
595 577
        new _writer_bits::MapStorage<Arc, Map>(map);
596 578
      _arc_maps.push_back(std::make_pair(caption, storage));
597 579
      return *this;
598 580
    }
599 581

	
600 582
    /// \brief Arc map writing rule
601 583
    ///
602 584
    /// Add an arc map writing rule with specialized converter to the
603 585
    /// writer.
604 586
    template <typename Map, typename Converter>
605 587
    DigraphWriter& arcMap(const std::string& caption, const Map& map,
606 588
                          const Converter& converter = Converter()) {
607 589
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
608 590
      _writer_bits::MapStorageBase<Arc>* storage =
609 591
        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
610 592
      _arc_maps.push_back(std::make_pair(caption, storage));
611 593
      return *this;
612 594
    }
613 595

	
614 596
    /// \brief Attribute writing rule
615 597
    ///
616 598
    /// Add an attribute writing rule to the writer.
617 599
    template <typename Value>
618 600
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
619 601
      _writer_bits::ValueStorageBase* storage =
620 602
        new _writer_bits::ValueStorage<Value>(value);
621 603
      _attributes.push_back(std::make_pair(caption, storage));
622 604
      return *this;
623 605
    }
624 606

	
625 607
    /// \brief Attribute writing rule
626 608
    ///
627 609
    /// Add an attribute writing rule with specialized converter to the
628 610
    /// writer.
629 611
    template <typename Value, typename Converter>
630 612
    DigraphWriter& attribute(const std::string& caption, const Value& value,
631 613
                             const Converter& converter = Converter()) {
632 614
      _writer_bits::ValueStorageBase* storage =
633 615
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
634 616
      _attributes.push_back(std::make_pair(caption, storage));
635 617
      return *this;
636 618
    }
637 619

	
638 620
    /// \brief Node writing rule
639 621
    ///
640 622
    /// Add a node writing rule to the writer.
641 623
    DigraphWriter& node(const std::string& caption, const Node& node) {
642 624
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
643 625
      Converter converter(_node_index);
644 626
      _writer_bits::ValueStorageBase* storage =
645 627
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
646 628
      _attributes.push_back(std::make_pair(caption, storage));
647 629
      return *this;
648 630
    }
649 631

	
650 632
    /// \brief Arc writing rule
651 633
    ///
652 634
    /// Add an arc writing rule to writer.
653 635
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
654 636
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
655 637
      Converter converter(_arc_index);
656 638
      _writer_bits::ValueStorageBase* storage =
657 639
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
658 640
      _attributes.push_back(std::make_pair(caption, storage));
659 641
      return *this;
660 642
    }
661 643

	
662 644
    /// \name Section captions
663 645
    /// @{
664 646

	
665 647
    /// \brief Add an additional caption to the \c \@nodes section
666 648
    ///
667 649
    /// Add an additional caption to the \c \@nodes section.
668 650
    DigraphWriter& nodes(const std::string& caption) {
669 651
      _nodes_caption = caption;
670 652
      return *this;
671 653
    }
672 654

	
673 655
    /// \brief Add an additional caption to the \c \@arcs section
674 656
    ///
675 657
    /// Add an additional caption to the \c \@arcs section.
676 658
    DigraphWriter& arcs(const std::string& caption) {
677 659
      _arcs_caption = caption;
678 660
      return *this;
679 661
    }
680 662

	
681 663
    /// \brief Add an additional caption to the \c \@attributes section
682 664
    ///
683 665
    /// Add an additional caption to the \c \@attributes section.
684 666
    DigraphWriter& attributes(const std::string& caption) {
685 667
      _attributes_caption = caption;
686 668
      return *this;
687 669
    }
688 670

	
689 671
    /// \name Skipping section
690 672
    /// @{
691 673

	
692 674
    /// \brief Skip writing the node set
693 675
    ///
694 676
    /// The \c \@nodes section will not be written to the stream.
695 677
    DigraphWriter& skipNodes() {
696 678
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
697 679
      _skip_nodes = true;
698 680
      return *this;
699 681
    }
700 682

	
701 683
    /// \brief Skip writing arc set
702 684
    ///
703 685
    /// The \c \@arcs section will not be written to the stream.
704 686
    DigraphWriter& skipArcs() {
705 687
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
706 688
      _skip_arcs = true;
707 689
      return *this;
708 690
    }
709 691

	
710 692
    /// @}
711 693

	
712 694
  private:
713 695

	
714 696
    void writeNodes() {
715 697
      _writer_bits::MapStorageBase<Node>* label = 0;
716 698
      for (typename NodeMaps::iterator it = _node_maps.begin();
717 699
           it != _node_maps.end(); ++it) {
718 700
        if (it->first == "label") {
719 701
          label = it->second;
720 702
          break;
721 703
        }
722 704
      }
723 705

	
724 706
      *_os << "@nodes";
725 707
      if (!_nodes_caption.empty()) {
726 708
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
727 709
      }
728 710
      *_os << std::endl;
729 711

	
730 712
      if (label == 0) {
731 713
        *_os << "label" << '\t';
732 714
      }
733 715
      for (typename NodeMaps::iterator it = _node_maps.begin();
734 716
           it != _node_maps.end(); ++it) {
735 717
        _writer_bits::writeToken(*_os, it->first) << '\t';
736 718
      }
737 719
      *_os << std::endl;
738 720

	
739 721
      std::vector<Node> nodes;
740 722
      for (NodeIt n(_digraph); n != INVALID; ++n) {
741 723
        nodes.push_back(n);
742 724
      }
743 725

	
744 726
      if (label == 0) {
745 727
        IdMap<Digraph, Node> id_map(_digraph);
746 728
        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
747 729
        std::sort(nodes.begin(), nodes.end(), id_less);
748 730
      } else {
749 731
        label->sort(nodes);
750 732
      }
751 733

	
752 734
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
753 735
        Node n = nodes[i];
754 736
        if (label == 0) {
755 737
          std::ostringstream os;
756 738
          os << _digraph.id(n);
757 739
          _writer_bits::writeToken(*_os, os.str());
758 740
          *_os << '\t';
759 741
          _node_index.insert(std::make_pair(n, os.str()));
760 742
        }
761 743
        for (typename NodeMaps::iterator it = _node_maps.begin();
762 744
             it != _node_maps.end(); ++it) {
763 745
          std::string value = it->second->get(n);
764 746
          _writer_bits::writeToken(*_os, value);
765 747
          if (it->first == "label") {
766 748
            _node_index.insert(std::make_pair(n, value));
767 749
          }
768 750
          *_os << '\t';
769 751
        }
770 752
        *_os << std::endl;
771 753
      }
772 754
    }
773 755

	
774 756
    void createNodeIndex() {
775 757
      _writer_bits::MapStorageBase<Node>* label = 0;
776 758
      for (typename NodeMaps::iterator it = _node_maps.begin();
777 759
           it != _node_maps.end(); ++it) {
778 760
        if (it->first == "label") {
779 761
          label = it->second;
780 762
          break;
781 763
        }
782 764
      }
783 765

	
784 766
      if (label == 0) {
785 767
        for (NodeIt n(_digraph); n != INVALID; ++n) {
786 768
          std::ostringstream os;
787 769
          os << _digraph.id(n);
788 770
          _node_index.insert(std::make_pair(n, os.str()));
789 771
        }
790 772
      } else {
791 773
        for (NodeIt n(_digraph); n != INVALID; ++n) {
792 774
          std::string value = label->get(n);
793 775
          _node_index.insert(std::make_pair(n, value));
794 776
        }
795 777
      }
796 778
    }
797 779

	
798 780
    void writeArcs() {
799 781
      _writer_bits::MapStorageBase<Arc>* label = 0;
800 782
      for (typename ArcMaps::iterator it = _arc_maps.begin();
801 783
           it != _arc_maps.end(); ++it) {
802 784
        if (it->first == "label") {
803 785
          label = it->second;
804 786
          break;
805 787
        }
806 788
      }
807 789

	
808 790
      *_os << "@arcs";
809 791
      if (!_arcs_caption.empty()) {
810 792
        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
811 793
      }
812 794
      *_os << std::endl;
813 795

	
814 796
      *_os << '\t' << '\t';
815 797
      if (label == 0) {
816 798
        *_os << "label" << '\t';
817 799
      }
818 800
      for (typename ArcMaps::iterator it = _arc_maps.begin();
819 801
           it != _arc_maps.end(); ++it) {
820 802
        _writer_bits::writeToken(*_os, it->first) << '\t';
821 803
      }
822 804
      *_os << std::endl;
823 805

	
824 806
      std::vector<Arc> arcs;
825 807
      for (ArcIt n(_digraph); n != INVALID; ++n) {
826 808
        arcs.push_back(n);
827 809
      }
828 810

	
829 811
      if (label == 0) {
830 812
        IdMap<Digraph, Arc> id_map(_digraph);
831 813
        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
832 814
        std::sort(arcs.begin(), arcs.end(), id_less);
833 815
      } else {
834 816
        label->sort(arcs);
835 817
      }
836 818

	
837 819
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
838 820
        Arc a = arcs[i];
839 821
        _writer_bits::writeToken(*_os, _node_index.
840 822
                                 find(_digraph.source(a))->second);
841 823
        *_os << '\t';
842 824
        _writer_bits::writeToken(*_os, _node_index.
843 825
                                 find(_digraph.target(a))->second);
844 826
        *_os << '\t';
845 827
        if (label == 0) {
846 828
          std::ostringstream os;
847 829
          os << _digraph.id(a);
848 830
          _writer_bits::writeToken(*_os, os.str());
849 831
          *_os << '\t';
850 832
          _arc_index.insert(std::make_pair(a, os.str()));
851 833
        }
852 834
        for (typename ArcMaps::iterator it = _arc_maps.begin();
853 835
             it != _arc_maps.end(); ++it) {
854 836
          std::string value = it->second->get(a);
855 837
          _writer_bits::writeToken(*_os, value);
856 838
          if (it->first == "label") {
857 839
            _arc_index.insert(std::make_pair(a, value));
858 840
          }
859 841
          *_os << '\t';
860 842
        }
861 843
        *_os << std::endl;
862 844
      }
863 845
    }
864 846

	
865 847
    void createArcIndex() {
866 848
      _writer_bits::MapStorageBase<Arc>* label = 0;
867 849
      for (typename ArcMaps::iterator it = _arc_maps.begin();
868 850
           it != _arc_maps.end(); ++it) {
869 851
        if (it->first == "label") {
870 852
          label = it->second;
871 853
          break;
872 854
        }
873 855
      }
874 856

	
875 857
      if (label == 0) {
876 858
        for (ArcIt a(_digraph); a != INVALID; ++a) {
877 859
          std::ostringstream os;
878 860
          os << _digraph.id(a);
879 861
          _arc_index.insert(std::make_pair(a, os.str()));
880 862
        }
881 863
      } else {
882 864
        for (ArcIt a(_digraph); a != INVALID; ++a) {
883 865
          std::string value = label->get(a);
884 866
          _arc_index.insert(std::make_pair(a, value));
885 867
        }
886 868
      }
887 869
    }
888 870

	
889 871
    void writeAttributes() {
890 872
      if (_attributes.empty()) return;
891 873
      *_os << "@attributes";
892 874
      if (!_attributes_caption.empty()) {
893 875
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
894 876
      }
895 877
      *_os << std::endl;
896 878
      for (typename Attributes::iterator it = _attributes.begin();
897 879
           it != _attributes.end(); ++it) {
898 880
        _writer_bits::writeToken(*_os, it->first) << ' ';
899 881
        _writer_bits::writeToken(*_os, it->second->get());
900 882
        *_os << std::endl;
901 883
      }
902 884
    }
903 885

	
904 886
  public:
905 887

	
906 888
    /// \name Execution of the writer
907 889
    /// @{
908 890

	
909 891
    /// \brief Start the batch processing
910 892
    ///
911 893
    /// This function starts the batch processing.
912 894
    void run() {
913 895
      if (!_skip_nodes) {
914 896
        writeNodes();
915 897
      } else {
916 898
        createNodeIndex();
917 899
      }
918 900
      if (!_skip_arcs) {
919 901
        writeArcs();
920 902
      } else {
921 903
        createArcIndex();
922 904
      }
923 905
      writeAttributes();
924 906
    }
925 907

	
926 908
    /// \brief Give back the stream of the writer
927 909
    ///
928 910
    /// Give back the stream of the writer.
929 911
    std::ostream& ostream() {
930 912
      return *_os;
931 913
    }
932 914

	
933 915
    /// @}
934 916
  };
935 917

	
918
  /// \brief Return a \ref DigraphWriter class
919
  ///
920
  /// This function just returns a \ref DigraphWriter class.
921
  /// \relates DigraphWriter
922
  template <typename Digraph>
923
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
924
                                       std::ostream& os) {
925
    DigraphWriter<Digraph> tmp(digraph, os);
926
    return tmp;
927
  }
928

	
929
  /// \brief Return a \ref DigraphWriter class
930
  ///
931
  /// This function just returns a \ref DigraphWriter class.
932
  /// \relates DigraphWriter
933
  template <typename Digraph>
934
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
935
                                       const std::string& fn) {
936
    DigraphWriter<Digraph> tmp(digraph, fn);
937
    return tmp;
938
  }
939

	
940
  /// \brief Return a \ref DigraphWriter class
941
  ///
942
  /// This function just returns a \ref DigraphWriter class.
943
  /// \relates DigraphWriter
944
  template <typename Digraph>
945
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
946
                                       const char* fn) {
947
    DigraphWriter<Digraph> tmp(digraph, fn);
948
    return tmp;
949
  }
950

	
936 951
  template <typename Graph>
937 952
  class GraphWriter;
938 953

	
939
  /// \brief Return a \ref GraphWriter class
940
  ///
941
  /// This function just returns a \ref GraphWriter class.
942
  /// \relates GraphWriter
943 954
  template <typename Graph>
944 955
  GraphWriter<Graph> graphWriter(const Graph& graph,
945
                                 std::ostream& os = std::cout) {
946
    GraphWriter<Graph> tmp(graph, os);
947
    return tmp;
948
  }
949

	
950
  /// \brief Return a \ref GraphWriter class
951
  ///
952
  /// This function just returns a \ref GraphWriter class.
953
  /// \relates GraphWriter
956
                                 std::ostream& os = std::cout);
954 957
  template <typename Graph>
955
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
956
    GraphWriter<Graph> tmp(graph, fn);
957
    return tmp;
958
  }
959

	
960
  /// \brief Return a \ref GraphWriter class
961
  ///
962
  /// This function just returns a \ref GraphWriter class.
963
  /// \relates GraphWriter
958
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
964 959
  template <typename Graph>
965
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
966
    GraphWriter<Graph> tmp(graph, fn);
967
    return tmp;
968
  }
960
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
969 961

	
970 962
  /// \ingroup lemon_io
971 963
  ///
972 964
  /// \brief \ref lgf-format "LGF" writer for directed graphs
973 965
  ///
974 966
  /// This utility writes an \ref lgf-format "LGF" file.
975 967
  ///
976 968
  /// It can be used almost the same way as \c DigraphWriter.
977 969
  /// The only difference is that this class can handle edges and
978 970
  /// edge maps as well as arcs and arc maps.
979 971
  ///
980 972
  /// The arc maps are written into the file as two columns, the
981 973
  /// caption of the columns are the name of the map prefixed with \c
982 974
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
983 975
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
984 976
  /// of the arc) and the label of corresponding edge.
985 977
  template <typename _Graph>
986 978
  class GraphWriter {
987 979
  public:
988 980

	
989 981
    typedef _Graph Graph;
990 982
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
991 983

	
992 984
  private:
993 985

	
994 986

	
995 987
    std::ostream* _os;
996 988
    bool local_os;
997 989

	
998 990
    const Graph& _graph;
999 991

	
1000 992
    std::string _nodes_caption;
1001 993
    std::string _edges_caption;
1002 994
    std::string _attributes_caption;
1003 995

	
1004 996
    typedef std::map<Node, std::string> NodeIndex;
1005 997
    NodeIndex _node_index;
1006 998
    typedef std::map<Edge, std::string> EdgeIndex;
1007 999
    EdgeIndex _edge_index;
1008 1000

	
1009 1001
    typedef std::vector<std::pair<std::string,
1010 1002
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
1011 1003
    NodeMaps _node_maps;
1012 1004

	
1013 1005
    typedef std::vector<std::pair<std::string,
1014 1006
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
1015 1007
    EdgeMaps _edge_maps;
1016 1008

	
1017 1009
    typedef std::vector<std::pair<std::string,
1018 1010
      _writer_bits::ValueStorageBase*> > Attributes;
1019 1011
    Attributes _attributes;
1020 1012

	
1021 1013
    bool _skip_nodes;
1022 1014
    bool _skip_edges;
1023 1015

	
1024 1016
  public:
1025 1017

	
1026 1018
    /// \brief Constructor
1027 1019
    ///
1028 1020
    /// Construct a directed graph writer, which writes to the given
1029 1021
    /// output stream.
1030 1022
    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
1031 1023
      : _os(&os), local_os(false), _graph(graph),
1032 1024
        _skip_nodes(false), _skip_edges(false) {}
1033 1025

	
1034 1026
    /// \brief Constructor
1035 1027
    ///
1036 1028
    /// Construct a directed graph writer, which writes to the given
1037 1029
    /// output file.
1038 1030
    GraphWriter(const Graph& graph, const std::string& fn)
1039 1031
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1040 1032
        _skip_nodes(false), _skip_edges(false) {
1041 1033
      if (!(*_os)) {
1042 1034
        delete _os;
1043 1035
        throw IoError("Cannot write file", fn);
1044 1036
      }
1045 1037
    }
1046 1038

	
1047 1039
    /// \brief Constructor
1048 1040
    ///
1049 1041
    /// Construct a directed graph writer, which writes to the given
1050 1042
    /// output file.
1051 1043
    GraphWriter(const Graph& graph, const char* fn)
1052 1044
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
1053 1045
        _skip_nodes(false), _skip_edges(false) {
1054 1046
      if (!(*_os)) {
1055 1047
        delete _os;
1056 1048
        throw IoError("Cannot write file", fn);
1057 1049
      }
1058 1050
    }
1059 1051

	
1060 1052
    /// \brief Destructor
1061 1053
    ~GraphWriter() {
1062 1054
      for (typename NodeMaps::iterator it = _node_maps.begin();
1063 1055
           it != _node_maps.end(); ++it) {
1064 1056
        delete it->second;
1065 1057
      }
1066 1058

	
1067 1059
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1068 1060
           it != _edge_maps.end(); ++it) {
1069 1061
        delete it->second;
1070 1062
      }
1071 1063

	
1072 1064
      for (typename Attributes::iterator it = _attributes.begin();
1073 1065
           it != _attributes.end(); ++it) {
1074 1066
        delete it->second;
1075 1067
      }
1076 1068

	
1077 1069
      if (local_os) {
1078 1070
        delete _os;
1079 1071
      }
1080 1072
    }
1081 1073

	
1082 1074
  private:
1083 1075

	
1084
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1085
                                            std::ostream& os);
1086
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1087
                                            const std::string& fn);
1088
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1089
                                            const char *fn);
1090

	
1076
    template <typename GR>
1077
    friend GraphWriter<GR> graphWriter(const GR& graph,
1078
                                       std::ostream& os);
1079
    template <typename GR>
1080
    friend GraphWriter<GR> graphWriter(const GR& graph,
1081
                                       const std::string& fn);
1082
    template <typename GR>
1083
    friend GraphWriter<GR> graphWriter(const GR& graph,
1084
                                       const char *fn);
1085
    
1091 1086
    GraphWriter(GraphWriter& other)
1092 1087
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1093 1088
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1094 1089

	
1095 1090
      other._os = 0;
1096 1091
      other.local_os = false;
1097 1092

	
1098 1093
      _node_index.swap(other._node_index);
1099 1094
      _edge_index.swap(other._edge_index);
1100 1095

	
1101 1096
      _node_maps.swap(other._node_maps);
1102 1097
      _edge_maps.swap(other._edge_maps);
1103 1098
      _attributes.swap(other._attributes);
1104 1099

	
1105 1100
      _nodes_caption = other._nodes_caption;
1106 1101
      _edges_caption = other._edges_caption;
1107 1102
      _attributes_caption = other._attributes_caption;
1108 1103
    }
1109 1104

	
1110 1105
    GraphWriter& operator=(const GraphWriter&);
1111 1106

	
1112 1107
  public:
1113 1108

	
1114 1109
    /// \name Writing rules
1115 1110
    /// @{
1116 1111

	
1117 1112
    /// \brief Node map writing rule
1118 1113
    ///
1119 1114
    /// Add a node map writing rule to the writer.
1120 1115
    template <typename Map>
1121 1116
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1122 1117
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1123 1118
      _writer_bits::MapStorageBase<Node>* storage =
1124 1119
        new _writer_bits::MapStorage<Node, Map>(map);
1125 1120
      _node_maps.push_back(std::make_pair(caption, storage));
1126 1121
      return *this;
1127 1122
    }
1128 1123

	
1129 1124
    /// \brief Node map writing rule
1130 1125
    ///
1131 1126
    /// Add a node map writing rule with specialized converter to the
1132 1127
    /// writer.
1133 1128
    template <typename Map, typename Converter>
1134 1129
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1135 1130
                           const Converter& converter = Converter()) {
1136 1131
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1137 1132
      _writer_bits::MapStorageBase<Node>* storage =
1138 1133
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1139 1134
      _node_maps.push_back(std::make_pair(caption, storage));
1140 1135
      return *this;
1141 1136
    }
1142 1137

	
1143 1138
    /// \brief Edge map writing rule
1144 1139
    ///
1145 1140
    /// Add an edge map writing rule to the writer.
1146 1141
    template <typename Map>
1147 1142
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1148 1143
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1149 1144
      _writer_bits::MapStorageBase<Edge>* storage =
1150 1145
        new _writer_bits::MapStorage<Edge, Map>(map);
1151 1146
      _edge_maps.push_back(std::make_pair(caption, storage));
1152 1147
      return *this;
1153 1148
    }
1154 1149

	
1155 1150
    /// \brief Edge map writing rule
1156 1151
    ///
1157 1152
    /// Add an edge map writing rule with specialized converter to the
1158 1153
    /// writer.
1159 1154
    template <typename Map, typename Converter>
1160 1155
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1161 1156
                          const Converter& converter = Converter()) {
1162 1157
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1163 1158
      _writer_bits::MapStorageBase<Edge>* storage =
1164 1159
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1165 1160
      _edge_maps.push_back(std::make_pair(caption, storage));
1166 1161
      return *this;
1167 1162
    }
1168 1163

	
1169 1164
    /// \brief Arc map writing rule
1170 1165
    ///
1171 1166
    /// Add an arc map writing rule to the writer.
1172 1167
    template <typename Map>
1173 1168
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1174 1169
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1175 1170
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1176 1171
        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1177 1172
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1178 1173
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1179 1174
        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1180 1175
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1181 1176
      return *this;
1182 1177
    }
1183 1178

	
1184 1179
    /// \brief Arc map writing rule
1185 1180
    ///
1186 1181
    /// Add an arc map writing rule with specialized converter to the
1187 1182
    /// writer.
1188 1183
    template <typename Map, typename Converter>
1189 1184
    GraphWriter& arcMap(const std::string& caption, const Map& map,
1190 1185
                          const Converter& converter = Converter()) {
1191 1186
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1192 1187
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1193 1188
        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1194 1189
        (_graph, map, converter);
1195 1190
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1196 1191
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1197 1192
        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1198 1193
        (_graph, map, converter);
1199 1194
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1200 1195
      return *this;
1201 1196
    }
1202 1197

	
1203 1198
    /// \brief Attribute writing rule
1204 1199
    ///
1205 1200
    /// Add an attribute writing rule to the writer.
1206 1201
    template <typename Value>
1207 1202
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1208 1203
      _writer_bits::ValueStorageBase* storage =
1209 1204
        new _writer_bits::ValueStorage<Value>(value);
1210 1205
      _attributes.push_back(std::make_pair(caption, storage));
1211 1206
      return *this;
1212 1207
    }
1213 1208

	
1214 1209
    /// \brief Attribute writing rule
1215 1210
    ///
1216 1211
    /// Add an attribute writing rule with specialized converter to the
1217 1212
    /// writer.
1218 1213
    template <typename Value, typename Converter>
1219 1214
    GraphWriter& attribute(const std::string& caption, const Value& value,
1220 1215
                             const Converter& converter = Converter()) {
1221 1216
      _writer_bits::ValueStorageBase* storage =
1222 1217
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1223 1218
      _attributes.push_back(std::make_pair(caption, storage));
1224 1219
      return *this;
1225 1220
    }
1226 1221

	
1227 1222
    /// \brief Node writing rule
1228 1223
    ///
1229 1224
    /// Add a node writing rule to the writer.
1230 1225
    GraphWriter& node(const std::string& caption, const Node& node) {
1231 1226
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1232 1227
      Converter converter(_node_index);
1233 1228
      _writer_bits::ValueStorageBase* storage =
1234 1229
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1235 1230
      _attributes.push_back(std::make_pair(caption, storage));
1236 1231
      return *this;
1237 1232
    }
1238 1233

	
1239 1234
    /// \brief Edge writing rule
1240 1235
    ///
1241 1236
    /// Add an edge writing rule to writer.
1242 1237
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1243 1238
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1244 1239
      Converter converter(_edge_index);
1245 1240
      _writer_bits::ValueStorageBase* storage =
1246 1241
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1247 1242
      _attributes.push_back(std::make_pair(caption, storage));
1248 1243
      return *this;
1249 1244
    }
1250 1245

	
1251 1246
    /// \brief Arc writing rule
1252 1247
    ///
1253 1248
    /// Add an arc writing rule to writer.
1254 1249
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1255 1250
      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1256 1251
      Converter converter(_graph, _edge_index);
1257 1252
      _writer_bits::ValueStorageBase* storage =
1258 1253
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1259 1254
      _attributes.push_back(std::make_pair(caption, storage));
1260 1255
      return *this;
1261 1256
    }
1262 1257

	
1263 1258
    /// \name Section captions
1264 1259
    /// @{
1265 1260

	
1266 1261
    /// \brief Add an additional caption to the \c \@nodes section
1267 1262
    ///
1268 1263
    /// Add an additional caption to the \c \@nodes section.
1269 1264
    GraphWriter& nodes(const std::string& caption) {
1270 1265
      _nodes_caption = caption;
1271 1266
      return *this;
1272 1267
    }
1273 1268

	
1274 1269
    /// \brief Add an additional caption to the \c \@arcs section
1275 1270
    ///
1276 1271
    /// Add an additional caption to the \c \@arcs section.
1277 1272
    GraphWriter& edges(const std::string& caption) {
1278 1273
      _edges_caption = caption;
1279 1274
      return *this;
1280 1275
    }
1281 1276

	
1282 1277
    /// \brief Add an additional caption to the \c \@attributes section
1283 1278
    ///
1284 1279
    /// Add an additional caption to the \c \@attributes section.
1285 1280
    GraphWriter& attributes(const std::string& caption) {
1286 1281
      _attributes_caption = caption;
1287 1282
      return *this;
1288 1283
    }
1289 1284

	
1290 1285
    /// \name Skipping section
1291 1286
    /// @{
1292 1287

	
1293 1288
    /// \brief Skip writing the node set
1294 1289
    ///
1295 1290
    /// The \c \@nodes section will not be written to the stream.
1296 1291
    GraphWriter& skipNodes() {
1297 1292
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1298 1293
      _skip_nodes = true;
1299 1294
      return *this;
1300 1295
    }
1301 1296

	
1302 1297
    /// \brief Skip writing edge set
1303 1298
    ///
1304 1299
    /// The \c \@edges section will not be written to the stream.
1305 1300
    GraphWriter& skipEdges() {
1306 1301
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1307 1302
      _skip_edges = true;
1308 1303
      return *this;
1309 1304
    }
1310 1305

	
1311 1306
    /// @}
1312 1307

	
1313 1308
  private:
1314 1309

	
1315 1310
    void writeNodes() {
1316 1311
      _writer_bits::MapStorageBase<Node>* label = 0;
1317 1312
      for (typename NodeMaps::iterator it = _node_maps.begin();
1318 1313
           it != _node_maps.end(); ++it) {
1319 1314
        if (it->first == "label") {
1320 1315
          label = it->second;
1321 1316
          break;
1322 1317
        }
1323 1318
      }
1324 1319

	
1325 1320
      *_os << "@nodes";
1326 1321
      if (!_nodes_caption.empty()) {
1327 1322
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1328 1323
      }
1329 1324
      *_os << std::endl;
1330 1325

	
1331 1326
      if (label == 0) {
1332 1327
        *_os << "label" << '\t';
1333 1328
      }
1334 1329
      for (typename NodeMaps::iterator it = _node_maps.begin();
1335 1330
           it != _node_maps.end(); ++it) {
1336 1331
        _writer_bits::writeToken(*_os, it->first) << '\t';
1337 1332
      }
1338 1333
      *_os << std::endl;
1339 1334

	
1340 1335
      std::vector<Node> nodes;
1341 1336
      for (NodeIt n(_graph); n != INVALID; ++n) {
1342 1337
        nodes.push_back(n);
1343 1338
      }
1344 1339

	
1345 1340
      if (label == 0) {
1346 1341
        IdMap<Graph, Node> id_map(_graph);
1347 1342
        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1348 1343
        std::sort(nodes.begin(), nodes.end(), id_less);
1349 1344
      } else {
1350 1345
        label->sort(nodes);
1351 1346
      }
1352 1347

	
1353 1348
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1354 1349
        Node n = nodes[i];
1355 1350
        if (label == 0) {
1356 1351
          std::ostringstream os;
1357 1352
          os << _graph.id(n);
1358 1353
          _writer_bits::writeToken(*_os, os.str());
1359 1354
          *_os << '\t';
1360 1355
          _node_index.insert(std::make_pair(n, os.str()));
1361 1356
        }
1362 1357
        for (typename NodeMaps::iterator it = _node_maps.begin();
1363 1358
             it != _node_maps.end(); ++it) {
1364 1359
          std::string value = it->second->get(n);
1365 1360
          _writer_bits::writeToken(*_os, value);
1366 1361
          if (it->first == "label") {
1367 1362
            _node_index.insert(std::make_pair(n, value));
1368 1363
          }
1369 1364
          *_os << '\t';
1370 1365
        }
1371 1366
        *_os << std::endl;
1372 1367
      }
1373 1368
    }
1374 1369

	
1375 1370
    void createNodeIndex() {
1376 1371
      _writer_bits::MapStorageBase<Node>* label = 0;
1377 1372
      for (typename NodeMaps::iterator it = _node_maps.begin();
1378 1373
           it != _node_maps.end(); ++it) {
1379 1374
        if (it->first == "label") {
1380 1375
          label = it->second;
1381 1376
          break;
1382 1377
        }
1383 1378
      }
1384 1379

	
1385 1380
      if (label == 0) {
1386 1381
        for (NodeIt n(_graph); n != INVALID; ++n) {
1387 1382
          std::ostringstream os;
1388 1383
          os << _graph.id(n);
1389 1384
          _node_index.insert(std::make_pair(n, os.str()));
1390 1385
        }
1391 1386
      } else {
1392 1387
        for (NodeIt n(_graph); n != INVALID; ++n) {
1393 1388
          std::string value = label->get(n);
1394 1389
          _node_index.insert(std::make_pair(n, value));
1395 1390
        }
1396 1391
      }
1397 1392
    }
1398 1393

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

	
1409 1404
      *_os << "@edges";
1410 1405
      if (!_edges_caption.empty()) {
1411 1406
        _writer_bits::writeToken(*_os << ' ', _edges_caption);
1412 1407
      }
1413 1408
      *_os << std::endl;
1414 1409

	
1415 1410
      *_os << '\t' << '\t';
1416 1411
      if (label == 0) {
1417 1412
        *_os << "label" << '\t';
1418 1413
      }
1419 1414
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1420 1415
           it != _edge_maps.end(); ++it) {
1421 1416
        _writer_bits::writeToken(*_os, it->first) << '\t';
1422 1417
      }
1423 1418
      *_os << std::endl;
1424 1419

	
1425 1420
      std::vector<Edge> edges;
1426 1421
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1427 1422
        edges.push_back(n);
1428 1423
      }
1429 1424

	
1430 1425
      if (label == 0) {
1431 1426
        IdMap<Graph, Edge> id_map(_graph);
1432 1427
        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1433 1428
        std::sort(edges.begin(), edges.end(), id_less);
1434 1429
      } else {
1435 1430
        label->sort(edges);
1436 1431
      }
1437 1432

	
1438 1433
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1439 1434
        Edge e = edges[i];
1440 1435
        _writer_bits::writeToken(*_os, _node_index.
1441 1436
                                 find(_graph.u(e))->second);
1442 1437
        *_os << '\t';
1443 1438
        _writer_bits::writeToken(*_os, _node_index.
1444 1439
                                 find(_graph.v(e))->second);
1445 1440
        *_os << '\t';
1446 1441
        if (label == 0) {
1447 1442
          std::ostringstream os;
1448 1443
          os << _graph.id(e);
1449 1444
          _writer_bits::writeToken(*_os, os.str());
1450 1445
          *_os << '\t';
1451 1446
          _edge_index.insert(std::make_pair(e, os.str()));
1452 1447
        }
1453 1448
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1454 1449
             it != _edge_maps.end(); ++it) {
1455 1450
          std::string value = it->second->get(e);
1456 1451
          _writer_bits::writeToken(*_os, value);
1457 1452
          if (it->first == "label") {
1458 1453
            _edge_index.insert(std::make_pair(e, value));
1459 1454
          }
1460 1455
          *_os << '\t';
1461 1456
        }
1462 1457
        *_os << std::endl;
1463 1458
      }
1464 1459
    }
1465 1460

	
1466 1461
    void createEdgeIndex() {
1467 1462
      _writer_bits::MapStorageBase<Edge>* label = 0;
1468 1463
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1469 1464
           it != _edge_maps.end(); ++it) {
1470 1465
        if (it->first == "label") {
1471 1466
          label = it->second;
1472 1467
          break;
1473 1468
        }
1474 1469
      }
1475 1470

	
1476 1471
      if (label == 0) {
1477 1472
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1478 1473
          std::ostringstream os;
1479 1474
          os << _graph.id(e);
1480 1475
          _edge_index.insert(std::make_pair(e, os.str()));
1481 1476
        }
1482 1477
      } else {
1483 1478
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1484 1479
          std::string value = label->get(e);
1485 1480
          _edge_index.insert(std::make_pair(e, value));
1486 1481
        }
1487 1482
      }
1488 1483
    }
1489 1484

	
1490 1485
    void writeAttributes() {
1491 1486
      if (_attributes.empty()) return;
1492 1487
      *_os << "@attributes";
1493 1488
      if (!_attributes_caption.empty()) {
1494 1489
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1495 1490
      }
1496 1491
      *_os << std::endl;
1497 1492
      for (typename Attributes::iterator it = _attributes.begin();
1498 1493
           it != _attributes.end(); ++it) {
1499 1494
        _writer_bits::writeToken(*_os, it->first) << ' ';
1500 1495
        _writer_bits::writeToken(*_os, it->second->get());
1501 1496
        *_os << std::endl;
1502 1497
      }
1503 1498
    }
1504 1499

	
1505 1500
  public:
1506 1501

	
1507 1502
    /// \name Execution of the writer
1508 1503
    /// @{
1509 1504

	
1510 1505
    /// \brief Start the batch processing
1511 1506
    ///
1512 1507
    /// This function starts the batch processing.
1513 1508
    void run() {
1514 1509
      if (!_skip_nodes) {
1515 1510
        writeNodes();
1516 1511
      } else {
1517 1512
        createNodeIndex();
1518 1513
      }
1519 1514
      if (!_skip_edges) {
1520 1515
        writeEdges();
1521 1516
      } else {
1522 1517
        createEdgeIndex();
1523 1518
      }
1524 1519
      writeAttributes();
1525 1520
    }
1526 1521

	
1527 1522
    /// \brief Give back the stream of the writer
1528 1523
    ///
1529 1524
    /// Give back the stream of the writer
1530 1525
    std::ostream& ostream() {
1531 1526
      return *_os;
1532 1527
    }
1533 1528

	
1534 1529
    /// @}
1535 1530
  };
1536 1531

	
1532
  /// \brief Return a \ref GraphWriter class
1533
  ///
1534
  /// This function just returns a \ref GraphWriter class.
1535
  /// \relates GraphWriter
1536
  template <typename Graph>
1537
  GraphWriter<Graph> graphWriter(const Graph& graph,
1538
                                 std::ostream& os) {
1539
    GraphWriter<Graph> tmp(graph, os);
1540
    return tmp;
1541
  }
1542

	
1543
  /// \brief Return a \ref GraphWriter class
1544
  ///
1545
  /// This function just returns a \ref GraphWriter class.
1546
  /// \relates GraphWriter
1547
  template <typename Graph>
1548
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
1549
    GraphWriter<Graph> tmp(graph, fn);
1550
    return tmp;
1551
  }
1552

	
1553
  /// \brief Return a \ref GraphWriter class
1554
  ///
1555
  /// This function just returns a \ref GraphWriter class.
1556
  /// \relates GraphWriter
1557
  template <typename Graph>
1558
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
1559
    GraphWriter<Graph> tmp(graph, fn);
1560
    return tmp;
1561
  }
1562

	
1537 1563
  class SectionWriter;
1538 1564

	
1539 1565
  SectionWriter sectionWriter(std::istream& is);
1540 1566
  SectionWriter sectionWriter(const std::string& fn);
1541 1567
  SectionWriter sectionWriter(const char* fn);
1542 1568

	
1543 1569
  /// \ingroup lemon_io
1544 1570
  ///
1545 1571
  /// \brief Section writer class
1546 1572
  ///
1547 1573
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1548 1574
  /// which contain any data in arbitrary format. Such sections can be
1549 1575
  /// written with this class. A writing rule can be added to the
1550 1576
  /// class with two different functions. With the \c sectionLines()
1551 1577
  /// function a generator can write the section line-by-line, while
1552 1578
  /// with the \c sectionStream() member the section can be written to
1553 1579
  /// an output stream.
1554 1580
  class SectionWriter {
1555 1581
  private:
1556 1582

	
1557 1583
    std::ostream* _os;
1558 1584
    bool local_os;
1559 1585

	
1560 1586
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1561 1587
    Sections;
1562 1588

	
1563 1589
    Sections _sections;
1564 1590

	
1565 1591
  public:
1566 1592

	
1567 1593
    /// \brief Constructor
1568 1594
    ///
1569 1595
    /// Construct a section writer, which writes to the given output
1570 1596
    /// stream.
1571 1597
    SectionWriter(std::ostream& os)
1572 1598
      : _os(&os), local_os(false) {}
1573 1599

	
1574 1600
    /// \brief Constructor
1575 1601
    ///
1576 1602
    /// Construct a section writer, which writes into the given file.
1577 1603
    SectionWriter(const std::string& fn)
1578 1604
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1579 1605
      if (!(*_os)) {
1580 1606
        delete _os;
1581 1607
        throw IoError("Cannot write file", fn);
1582 1608
      }
1583 1609
    }
1584 1610

	
1585 1611
    /// \brief Constructor
1586 1612
    ///
1587 1613
    /// Construct a section writer, which writes into the given file.
1588 1614
    SectionWriter(const char* fn)
1589 1615
      : _os(new std::ofstream(fn)), local_os(true) {
1590 1616
      if (!(*_os)) {
1591 1617
        delete _os;
1592 1618
        throw IoError("Cannot write file", fn);
1593 1619
      }
1594 1620
    }
1595 1621

	
1596 1622
    /// \brief Destructor
1597 1623
    ~SectionWriter() {
1598 1624
      for (Sections::iterator it = _sections.begin();
1599 1625
           it != _sections.end(); ++it) {
1600 1626
        delete it->second;
1601 1627
      }
1602 1628

	
1603 1629
      if (local_os) {
1604 1630
        delete _os;
1605 1631
      }
1606 1632

	
1607 1633
    }
1608 1634

	
1609 1635
  private:
1610 1636

	
1611 1637
    friend SectionWriter sectionWriter(std::ostream& os);
1612 1638
    friend SectionWriter sectionWriter(const std::string& fn);
1613 1639
    friend SectionWriter sectionWriter(const char* fn);
1614 1640

	
1615 1641
    SectionWriter(SectionWriter& other)
1616 1642
      : _os(other._os), local_os(other.local_os) {
1617 1643

	
1618 1644
      other._os = 0;
1619 1645
      other.local_os = false;
1620 1646

	
1621 1647
      _sections.swap(other._sections);
1622 1648
    }
1623 1649

	
1624 1650
    SectionWriter& operator=(const SectionWriter&);
1625 1651

	
1626 1652
  public:
1627 1653

	
1628 1654
    /// \name Section writers
1629 1655
    /// @{
1630 1656

	
1631 1657
    /// \brief Add a section writer with line oriented writing
1632 1658
    ///
1633 1659
    /// The first parameter is the type descriptor of the section, the
1634 1660
    /// second is a generator with std::string values. At the writing
1635 1661
    /// process, the returned \c std::string will be written into the
1636 1662
    /// output file until it is an empty string.
1637 1663
    ///
1638 1664
    /// For example, an integer vector is written into a section.
1639 1665
    ///\code
1640 1666
    ///  @numbers
1641 1667
    ///  12 45 23 78
1642 1668
    ///  4 28 38 28
1643 1669
    ///  23 6 16
1644 1670
    ///\endcode
1645 1671
    ///
1646 1672
    /// The generator is implemented as a struct.
1647 1673
    ///\code
1648 1674
    ///  struct NumberSection {
1649 1675
    ///    std::vector<int>::const_iterator _it, _end;
1650 1676
    ///    NumberSection(const std::vector<int>& data)
1651 1677
    ///      : _it(data.begin()), _end(data.end()) {}
1652 1678
    ///    std::string operator()() {
1653 1679
    ///      int rem_in_line = 4;
1654 1680
    ///      std::ostringstream ls;
1655 1681
    ///      while (rem_in_line > 0 && _it != _end) {
1656 1682
    ///        ls << *(_it++) << ' ';
1657 1683
    ///        --rem_in_line;
1658 1684
    ///      }
1659 1685
    ///      return ls.str();
1660 1686
    ///    }
1661 1687
    ///  };
1662 1688
    ///
1663 1689
    ///  // ...
1664 1690
    ///
1665 1691
    ///  writer.sectionLines("numbers", NumberSection(vec));
1666 1692
    ///\endcode
1667 1693
    template <typename Functor>
1668 1694
    SectionWriter& sectionLines(const std::string& type, Functor functor) {
1669 1695
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1670 1696
      _sections.push_back(std::make_pair(type,
1671 1697
        new _writer_bits::LineSection<Functor>(functor)));
1672 1698
      return *this;
1673 1699
    }
1674 1700

	
1675 1701

	
1676 1702
    /// \brief Add a section writer with stream oriented writing
1677 1703
    ///
1678 1704
    /// The first parameter is the type of the section, the second is
1679 1705
    /// a functor, which takes a \c std::ostream& parameter. The
1680 1706
    /// functor writes the section to the output stream.
1681 1707
    /// \warning The last line must be closed with end-line character.
1682 1708
    template <typename Functor>
1683 1709
    SectionWriter& sectionStream(const std::string& type, Functor functor) {
1684 1710
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1685 1711
      _sections.push_back(std::make_pair(type,
1686 1712
         new _writer_bits::StreamSection<Functor>(functor)));
1687 1713
      return *this;
1688 1714
    }
1689 1715

	
1690 1716
    /// @}
1691 1717

	
1692 1718
  public:
1693 1719

	
1694 1720

	
1695 1721
    /// \name Execution of the writer
1696 1722
    /// @{
1697 1723

	
1698 1724
    /// \brief Start the batch processing
1699 1725
    ///
1700 1726
    /// This function starts the batch processing.
1701 1727
    void run() {
1702 1728

	
1703 1729
      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
1704 1730

	
1705 1731
      for (Sections::iterator it = _sections.begin();
1706 1732
           it != _sections.end(); ++it) {
1707 1733
        (*_os) << '@' << it->first << std::endl;
1708 1734
        it->second->process(*_os);
1709 1735
      }
1710 1736
    }
1711 1737

	
1712 1738
    /// \brief Give back the stream of the writer
1713 1739
    ///
1714 1740
    /// Returns the stream of the writer
1715 1741
    std::ostream& ostream() {
1716 1742
      return *_os;
1717 1743
    }
1718 1744

	
1719 1745
    /// @}
1720 1746

	
1721 1747
  };
1722 1748

	
1723 1749
  /// \brief Return a \ref SectionWriter class
1724 1750
  ///
1725 1751
  /// This function just returns a \ref SectionWriter class.
1726 1752
  /// \relates SectionWriter
1727 1753
  inline SectionWriter sectionWriter(std::ostream& os) {
1728 1754
    SectionWriter tmp(os);
1729 1755
    return tmp;
1730 1756
  }
1731 1757

	
1732 1758
  /// \brief Return a \ref SectionWriter class
1733 1759
  ///
1734 1760
  /// This function just returns a \ref SectionWriter class.
1735 1761
  /// \relates SectionWriter
1736 1762
  inline SectionWriter sectionWriter(const std::string& fn) {
1737 1763
    SectionWriter tmp(fn);
1738 1764
    return tmp;
1739 1765
  }
1740 1766

	
1741 1767
  /// \brief Return a \ref SectionWriter class
1742 1768
  ///
1743 1769
  /// This function just returns a \ref SectionWriter class.
1744 1770
  /// \relates SectionWriter
1745 1771
  inline SectionWriter sectionWriter(const char* fn) {
1746 1772
    SectionWriter tmp(fn);
1747 1773
    return tmp;
1748 1774
  }
1749 1775
}
1750 1776

	
1751 1777
#endif
Ignore white space 6 line context
... ...
@@ -676,411 +676,427 @@
676 676
          if (tpath.first) {
677 677
            last->next = tpath.first;
678 678
            tpath.first->prev = last;
679 679
            last = tpath.last;
680 680
          }
681 681
        } else {
682 682
          first = tpath.first;
683 683
          last = tpath.last;
684 684
        }
685 685
      }
686 686
      tpath.first = tpath.last = 0;
687 687
    }
688 688

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

	
713 713

	
714 714
    typedef True BuildTag;
715 715

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

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

	
730 730
  };
731 731

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

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

	
756 756
    /// \brief Default constructor
757 757
    ///
758 758
    /// Default constructor
759 759
    StaticPath() : len(0), arcs(0) {}
760 760

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

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

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

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

	
802 802
    private:
803 803

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

	
808 808
    public:
809 809

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

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

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

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

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

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

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

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

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

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

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

	
869 869

	
870 870
    typedef True BuildTag;
871 871

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

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

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

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

	
903 903
  namespace _path_bits {
904 904

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

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

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

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

	
931 931
    template <typename Target, typename Source,
932
              bool buildEnable = BuildTagIndicator<Target>::value,
933
              bool revEnable = RevPathTagIndicator<Source>::value>
934
    struct PathCopySelector {
932
              bool buildEnable = BuildTagIndicator<Target>::value>
933
    struct PathCopySelectorForward {
935 934
      static void copy(Target& target, const Source& source) {
936 935
        target.clear();
937 936
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
938 937
          target.addBack(it);
939 938
        }
940 939
      }
941 940
    };
942 941

	
943 942
    template <typename Target, typename Source>
944
    struct PathCopySelector<Target, Source, false, true> {
943
    struct PathCopySelectorForward<Target, Source, true> {
944
      static void copy(Target& target, const Source& source) {
945
        target.clear();
946
        target.build(source);
947
      }
948
    };
949

	
950
    template <typename Target, typename Source,
951
              bool buildEnable = BuildTagIndicator<Target>::value>
952
    struct PathCopySelectorBackward {
945 953
      static void copy(Target& target, const Source& source) {
946 954
        target.clear();
947 955
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
948 956
          target.addFront(it);
949 957
        }
950 958
      }
951 959
    };
952 960

	
953 961
    template <typename Target, typename Source>
954
    struct PathCopySelector<Target, Source, true, false> {
955
      static void copy(Target& target, const Source& source) {
956
        target.clear();
957
        target.build(source);
958
      }
959
    };
960

	
961
    template <typename Target, typename Source>
962
    struct PathCopySelector<Target, Source, true, true> {
962
    struct PathCopySelectorBackward<Target, Source, true> {
963 963
      static void copy(Target& target, const Source& source) {
964 964
        target.clear();
965 965
        target.buildRev(source);
966 966
      }
967 967
    };
968 968

	
969
    
970
    template <typename Target, typename Source,
971
              bool revEnable = RevPathTagIndicator<Source>::value>
972
    struct PathCopySelector {
973
      static void copy(Target& target, const Source& source) {
974
        PathCopySelectorForward<Target, Source>::copy(target, source);
975
      }      
976
    };
977

	
978
    template <typename Target, typename Source>
979
    struct PathCopySelector<Target, Source, true> {
980
      static void copy(Target& target, const Source& source) {
981
        PathCopySelectorBackward<Target, Source>::copy(target, source);
982
      }      
983
    };
984

	
969 985
  }
970 986

	
971 987

	
972 988
  /// \brief Make a copy of a path.
973 989
  ///
974 990
  ///  This function makes a copy of a path.
975 991
  template <typename Target, typename Source>
976 992
  void copyPath(Target& target, const Source& source) {
977 993
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
978 994
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
979 995
  }
980 996

	
981 997
  /// \brief Check the consistency of a path.
982 998
  ///
983 999
  /// This function checks that the target of each arc is the same
984 1000
  /// as the source of the next one.
985 1001
  ///
986 1002
  template <typename Digraph, typename Path>
987 1003
  bool checkPath(const Digraph& digraph, const Path& path) {
988 1004
    typename Path::ArcIt it(path);
989 1005
    if (it == INVALID) return true;
990 1006
    typename Digraph::Node node = digraph.target(it);
991 1007
    ++it;
992 1008
    while (it != INVALID) {
993 1009
      if (digraph.source(it) != node) return false;
994 1010
      node = digraph.target(it);
995 1011
      ++it;
996 1012
    }
997 1013
    return true;
998 1014
  }
999 1015

	
1000 1016
  /// \brief The source of a path
1001 1017
  ///
1002 1018
  /// This function returns the source of the given path.
1003 1019
  template <typename Digraph, typename Path>
1004 1020
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1005 1021
    return digraph.source(path.front());
1006 1022
  }
1007 1023

	
1008 1024
  /// \brief The target of a path
1009 1025
  ///
1010 1026
  /// This function returns the target of the given path.
1011 1027
  template <typename Digraph, typename Path>
1012 1028
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1013 1029
    return digraph.target(path.back());
1014 1030
  }
1015 1031

	
1016 1032
  /// \brief Class which helps to iterate through the nodes of a path
1017 1033
  ///
1018 1034
  /// In a sense, the path can be treated as a list of arcs. The
1019 1035
  /// lemon path type stores only this list. As a consequence, it
1020 1036
  /// cannot enumerate the nodes in the path and the zero length paths
1021 1037
  /// cannot have a source node.
1022 1038
  ///
1023 1039
  /// This class implements the node iterator of a path structure. To
1024 1040
  /// provide this feature, the underlying digraph should be passed to
1025 1041
  /// the constructor of the iterator.
1026 1042
  template <typename Path>
1027 1043
  class PathNodeIt {
1028 1044
  private:
1029 1045
    const typename Path::Digraph *_digraph;
1030 1046
    typename Path::ArcIt _it;
1031 1047
    typename Path::Digraph::Node _nd;
1032 1048

	
1033 1049
  public:
1034 1050

	
1035 1051
    typedef typename Path::Digraph Digraph;
1036 1052
    typedef typename Digraph::Node Node;
1037 1053

	
1038 1054
    /// Default constructor
1039 1055
    PathNodeIt() {}
1040 1056
    /// Invalid constructor
1041 1057
    PathNodeIt(Invalid)
1042 1058
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1043 1059
    /// Constructor
1044 1060
    PathNodeIt(const Digraph& digraph, const Path& path)
1045 1061
      : _digraph(&digraph), _it(path) {
1046 1062
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1047 1063
    }
1048 1064
    /// Constructor
1049 1065
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1050 1066
      : _digraph(&digraph), _it(path), _nd(src) {}
1051 1067

	
1052 1068
    ///Conversion to Digraph::Node
1053 1069
    operator Node() const {
1054 1070
      return _nd;
1055 1071
    }
1056 1072

	
1057 1073
    /// Next node
1058 1074
    PathNodeIt& operator++() {
1059 1075
      if (_it == INVALID) _nd = INVALID;
1060 1076
      else {
1061 1077
        _nd = _digraph->target(_it);
1062 1078
        ++_it;
1063 1079
      }
1064 1080
      return *this;
1065 1081
    }
1066 1082

	
1067 1083
    /// Comparison operator
1068 1084
    bool operator==(const PathNodeIt& n) const {
1069 1085
      return _it == n._it && _nd == n._nd;
1070 1086
    }
1071 1087
    /// Comparison operator
1072 1088
    bool operator!=(const PathNodeIt& n) const {
1073 1089
      return _it != n._it || _nd != n._nd;
1074 1090
    }
1075 1091
    /// Comparison operator
1076 1092
    bool operator<(const PathNodeIt& n) const {
1077 1093
      return (_it < n._it && _nd != INVALID);
1078 1094
    }
1079 1095

	
1080 1096
  };
1081 1097

	
1082 1098
  ///@}
1083 1099

	
1084 1100
} // namespace lemon
1085 1101

	
1086 1102
#endif // LEMON_PATH_H
Ignore white space 512 line context
... ...
@@ -91,592 +91,582 @@
91 91
    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
92 92
    struct RandomTraits {};
93 93

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

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

	
100 100
      static const int length = 624;
101 101
      static const int shift = 397;
102 102

	
103 103
      static const Word mul = 0x6c078965u;
104 104
      static const Word arrayInit = 0x012BD6AAu;
105 105
      static const Word arrayMul1 = 0x0019660Du;
106 106
      static const Word arrayMul2 = 0x5D588B65u;
107 107

	
108 108
      static const Word mask = 0x9908B0DFu;
109 109
      static const Word loMask = (1u << 31) - 1;
110 110
      static const Word hiMask = ~loMask;
111 111

	
112 112

	
113 113
      static Word tempering(Word rnd) {
114 114
        rnd ^= (rnd >> 11);
115 115
        rnd ^= (rnd << 7) & 0x9D2C5680u;
116 116
        rnd ^= (rnd << 15) & 0xEFC60000u;
117 117
        rnd ^= (rnd >> 18);
118 118
        return rnd;
119 119
      }
120 120

	
121 121
    };
122 122

	
123 123
    template <typename _Word>
124 124
    struct RandomTraits<_Word, 64> {
125 125

	
126 126
      typedef _Word Word;
127 127
      static const int bits = 64;
128 128

	
129 129
      static const int length = 312;
130 130
      static const int shift = 156;
131 131

	
132 132
      static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
133 133
      static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
134 134
      static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
135 135
      static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
136 136

	
137 137
      static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
138 138
      static const Word loMask = (Word(1u) << 31) - 1;
139 139
      static const Word hiMask = ~loMask;
140 140

	
141 141
      static Word tempering(Word rnd) {
142 142
        rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
143 143
        rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
144 144
        rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
145 145
        rnd ^= (rnd >> 43);
146 146
        return rnd;
147 147
      }
148 148

	
149 149
    };
150 150

	
151 151
    template <typename _Word>
152 152
    class RandomCore {
153 153
    public:
154 154

	
155 155
      typedef _Word Word;
156 156

	
157 157
    private:
158 158

	
159 159
      static const int bits = RandomTraits<Word>::bits;
160 160

	
161 161
      static const int length = RandomTraits<Word>::length;
162 162
      static const int shift = RandomTraits<Word>::shift;
163 163

	
164 164
    public:
165 165

	
166 166
      void initState() {
167 167
        static const Word seedArray[4] = {
168 168
          0x12345u, 0x23456u, 0x34567u, 0x45678u
169 169
        };
170 170

	
171 171
        initState(seedArray, seedArray + 4);
172 172
      }
173 173

	
174 174
      void initState(Word seed) {
175 175

	
176 176
        static const Word mul = RandomTraits<Word>::mul;
177 177

	
178 178
        current = state;
179 179

	
180 180
        Word *curr = state + length - 1;
181 181
        curr[0] = seed; --curr;
182 182
        for (int i = 1; i < length; ++i) {
183 183
          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
184 184
          --curr;
185 185
        }
186 186
      }
187 187

	
188 188
      template <typename Iterator>
189 189
      void initState(Iterator begin, Iterator end) {
190 190

	
191 191
        static const Word init = RandomTraits<Word>::arrayInit;
192 192
        static const Word mul1 = RandomTraits<Word>::arrayMul1;
193 193
        static const Word mul2 = RandomTraits<Word>::arrayMul2;
194 194

	
195 195

	
196 196
        Word *curr = state + length - 1; --curr;
197 197
        Iterator it = begin; int cnt = 0;
198 198
        int num;
199 199

	
200 200
        initState(init);
201 201

	
202 202
        num = length > end - begin ? length : end - begin;
203 203
        while (num--) {
204 204
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
205 205
            + *it + cnt;
206 206
          ++it; ++cnt;
207 207
          if (it == end) {
208 208
            it = begin; cnt = 0;
209 209
          }
210 210
          if (curr == state) {
211 211
            curr = state + length - 1; curr[0] = state[0];
212 212
          }
213 213
          --curr;
214 214
        }
215 215

	
216 216
        num = length - 1; cnt = length - (curr - state) - 1;
217 217
        while (num--) {
218 218
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
219 219
            - cnt;
220 220
          --curr; ++cnt;
221 221
          if (curr == state) {
222 222
            curr = state + length - 1; curr[0] = state[0]; --curr;
223 223
            cnt = 1;
224 224
          }
225 225
        }
226 226

	
227 227
        state[length - 1] = Word(1) << (bits - 1);
228 228
      }
229 229

	
230 230
      void copyState(const RandomCore& other) {
231 231
        std::copy(other.state, other.state + length, state);
232 232
        current = state + (other.current - other.state);
233 233
      }
234 234

	
235 235
      Word operator()() {
236 236
        if (current == state) fillState();
237 237
        --current;
238 238
        Word rnd = *current;
239 239
        return RandomTraits<Word>::tempering(rnd);
240 240
      }
241 241

	
242 242
    private:
243 243

	
244 244

	
245 245
      void fillState() {
246 246
        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
247 247
        static const Word loMask = RandomTraits<Word>::loMask;
248 248
        static const Word hiMask = RandomTraits<Word>::hiMask;
249 249

	
250 250
        current = state + length;
251 251

	
252 252
        register Word *curr = state + length - 1;
253 253
        register long num;
254 254

	
255 255
        num = length - shift;
256 256
        while (num--) {
257 257
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
258 258
            curr[- shift] ^ mask[curr[-1] & 1ul];
259 259
          --curr;
260 260
        }
261 261
        num = shift - 1;
262 262
        while (num--) {
263 263
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
264 264
            curr[length - shift] ^ mask[curr[-1] & 1ul];
265 265
          --curr;
266 266
        }
267 267
        state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
268 268
          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
269 269

	
270 270
      }
271 271

	
272 272

	
273 273
      Word *current;
274 274
      Word state[length];
275 275

	
276 276
    };
277 277

	
278 278

	
279 279
    template <typename Result,
280 280
              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
281 281
    struct Masker {
282 282
      static Result mask(const Result& result) {
283 283
        return Masker<Result, (shift + 1) / 2>::
284 284
          mask(static_cast<Result>(result | (result >> shift)));
285 285
      }
286 286
    };
287 287

	
288 288
    template <typename Result>
289 289
    struct Masker<Result, 1> {
290 290
      static Result mask(const Result& result) {
291 291
        return static_cast<Result>(result | (result >> 1));
292 292
      }
293 293
    };
294 294

	
295 295
    template <typename Result, typename Word,
296 296
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
297 297
              bool last = rest <= std::numeric_limits<Word>::digits>
298 298
    struct IntConversion {
299 299
      static const int bits = std::numeric_limits<Word>::digits;
300 300

	
301 301
      static Result convert(RandomCore<Word>& rnd) {
302 302
        return static_cast<Result>(rnd() >> (bits - rest)) << shift;
303 303
      }
304 304

	
305 305
    };
306 306

	
307 307
    template <typename Result, typename Word, int rest, int shift>
308 308
    struct IntConversion<Result, Word, rest, shift, false> {
309 309
      static const int bits = std::numeric_limits<Word>::digits;
310 310

	
311 311
      static Result convert(RandomCore<Word>& rnd) {
312 312
        return (static_cast<Result>(rnd()) << shift) |
313 313
          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
314 314
      }
315 315
    };
316 316

	
317 317

	
318 318
    template <typename Result, typename Word,
319 319
              bool one_word = (std::numeric_limits<Word>::digits <
320 320
                               std::numeric_limits<Result>::digits) >
321 321
    struct Mapping {
322 322
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
323 323
        Word max = Word(bound - 1);
324 324
        Result mask = Masker<Result>::mask(bound - 1);
325 325
        Result num;
326 326
        do {
327 327
          num = IntConversion<Result, Word>::convert(rnd) & mask;
328 328
        } while (num > max);
329 329
        return num;
330 330
      }
331 331
    };
332 332

	
333 333
    template <typename Result, typename Word>
334 334
    struct Mapping<Result, Word, false> {
335 335
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
336 336
        Word max = Word(bound - 1);
337 337
        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
338 338
          ::mask(max);
339 339
        Word num;
340 340
        do {
341 341
          num = rnd() & mask;
342 342
        } while (num > max);
343 343
        return num;
344 344
      }
345 345
    };
346 346

	
347
    template <typename Result, int exp, bool pos = (exp >= 0)>
347
    template <typename Result, int exp>
348 348
    struct ShiftMultiplier {
349 349
      static const Result multiplier() {
350 350
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
351 351
        res *= res;
352
        if ((exp & 1) == 1) res *= static_cast<Result>(2.0);
353
        return res;
354
      }
355
    };
356

	
357
    template <typename Result, int exp>
358
    struct ShiftMultiplier<Result, exp, false> {
359
      static const Result multiplier() {
360
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
361
        res *= res;
362 352
        if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
363 353
        return res;
364 354
      }
365 355
    };
366 356

	
367 357
    template <typename Result>
368
    struct ShiftMultiplier<Result, 0, true> {
358
    struct ShiftMultiplier<Result, 0> {
369 359
      static const Result multiplier() {
370 360
        return static_cast<Result>(1.0);
371 361
      }
372 362
    };
373 363

	
374 364
    template <typename Result>
375
    struct ShiftMultiplier<Result, -20, true> {
365
    struct ShiftMultiplier<Result, 20> {
376 366
      static const Result multiplier() {
377 367
        return static_cast<Result>(1.0/1048576.0);
378 368
      }
379 369
    };
380 370

	
381 371
    template <typename Result>
382
    struct ShiftMultiplier<Result, -32, true> {
372
    struct ShiftMultiplier<Result, 32> {
383 373
      static const Result multiplier() {
384
        return static_cast<Result>(1.0/424967296.0);
374
        return static_cast<Result>(1.0/4294967296.0);
385 375
      }
386 376
    };
387 377

	
388 378
    template <typename Result>
389
    struct ShiftMultiplier<Result, -53, true> {
379
    struct ShiftMultiplier<Result, 53> {
390 380
      static const Result multiplier() {
391 381
        return static_cast<Result>(1.0/9007199254740992.0);
392 382
      }
393 383
    };
394 384

	
395 385
    template <typename Result>
396
    struct ShiftMultiplier<Result, -64, true> {
386
    struct ShiftMultiplier<Result, 64> {
397 387
      static const Result multiplier() {
398 388
        return static_cast<Result>(1.0/18446744073709551616.0);
399 389
      }
400 390
    };
401 391

	
402 392
    template <typename Result, int exp>
403 393
    struct Shifting {
404 394
      static Result shift(const Result& result) {
405 395
        return result * ShiftMultiplier<Result, exp>::multiplier();
406 396
      }
407 397
    };
408 398

	
409 399
    template <typename Result, typename Word,
410 400
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
411 401
              bool last = rest <= std::numeric_limits<Word>::digits>
412 402
    struct RealConversion{
413 403
      static const int bits = std::numeric_limits<Word>::digits;
414 404

	
415 405
      static Result convert(RandomCore<Word>& rnd) {
416
        return Shifting<Result, - shift - rest>::
406
        return Shifting<Result, shift + rest>::
417 407
          shift(static_cast<Result>(rnd() >> (bits - rest)));
418 408
      }
419 409
    };
420 410

	
421 411
    template <typename Result, typename Word, int rest, int shift>
422 412
    struct RealConversion<Result, Word, rest, shift, false> {
423 413
      static const int bits = std::numeric_limits<Word>::digits;
424 414

	
425 415
      static Result convert(RandomCore<Word>& rnd) {
426
        return Shifting<Result, - shift - bits>::
416
        return Shifting<Result, shift + bits>::
427 417
          shift(static_cast<Result>(rnd())) +
428 418
          RealConversion<Result, Word, rest-bits, shift + bits>::
429 419
          convert(rnd);
430 420
      }
431 421
    };
432 422

	
433 423
    template <typename Result, typename Word>
434 424
    struct Initializer {
435 425

	
436 426
      template <typename Iterator>
437 427
      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
438 428
        std::vector<Word> ws;
439 429
        for (Iterator it = begin; it != end; ++it) {
440 430
          ws.push_back(Word(*it));
441 431
        }
442 432
        rnd.initState(ws.begin(), ws.end());
443 433
      }
444 434

	
445 435
      static void init(RandomCore<Word>& rnd, Result seed) {
446 436
        rnd.initState(seed);
447 437
      }
448 438
    };
449 439

	
450 440
    template <typename Word>
451 441
    struct BoolConversion {
452 442
      static bool convert(RandomCore<Word>& rnd) {
453 443
        return (rnd() & 1) == 1;
454 444
      }
455 445
    };
456 446

	
457 447
    template <typename Word>
458 448
    struct BoolProducer {
459 449
      Word buffer;
460 450
      int num;
461 451

	
462 452
      BoolProducer() : num(0) {}
463 453

	
464 454
      bool convert(RandomCore<Word>& rnd) {
465 455
        if (num == 0) {
466 456
          buffer = rnd();
467 457
          num = RandomTraits<Word>::bits;
468 458
        }
469 459
        bool r = (buffer & 1);
470 460
        buffer >>= 1;
471 461
        --num;
472 462
        return r;
473 463
      }
474 464
    };
475 465

	
476 466
  }
477 467

	
478 468
  /// \ingroup misc
479 469
  ///
480 470
  /// \brief Mersenne Twister random number generator
481 471
  ///
482 472
  /// The Mersenne Twister is a twisted generalized feedback
483 473
  /// shift-register generator of Matsumoto and Nishimura. The period
484 474
  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
485 475
  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
486 476
  /// performance of this generator is comparable to the commonly used
487 477
  /// generators.
488 478
  ///
489 479
  /// This implementation is specialized for both 32-bit and 64-bit
490 480
  /// architectures. The generators differ sligthly in the
491 481
  /// initialization and generation phase so they produce two
492 482
  /// completly different sequences.
493 483
  ///
494 484
  /// The generator gives back random numbers of serveral types. To
495 485
  /// get a random number from a range of a floating point type you
496 486
  /// can use one form of the \c operator() or the \c real() member
497 487
  /// function. If you want to get random number from the {0, 1, ...,
498 488
  /// n-1} integer range use the \c operator[] or the \c integer()
499 489
  /// method. And to get random number from the whole range of an
500 490
  /// integer type you can use the argumentless \c integer() or \c
501 491
  /// uinteger() functions. After all you can get random bool with
502 492
  /// equal chance of true and false or given probability of true
503 493
  /// result with the \c boolean() member functions.
504 494
  ///
505 495
  ///\code
506 496
  /// // The commented code is identical to the other
507 497
  /// double a = rnd();                     // [0.0, 1.0)
508 498
  /// // double a = rnd.real();             // [0.0, 1.0)
509 499
  /// double b = rnd(100.0);                // [0.0, 100.0)
510 500
  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
511 501
  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
512 502
  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
513 503
  /// int d = rnd[100000];                  // 0..99999
514 504
  /// // int d = rnd.integer(100000);       // 0..99999
515 505
  /// int e = rnd[6] + 1;                   // 1..6
516 506
  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
517 507
  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
518 508
  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
519 509
  /// bool g = rnd.boolean();               // P(g = true) = 0.5
520 510
  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
521 511
  ///\endcode
522 512
  ///
523 513
  /// LEMON provides a global instance of the random number
524 514
  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
525 515
  /// good programming convenience to use this global generator to get
526 516
  /// random numbers.
527 517
  class Random {
528 518
  private:
529 519

	
530 520
    // Architecture word
531 521
    typedef unsigned long Word;
532 522

	
533 523
    _random_bits::RandomCore<Word> core;
534 524
    _random_bits::BoolProducer<Word> bool_producer;
535 525

	
536 526

	
537 527
  public:
538 528

	
539 529
    ///\name Initialization
540 530
    ///
541 531
    /// @{
542 532

	
543 533
    ///\name Initialization
544 534
    ///
545 535
    /// @{
546 536

	
547 537
    /// \brief Default constructor
548 538
    ///
549 539
    /// Constructor with constant seeding.
550 540
    Random() { core.initState(); }
551 541

	
552 542
    /// \brief Constructor with seed
553 543
    ///
554 544
    /// Constructor with seed. The current number type will be converted
555 545
    /// to the architecture word type.
556 546
    template <typename Number>
557 547
    Random(Number seed) {
558 548
      _random_bits::Initializer<Number, Word>::init(core, seed);
559 549
    }
560 550

	
561 551
    /// \brief Constructor with array seeding
562 552
    ///
563 553
    /// Constructor with array seeding. The given range should contain
564 554
    /// any number type and the numbers will be converted to the
565 555
    /// architecture word type.
566 556
    template <typename Iterator>
567 557
    Random(Iterator begin, Iterator end) {
568 558
      typedef typename std::iterator_traits<Iterator>::value_type Number;
569 559
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
570 560
    }
571 561

	
572 562
    /// \brief Copy constructor
573 563
    ///
574 564
    /// Copy constructor. The generated sequence will be identical to
575 565
    /// the other sequence. It can be used to save the current state
576 566
    /// of the generator and later use it to generate the same
577 567
    /// sequence.
578 568
    Random(const Random& other) {
579 569
      core.copyState(other.core);
580 570
    }
581 571

	
582 572
    /// \brief Assign operator
583 573
    ///
584 574
    /// Assign operator. The generated sequence will be identical to
585 575
    /// the other sequence. It can be used to save the current state
586 576
    /// of the generator and later use it to generate the same
587 577
    /// sequence.
588 578
    Random& operator=(const Random& other) {
589 579
      if (&other != this) {
590 580
        core.copyState(other.core);
591 581
      }
592 582
      return *this;
593 583
    }
594 584

	
595 585
    /// \brief Seeding random sequence
596 586
    ///
597 587
    /// Seeding the random sequence. The current number type will be
598 588
    /// converted to the architecture word type.
599 589
    template <typename Number>
600 590
    void seed(Number seed) {
601 591
      _random_bits::Initializer<Number, Word>::init(core, seed);
602 592
    }
603 593

	
604 594
    /// \brief Seeding random sequence
605 595
    ///
606 596
    /// Seeding the random sequence. The given range should contain
607 597
    /// any number type and the numbers will be converted to the
608 598
    /// architecture word type.
609 599
    template <typename Iterator>
610 600
    void seed(Iterator begin, Iterator end) {
611 601
      typedef typename std::iterator_traits<Iterator>::value_type Number;
612 602
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
613 603
    }
614 604

	
615 605
    /// \brief Seeding from file or from process id and time
616 606
    ///
617 607
    /// By default, this function calls the \c seedFromFile() member
618 608
    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
619 609
    /// it uses the \c seedFromTime().
620 610
    /// \return Currently always true.
621 611
    bool seed() {
622 612
#ifndef WIN32
623 613
      if (seedFromFile("/dev/urandom", 0)) return true;
624 614
#endif
625 615
      if (seedFromTime()) return true;
626 616
      return false;
627 617
    }
628 618

	
629 619
    /// \brief Seeding from file
630 620
    ///
631 621
    /// Seeding the random sequence from file. The linux kernel has two
632 622
    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
633 623
    /// could give good seed values for pseudo random generators (The
634 624
    /// difference between two devices is that the <tt>random</tt> may
635 625
    /// block the reading operation while the kernel can give good
636 626
    /// source of randomness, while the <tt>urandom</tt> does not
637 627
    /// block the input, but it could give back bytes with worse
638 628
    /// entropy).
639 629
    /// \param file The source file
640 630
    /// \param offset The offset, from the file read.
641 631
    /// \return True when the seeding successes.
642 632
#ifndef WIN32
643 633
    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
644 634
#else
645 635
    bool seedFromFile(const std::string& file = "", int offset = 0)
646 636
#endif
647 637
    {
648 638
      std::ifstream rs(file.c_str());
649 639
      const int size = 4;
650 640
      Word buf[size];
651 641
      if (offset != 0 && !rs.seekg(offset)) return false;
652 642
      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
653 643
      seed(buf, buf + size);
654 644
      return true;
655 645
    }
656 646

	
657 647
    /// \brief Seding from process id and time
658 648
    ///
659 649
    /// Seding from process id and time. This function uses the
660 650
    /// current process id and the current time for initialize the
661 651
    /// random sequence.
662 652
    /// \return Currently always true.
663 653
    bool seedFromTime() {
664 654
#ifndef WIN32
665 655
      timeval tv;
666 656
      gettimeofday(&tv, 0);
667 657
      seed(getpid() + tv.tv_sec + tv.tv_usec);
668 658
#else
669 659
      seed(bits::getWinRndSeed());
670 660
#endif
671 661
      return true;
672 662
    }
673 663

	
674 664
    /// @}
675 665

	
676 666
    ///\name Uniform distributions
677 667
    ///
678 668
    /// @{
679 669

	
680 670
    /// \brief Returns a random real number from the range [0, 1)
681 671
    ///
682 672
    /// It returns a random real number from the range [0, 1). The
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 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_TOLERANCE_H
20 20
#define LEMON_TOLERANCE_H
21 21

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

	
28 28
namespace lemon {
29 29

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

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

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

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

	
64 61
    ///@{
65 62

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

	
77 74
    ///@}
78 75

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

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

	
87 84

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

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

	
102 99
    ///Constructor setting the epsilon tolerance to the default value.
103 100
    Tolerance() : _epsilon(def_epsilon) {}
104 101
    ///Constructor setting the epsilon tolerance to the given value.
105 102
    Tolerance(float e) : _epsilon(e) {}
106 103

	
107 104
    ///Returns the epsilon value.
108 105
    Value epsilon() const {return _epsilon;}
109 106
    ///Sets the epsilon value.
110 107
    void epsilon(Value e) {_epsilon=e;}
111 108

	
112 109
    ///Returns the default epsilon value.
113 110
    static Value defaultEpsilon() {return def_epsilon;}
114 111
    ///Sets the default epsilon value.
115 112
    static void defaultEpsilon(Value e) {def_epsilon=e;}
116 113

	
117 114
    ///\name Comparisons
118 115
    ///See \ref lemon::Tolerance "Tolerance" for more details.
119 116

	
120 117
    ///@{
121 118

	
122 119
    ///Returns \c true if \c a is \e surely strictly less than \c b
123 120
    bool less(Value a,Value b) const {return a+_epsilon<b;}
124 121
    ///Returns \c true if \c a is \e surely different from \c b
125 122
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
126 123
    ///Returns \c true if \c a is \e surely positive
127 124
    bool positive(Value a) const { return _epsilon<a; }
128 125
    ///Returns \c true if \c a is \e surely negative
129 126
    bool negative(Value a) const { return -_epsilon>a; }
130 127
    ///Returns \c true if \c a is \e surely non-zero
131 128
    bool nonZero(Value a) const { return positive(a)||negative(a); }
132 129

	
133 130
    ///@}
134 131

	
135 132
    ///Returns zero
136 133
    static Value zero() {return 0;}
137 134
  };
138 135

	
139 136
  ///Double specialization of Tolerance.
140 137

	
141 138
  ///Double specialization of Tolerance.
142 139
  ///\sa Tolerance
143 140
  ///\relates Tolerance
144 141
  template<>
145 142
  class Tolerance<double>
146 143
  {
147 144
    static double def_epsilon;
148 145
    double _epsilon;
149 146
  public:
150 147
    ///\e
151 148
    typedef double Value;
152 149

	
153 150
    ///Constructor setting the epsilon tolerance to the default value.
154 151
    Tolerance() : _epsilon(def_epsilon) {}
155 152
    ///Constructor setting the epsilon tolerance to the given value.
156 153
    Tolerance(double e) : _epsilon(e) {}
157 154

	
158 155
    ///Returns the epsilon value.
159 156
    Value epsilon() const {return _epsilon;}
160 157
    ///Sets the epsilon value.
161 158
    void epsilon(Value e) {_epsilon=e;}
162 159

	
163 160
    ///Returns the default epsilon value.
164 161
    static Value defaultEpsilon() {return def_epsilon;}
165 162
    ///Sets the default epsilon value.
166 163
    static void defaultEpsilon(Value e) {def_epsilon=e;}
167 164

	
168 165
    ///\name Comparisons
169 166
    ///See \ref lemon::Tolerance "Tolerance" for more details.
170 167

	
171 168
    ///@{
172 169

	
173 170
    ///Returns \c true if \c a is \e surely strictly less than \c b
174 171
    bool less(Value a,Value b) const {return a+_epsilon<b;}
175 172
    ///Returns \c true if \c a is \e surely different from \c b
176 173
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
177 174
    ///Returns \c true if \c a is \e surely positive
178 175
    bool positive(Value a) const { return _epsilon<a; }
179 176
    ///Returns \c true if \c a is \e surely negative
180 177
    bool negative(Value a) const { return -_epsilon>a; }
181 178
    ///Returns \c true if \c a is \e surely non-zero
182 179
    bool nonZero(Value a) const { return positive(a)||negative(a); }
183 180

	
184 181
    ///@}
185 182

	
186 183
    ///Returns zero
187 184
    static Value zero() {return 0;}
188 185
  };
189 186

	
190 187
  ///Long double specialization of Tolerance.
191 188

	
192 189
  ///Long double specialization of Tolerance.
193 190
  ///\sa Tolerance
194 191
  ///\relates Tolerance
195 192
  template<>
196 193
  class Tolerance<long double>
197 194
  {
198 195
    static long double def_epsilon;
199 196
    long double _epsilon;
200 197
  public:
201 198
    ///\e
202 199
    typedef long double Value;
203 200

	
204 201
    ///Constructor setting the epsilon tolerance to the default value.
205 202
    Tolerance() : _epsilon(def_epsilon) {}
206 203
    ///Constructor setting the epsilon tolerance to the given value.
207 204
    Tolerance(long double e) : _epsilon(e) {}
208 205

	
209 206
    ///Returns the epsilon value.
210 207
    Value epsilon() const {return _epsilon;}
211 208
    ///Sets the epsilon value.
212 209
    void epsilon(Value e) {_epsilon=e;}
213 210

	
214 211
    ///Returns the default epsilon value.
215 212
    static Value defaultEpsilon() {return def_epsilon;}
216 213
    ///Sets the default epsilon value.
217 214
    static void defaultEpsilon(Value e) {def_epsilon=e;}
218 215

	
219 216
    ///\name Comparisons
220 217
    ///See \ref lemon::Tolerance "Tolerance" for more details.
221 218

	
222 219
    ///@{
223 220

	
224 221
    ///Returns \c true if \c a is \e surely strictly less than \c b
225 222
    bool less(Value a,Value b) const {return a+_epsilon<b;}
226 223
    ///Returns \c true if \c a is \e surely different from \c b
227 224
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
228 225
    ///Returns \c true if \c a is \e surely positive
229 226
    bool positive(Value a) const { return _epsilon<a; }
230 227
    ///Returns \c true if \c a is \e surely negative
231 228
    bool negative(Value a) const { return -_epsilon>a; }
232 229
    ///Returns \c true if \c a is \e surely non-zero
233 230
    bool nonZero(Value a) const { return positive(a)||negative(a); }
234 231

	
235 232
    ///@}
236 233

	
237 234
    ///Returns zero
238 235
    static Value zero() {return 0;}
239 236
  };
240 237

	
241
  ///Integer specialization of Tolerance.
242

	
243
  ///Integer specialization of Tolerance.
244
  ///\sa Tolerance
245
  template<>
246
  class Tolerance<int>
247
  {
248
  public:
249
    ///\e
250
    typedef int Value;
251

	
252
    ///\name Comparisons
253
    ///See \ref lemon::Tolerance "Tolerance" for more details.
254

	
255
    ///@{
256

	
257
    ///Returns \c true if \c a is \e surely strictly less than \c b
258
    static bool less(Value a,Value b) { return a<b;}
259
    ///Returns \c true if \c a is \e surely different from \c b
260
    static bool different(Value a,Value b) { return a!=b; }
261
    ///Returns \c true if \c a is \e surely positive
262
    static bool positive(Value a) { return 0<a; }
263
    ///Returns \c true if \c a is \e surely negative
264
    static bool negative(Value a) { return 0>a; }
265
    ///Returns \c true if \c a is \e surely non-zero
266
    static bool nonZero(Value a) { return a!=0; }
267

	
268
    ///@}
269

	
270
    ///Returns zero
271
    static Value zero() {return 0;}
272
  };
273

	
274
  ///Unsigned integer specialization of Tolerance.
275

	
276
  ///Unsigned integer specialization of Tolerance.
277
  ///\sa Tolerance
278
  template<>
279
  class Tolerance<unsigned int>
280
  {
281
  public:
282
    ///\e
283
    typedef unsigned int Value;
284

	
285
    ///\name Comparisons
286
    ///See \ref lemon::Tolerance "Tolerance" for more details.
287

	
288
    ///@{
289

	
290
    ///Returns \c true if \c a is \e surely strictly less than \c b
291
    static bool less(Value a,Value b) { return a<b;}
292
    ///Returns \c true if \c a is \e surely different from \c b
293
    static bool different(Value a,Value b) { return a!=b; }
294
    ///Returns \c true if \c a is \e surely positive
295
    static bool positive(Value a) { return 0<a; }
296
    ///Returns \c true if \c a is \e surely negative
297
    static bool negative(Value) { return false; }
298
    ///Returns \c true if \c a is \e surely non-zero
299
    static bool nonZero(Value a) { return a!=0; }
300

	
301
    ///@}
302

	
303
    ///Returns zero
304
    static Value zero() {return 0;}
305
  };
306

	
307

	
308
  ///Long integer specialization of Tolerance.
309

	
310
  ///Long integer specialization of Tolerance.
311
  ///\sa Tolerance
312
  template<>
313
  class Tolerance<long int>
314
  {
315
  public:
316
    ///\e
317
    typedef long int Value;
318

	
319
    ///\name Comparisons
320
    ///See \ref lemon::Tolerance "Tolerance" for more details.
321

	
322
    ///@{
323

	
324
    ///Returns \c true if \c a is \e surely strictly less than \c b
325
    static bool less(Value a,Value b) { return a<b;}
326
    ///Returns \c true if \c a is \e surely different from \c b
327
    static bool different(Value a,Value b) { return a!=b; }
328
    ///Returns \c true if \c a is \e surely positive
329
    static bool positive(Value a) { return 0<a; }
330
    ///Returns \c true if \c a is \e surely negative
331
    static bool negative(Value a) { return 0>a; }
332
    ///Returns \c true if \c a is \e surely non-zero
333
    static bool nonZero(Value a) { return a!=0;}
334

	
335
    ///@}
336

	
337
    ///Returns zero
338
    static Value zero() {return 0;}
339
  };
340

	
341
  ///Unsigned long integer specialization of Tolerance.
342

	
343
  ///Unsigned long integer specialization of Tolerance.
344
  ///\sa Tolerance
345
  template<>
346
  class Tolerance<unsigned long int>
347
  {
348
  public:
349
    ///\e
350
    typedef unsigned long int Value;
351

	
352
    ///\name Comparisons
353
    ///See \ref lemon::Tolerance "Tolerance" for more details.
354

	
355
    ///@{
356

	
357
    ///Returns \c true if \c a is \e surely strictly less than \c b
358
    static bool less(Value a,Value b) { return a<b;}
359
    ///Returns \c true if \c a is \e surely different from \c b
360
    static bool different(Value a,Value b) { return a!=b; }
361
    ///Returns \c true if \c a is \e surely positive
362
    static bool positive(Value a) { return 0<a; }
363
    ///Returns \c true if \c a is \e surely negative
364
    static bool negative(Value) { return false; }
365
    ///Returns \c true if \c a is \e surely non-zero
366
    static bool nonZero(Value a) { return a!=0;}
367

	
368
    ///@}
369

	
370
    ///Returns zero
371
    static Value zero() {return 0;}
372
  };
373

	
374
#if defined __GNUC__ && !defined __STRICT_ANSI__
375

	
376
  ///Long long integer specialization of Tolerance.
377

	
378
  ///Long long integer specialization of Tolerance.
379
  ///\warning This class (more exactly, type <tt>long long</tt>)
380
  ///is not ansi compatible.
381
  ///\sa Tolerance
382
  template<>
383
  class Tolerance<long long int>
384
  {
385
  public:
386
    ///\e
387
    typedef long long int Value;
388

	
389
    ///\name Comparisons
390
    ///See \ref lemon::Tolerance "Tolerance" for more details.
391

	
392
    ///@{
393

	
394
    ///Returns \c true if \c a is \e surely strictly less than \c b
395
    static bool less(Value a,Value b) { return a<b;}
396
    ///Returns \c true if \c a is \e surely different from \c b
397
    static bool different(Value a,Value b) { return a!=b; }
398
    ///Returns \c true if \c a is \e surely positive
399
    static bool positive(Value a) { return 0<a; }
400
    ///Returns \c true if \c a is \e surely negative
401
    static bool negative(Value a) { return 0>a; }
402
    ///Returns \c true if \c a is \e surely non-zero
403
    static bool nonZero(Value a) { return a!=0;}
404

	
405
    ///@}
406

	
407
    ///Returns zero
408
    static Value zero() {return 0;}
409
  };
410

	
411
  ///Unsigned long long integer specialization of Tolerance.
412

	
413
  ///Unsigned long long integer specialization of Tolerance.
414
  ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
415
  ///is not ansi compatible.
416
  ///\sa Tolerance
417
  template<>
418
  class Tolerance<unsigned long long int>
419
  {
420
  public:
421
    ///\e
422
    typedef unsigned long long int Value;
423

	
424
    ///\name Comparisons
425
    ///See \ref lemon::Tolerance "Tolerance" for more details.
426

	
427
    ///@{
428

	
429
    ///Returns \c true if \c a is \e surely strictly less than \c b
430
    static bool less(Value a,Value b) { return a<b;}
431
    ///Returns \c true if \c a is \e surely different from \c b
432
    static bool different(Value a,Value b) { return a!=b; }
433
    ///Returns \c true if \c a is \e surely positive
434
    static bool positive(Value a) { return 0<a; }
435
    ///Returns \c true if \c a is \e surely negative
436
    static bool negative(Value) { return false; }
437
    ///Returns \c true if \c a is \e surely non-zero
438
    static bool nonZero(Value a) { return a!=0;}
439

	
440
    ///@}
441

	
442
    ///Returns zero
443
    static Value zero() {return 0;}
444
  };
445

	
446
#endif
447

	
448 238
  /// @}
449 239

	
450 240
} //namespace lemon
451 241

	
452 242
#endif //LEMON_TOLERANCE_H
0 comments (0 inline)