gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 12 0
merge default
11 files changed with 255 insertions and 403 deletions:
↑ Collapse diff ↑
Ignore white space 1536 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
m4/libtool.m4
30 31
m4/ltoptions.m4
31 32
m4/ltsugar.m4
32 33
m4/ltversion.m4
33 34
m4/lt~obsolete.m4
34 35

	
35 36
syntax: regexp
36 37
(.*/)?\#[^/]*\#$
37 38
(.*/)?\.\#[^/]*$
38 39
^doc/html/.*
39 40
^doc/.*\.tag
40 41
^autom4te.cache/.*
41 42
^build-aux/.*
42 43
^.*objs.*/.*
43 44
^test/[a-z_]*$
44 45
^tools/[a-z-_]*$
45 46
^demo/.*_demo$
46 47
^.*build.*/.*
47 48
^doc/gen-images/.*
48 49
CMakeFiles
49 50
DartTestfile.txt
50 51
cmake_install.cmake
51 52
CMakeCache.txt
Ignore white space 1536 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
INCLUDE(FindDoxygen)
15 15
INCLUDE(FindGhostscript)
16 16
FIND_PACKAGE(GLPK 4.33)
17 17

	
18 18
ADD_DEFINITIONS(-DHAVE_CONFIG_H)
19 19

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

	
29 29
IF(GLPK_FOUND)
30 30
  SET(HAVE_LP TRUE)
31 31
  SET(HAVE_MIP TRUE)
32 32
  SET(HAVE_GLPK TRUE)
33 33
ENDIF(GLPK_FOUND)
34 34

	
35
INCLUDE(CheckTypeSize)
36
CHECK_TYPE_SIZE("long long" LONG_LONG)
37

	
35 38
ENABLE_TESTING()
36 39

	
37 40
ADD_SUBDIRECTORY(lemon)
38 41
ADD_SUBDIRECTORY(demo)
39 42
ADD_SUBDIRECTORY(doc)
40 43
ADD_SUBDIRECTORY(test)
41 44

	
42 45
IF(WIN32)
43 46
  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
44 47
  SET(CPACK_PACKAGE_VENDOR "EGRES")
45 48
  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
46 49
    "LEMON - Library of Efficient Models and Optimization in Networks")
47 50
  SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
48 51

	
49 52
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
50 53

	
51 54
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
52 55
    "${PROJECT_NAME} ${PROJECT_VERSION}")
53 56
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
54 57
    "${PROJECT_NAME} ${PROJECT_VERSION}")
55 58

	
56 59
  SET(CPACK_COMPONENTS_ALL headers library html_documentation)
57 60

	
58 61
  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
59 62
  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
60 63
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
61 64

	
62 65
  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
63 66
    "C++ header files")
64 67
  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
65 68
    "DLL and import library")
66 69
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
67 70
    "Doxygen generated documentation")
68 71

	
69 72
  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
70 73

	
71 74
  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
72 75
  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
73 76
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
74 77

	
75 78
  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
76 79
    "Components needed to develop software using LEMON")
77 80
  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
78 81
    "Documentation of LEMON")
79 82

	
80 83
  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
81 84

	
82 85
  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
83 86
  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
84 87
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
85 88

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

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

	
3 3
dnl Version information.
4 4
m4_define([lemon_version_number],
5 5
	[m4_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
dnl Do compilation tests using the C++ compiler.
23 23
AC_LANG([C++])
24 24

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

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

	
32 38
AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
33 39
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
34 40

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

	
46 52
dnl Set custom compiler flags when using g++.
47 53
if test "$GXX" = yes -a "$ICC" = no; then
48 54
  WARNINGCXXFLAGS="-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 -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
49 55
fi
50 56
AC_SUBST([WARNINGCXXFLAGS])
51 57

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

	
58 64
AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
59 65
AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
60 66

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

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

	
87 93
dnl Checks for header files.
88 94
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
89 95

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

	
97 103
dnl Checks for library functions.
98 104
AC_HEADER_STDC
99 105
AC_CHECK_FUNCS(gettimeofday times ctime_r)
100 106

	
101 107
dnl Add dependencies on files generated by configure.
102 108
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
103 109
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
104 110

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

	
112 118
AC_OUTPUT
113 119

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

	
136 144
echo
137 145
echo Configure complete, now type \'make\' and then \'make install\'.
138 146
echo
Ignore white space 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-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
#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 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-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 1536 line context
1
#cmakedefine HAVE_LP 1
2
#cmakedefine HAVE_MIP 1
3
#cmakedefine HAVE_GLPK 1

1
#cmakedefine HAVE_LONG_LONG 1
2
#cmakedefine HAVE_LP 1
3
#cmakedefine HAVE_MIP 1
4
#cmakedefine HAVE_GLPK 1
Ignore white space 1536 line context
1
/* Define to 1 if you have long long */
2
#undef HAVE_LONG_LONG
3

	
1 4
/* Define to 1 if you have any LP solver. */
2 5
#undef HAVE_LP
3 6

	
4 7
/* Define to 1 if you have any MIP solver. */
5 8
#undef HAVE_MIP
6 9

	
7 10
/* Define to 1 if you have CPLEX. */
8 11
#undef HAVE_CPLEX
9 12

	
10 13
/* Define to 1 if you have GLPK. */
11 14
#undef HAVE_GLPK
12 15

	
13 16
/* Define to 1 if you have SOPLEX */
14 17
#undef HAVE_SOPLEX
15 18

	
16 19
/* Define to 1 if you have CLP */
17 20
#undef HAVE_CLP
Ignore white space 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-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
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" reader.
22 22

	
23 23

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

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

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

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

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

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

	
41 41
namespace lemon {
42 42

	
43 43
  namespace _reader_bits {
44 44

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

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

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

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

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

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

	
80 80
    };
81 81

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
332 332
      Functor _functor;
333 333

	
334 334
    public:
335 335

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

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

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

	
364 364
      Functor _functor;
365 365

	
366 366
    public:
367 367

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

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

	
388 388
  }
389 389

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

	
393
  /// \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

	
849 826
  private:
850 827

	
851 828
    bool readLine() {
852 829
      std::string str;
853 830
      while(++line_num, std::getline(*_is, str)) {
854 831
        line.clear(); line.str(str);
855 832
        char c;
856 833
        if (line >> std::ws >> c && c != '#') {
857 834
          line.putback(c);
858 835
          return true;
859 836
        }
860 837
      }
861 838
      return false;
862 839
    }
863 840

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

	
868 845
    void skipSection() {
869 846
      char c;
870 847
      while (readSuccess() && line >> c && c != '@') {
871 848
        readLine();
872 849
      }
873 850
      if (readSuccess()) {
874 851
        line.putback(c);
875 852
      }
876 853
    }
877 854

	
878 855
    void readNodes() {
879 856

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

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

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

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

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

	
918 895
        {
919 896
          std::map<std::string, int>::iterator jt = maps.find("label");
920 897
          if (jt != maps.end()) {
921 898
            label_index = jt->second;
922 899
          } else {
923 900
            label_index = -1;
924 901
          }
925 902
        }
926 903
        map_num = maps.size();
927 904
      }
928 905

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

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

	
943 920
        Node n;
944 921
        if (!_use_nodes) {
945 922
          n = _digraph.addNode();
946 923
          if (label_index != -1)
947 924
            _node_index.insert(std::make_pair(tokens[label_index], n));
948 925
        } else {
949 926
          if (label_index == -1)
950 927
            throw FormatError("Label map not found");
951 928
          typename std::map<std::string, Node>::iterator it =
952 929
            _node_index.find(tokens[label_index]);
953 930
          if (it == _node_index.end()) {
954 931
            std::ostringstream msg;
955 932
            msg << "Node with label not found: " << tokens[label_index];
956 933
            throw FormatError(msg.str());
957 934
          }
958 935
          n = it->second;
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;
1633 1621
    }
1634 1622

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

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

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

	
1678 1666
    /// @}
1679 1667

	
1680 1668
  private:
1681 1669

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

	
1695 1683
    bool readSuccess() {
1696 1684
      return static_cast<bool>(*_is);
1697 1685
    }
1698 1686

	
1699 1687
    void skipSection() {
1700 1688
      char c;
1701 1689
      while (readSuccess() && line >> c && c != '@') {
1702 1690
        readLine();
1703 1691
      }
1704 1692
      if (readSuccess()) {
1705 1693
        line.putback(c);
1706 1694
      }
1707 1695
    }
1708 1696

	
1709 1697
    void readNodes() {
1710 1698

	
1711 1699
      std::vector<int> map_index(_node_maps.size());
1712 1700
      int map_num, label_index;
1713 1701

	
1714 1702
      char c;
1715 1703
      if (!readLine() || !(line >> c) || c == '@') {
1716 1704
        if (readSuccess() && line) line.putback(c);
1717 1705
        if (!_node_maps.empty())
1718 1706
          throw FormatError("Cannot find map names");
1719 1707
        return;
1720 1708
      }
1721 1709
      line.putback(c);
1722 1710

	
1723 1711
      {
1724 1712
        std::map<std::string, int> maps;
1725 1713

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

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

	
1749 1737
        {
1750 1738
          std::map<std::string, int>::iterator jt = maps.find("label");
1751 1739
          if (jt != maps.end()) {
1752 1740
            label_index = jt->second;
1753 1741
          } else {
1754 1742
            label_index = -1;
1755 1743
          }
1756 1744
        }
1757 1745
        map_num = maps.size();
1758 1746
      }
1759 1747

	
1760 1748
      while (readLine() && line >> c && c != '@') {
1761 1749
        line.putback(c);
1762 1750

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

	
1774 1762
        Node n;
1775 1763
        if (!_use_nodes) {
1776 1764
          n = _graph.addNode();
1777 1765
          if (label_index != -1)
1778 1766
            _node_index.insert(std::make_pair(tokens[label_index], n));
1779 1767
        } else {
1780 1768
          if (label_index == -1)
1781 1769
            throw FormatError("Label map not found");
1782 1770
          typename std::map<std::string, Node>::iterator it =
1783 1771
            _node_index.find(tokens[label_index]);
1784 1772
          if (it == _node_index.end()) {
1785 1773
            std::ostringstream msg;
1786 1774
            msg << "Node with label not found: " << tokens[label_index];
1787 1775
            throw FormatError(msg.str());
1788 1776
          }
1789 1777
          n = it->second;
1790 1778
        }
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.
2303 2321
  /// \relates SectionReader
2304 2322
  inline SectionReader sectionReader(std::istream& is) {
2305 2323
    SectionReader tmp(is);
2306 2324
    return tmp;
2307 2325
  }
2308 2326

	
2309 2327
  /// \brief Return a \ref SectionReader class
2310 2328
  ///
2311 2329
  /// This function just returns a \ref SectionReader class.
2312 2330
  /// \relates SectionReader
2313 2331
  inline SectionReader sectionReader(const std::string& fn) {
2314 2332
    SectionReader tmp(fn);
2315 2333
    return tmp;
2316 2334
  }
2317 2335

	
2318 2336
  /// \brief Return a \ref SectionReader class
2319 2337
  ///
2320 2338
  /// This function just returns a \ref SectionReader class.
2321 2339
  /// \relates SectionReader
2322 2340
  inline SectionReader sectionReader(const char* fn) {
2323 2341
    SectionReader tmp(fn);
2324 2342
    return tmp;
2325 2343
  }
2326 2344

	
2327 2345
  /// \ingroup lemon_io
2328 2346
  ///
2329 2347
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2330 2348
  ///
2331 2349
  /// This class can be used to read the sections, the map names and
2332 2350
  /// the attributes from a file. Usually, the LEMON programs know
2333 2351
  /// that, which type of graph, which maps and which attributes
2334 2352
  /// should be read from a file, but in general tools (like glemon)
2335 2353
  /// the contents of an LGF file should be guessed somehow. This class
2336 2354
  /// reads the graph and stores the appropriate information for
2337 2355
  /// reading the graph.
2338 2356
  ///
2339 2357
  ///\code
2340 2358
  /// LgfContents contents("graph.lgf");
2341 2359
  /// contents.run();
2342 2360
  ///
2343 2361
  /// // Does it contain any node section and arc section?
2344 2362
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2345 2363
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2346 2364
  ///   return -1;
2347 2365
  /// }
2348 2366
  /// std::cout << "The name of the default node section: "
2349 2367
  ///           << contents.nodeSection(0) << std::endl;
2350 2368
  /// std::cout << "The number of the arc maps: "
2351 2369
  ///           << contents.arcMaps(0).size() << std::endl;
2352 2370
  /// std::cout << "The name of second arc map: "
2353 2371
  ///           << contents.arcMaps(0)[1] << std::endl;
2354 2372
  ///\endcode
2355 2373
  class LgfContents {
2356 2374
  private:
2357 2375

	
2358 2376
    std::istream* _is;
2359 2377
    bool local_is;
2360 2378

	
2361 2379
    std::vector<std::string> _node_sections;
2362 2380
    std::vector<std::string> _edge_sections;
2363 2381
    std::vector<std::string> _attribute_sections;
2364 2382
    std::vector<std::string> _extra_sections;
2365 2383

	
2366 2384
    std::vector<bool> _arc_sections;
2367 2385

	
2368 2386
    std::vector<std::vector<std::string> > _node_maps;
2369 2387
    std::vector<std::vector<std::string> > _edge_maps;
2370 2388

	
2371 2389
    std::vector<std::vector<std::string> > _attributes;
2372 2390

	
2373 2391

	
2374 2392
    int line_num;
2375 2393
    std::istringstream line;
2376 2394

	
2377 2395
  public:
2378 2396

	
2379 2397
    /// \brief Constructor
2380 2398
    ///
2381 2399
    /// Construct an \e LGF contents reader, which reads from the given
2382 2400
    /// input stream.
2383 2401
    LgfContents(std::istream& is)
2384 2402
      : _is(&is), local_is(false) {}
2385 2403

	
2386 2404
    /// \brief Constructor
2387 2405
    ///
2388 2406
    /// Construct an \e LGF contents reader, which reads from the given
2389 2407
    /// file.
2390 2408
    LgfContents(const std::string& fn)
2391 2409
      : _is(new std::ifstream(fn.c_str())), local_is(true) {
2392 2410
      if (!(*_is)) {
2393 2411
        delete _is;
2394 2412
        throw IoError("Cannot open file", fn);
2395 2413
      }
2396 2414
    }
2397 2415

	
2398 2416
    /// \brief Constructor
2399 2417
    ///
2400 2418
    /// Construct an \e LGF contents reader, which reads from the given
2401 2419
    /// file.
2402 2420
    LgfContents(const char* fn)
2403 2421
      : _is(new std::ifstream(fn)), local_is(true) {
2404 2422
      if (!(*_is)) {
2405 2423
        delete _is;
2406 2424
        throw IoError("Cannot open file", fn);
2407 2425
      }
2408 2426
    }
2409 2427

	
2410 2428
    /// \brief Destructor
2411 2429
    ~LgfContents() {
2412 2430
      if (local_is) delete _is;
2413 2431
    }
2414 2432

	
2415 2433
  private:
2416 2434

	
2417 2435
    LgfContents(const LgfContents&);
2418 2436
    LgfContents& operator=(const LgfContents&);
2419 2437

	
2420 2438
  public:
2421 2439

	
2422 2440

	
2423 2441
    /// \name Node sections
2424 2442
    /// @{
2425 2443

	
2426 2444
    /// \brief Gives back the number of node sections in the file.
2427 2445
    ///
2428 2446
    /// Gives back the number of node sections in the file.
2429 2447
    int nodeSectionNum() const {
2430 2448
      return _node_sections.size();
2431 2449
    }
2432 2450

	
2433 2451
    /// \brief Returns the node section name at the given position.
2434 2452
    ///
2435 2453
    /// Returns the node section name at the given position.
2436 2454
    const std::string& nodeSection(int i) const {
2437 2455
      return _node_sections[i];
2438 2456
    }
2439 2457

	
2440 2458
    /// \brief Gives back the node maps for the given section.
2441 2459
    ///
2442 2460
    /// Gives back the node maps for the given section.
2443 2461
    const std::vector<std::string>& nodeMapNames(int i) const {
2444 2462
      return _node_maps[i];
2445 2463
    }
2446 2464

	
2447 2465
    /// @}
2448 2466

	
2449 2467
    /// \name Arc/Edge sections
2450 2468
    /// @{
2451 2469

	
2452 2470
    /// \brief Gives back the number of arc/edge sections in the file.
2453 2471
    ///
2454 2472
    /// Gives back the number of arc/edge sections in the file.
2455 2473
    /// \note It is synonym of \c edgeSectionNum().
2456 2474
    int arcSectionNum() const {
2457 2475
      return _edge_sections.size();
2458 2476
    }
2459 2477

	
2460 2478
    /// \brief Returns the arc/edge section name at the given position.
2461 2479
    ///
2462 2480
    /// Returns the arc/edge section name at the given position.
2463 2481
    /// \note It is synonym of \c edgeSection().
2464 2482
    const std::string& arcSection(int i) const {
2465 2483
      return _edge_sections[i];
2466 2484
    }
2467 2485

	
2468 2486
    /// \brief Gives back the arc/edge maps for the given section.
2469 2487
    ///
2470 2488
    /// Gives back the arc/edge maps for the given section.
2471 2489
    /// \note It is synonym of \c edgeMapNames().
2472 2490
    const std::vector<std::string>& arcMapNames(int i) const {
2473 2491
      return _edge_maps[i];
2474 2492
    }
2475 2493

	
2476 2494
    /// @}
2477 2495

	
2478 2496
    /// \name Synonyms
2479 2497
    /// @{
2480 2498

	
2481 2499
    /// \brief Gives back the number of arc/edge sections in the file.
2482 2500
    ///
2483 2501
    /// Gives back the number of arc/edge sections in the file.
2484 2502
    /// \note It is synonym of \c arcSectionNum().
2485 2503
    int edgeSectionNum() const {
2486 2504
      return _edge_sections.size();
2487 2505
    }
2488 2506

	
2489 2507
    /// \brief Returns the section name at the given position.
2490 2508
    ///
2491 2509
    /// Returns the section name at the given position.
2492 2510
    /// \note It is synonym of \c arcSection().
2493 2511
    const std::string& edgeSection(int i) const {
2494 2512
      return _edge_sections[i];
2495 2513
    }
2496 2514

	
2497 2515
    /// \brief Gives back the edge maps for the given section.
2498 2516
    ///
2499 2517
    /// Gives back the edge maps for the given section.
2500 2518
    /// \note It is synonym of \c arcMapNames().
2501 2519
    const std::vector<std::string>& edgeMapNames(int i) const {
2502 2520
      return _edge_maps[i];
2503 2521
    }
2504 2522

	
2505 2523
    /// @}
2506 2524

	
2507 2525
    /// \name Attribute sections
2508 2526
    /// @{
2509 2527

	
2510 2528
    /// \brief Gives back the number of attribute sections in the file.
2511 2529
    ///
2512 2530
    /// Gives back the number of attribute sections in the file.
2513 2531
    int attributeSectionNum() const {
2514 2532
      return _attribute_sections.size();
2515 2533
    }
2516 2534

	
2517 2535
    /// \brief Returns the attribute section name at the given position.
2518 2536
    ///
2519 2537
    /// Returns the attribute section name at the given position.
2520 2538
    const std::string& attributeSectionNames(int i) const {
2521 2539
      return _attribute_sections[i];
2522 2540
    }
2523 2541

	
2524 2542
    /// \brief Gives back the attributes for the given section.
2525 2543
    ///
2526 2544
    /// Gives back the attributes for the given section.
2527 2545
    const std::vector<std::string>& attributes(int i) const {
2528 2546
      return _attributes[i];
2529 2547
    }
2530 2548

	
2531 2549
    /// @}
2532 2550

	
2533 2551
    /// \name Extra sections
2534 2552
    /// @{
2535 2553

	
2536 2554
    /// \brief Gives back the number of extra sections in the file.
2537 2555
    ///
2538 2556
    /// Gives back the number of extra sections in the file.
2539 2557
    int extraSectionNum() const {
2540 2558
      return _extra_sections.size();
2541 2559
    }
2542 2560

	
2543 2561
    /// \brief Returns the extra section type at the given position.
2544 2562
    ///
2545 2563
    /// Returns the section type at the given position.
2546 2564
    const std::string& extraSection(int i) const {
2547 2565
      return _extra_sections[i];
2548 2566
    }
2549 2567

	
2550 2568
    /// @}
2551 2569

	
2552 2570
  private:
2553 2571

	
2554 2572
    bool readLine() {
2555 2573
      std::string str;
2556 2574
      while(++line_num, std::getline(*_is, str)) {
2557 2575
        line.clear(); line.str(str);
2558 2576
        char c;
2559 2577
        if (line >> std::ws >> c && c != '#') {
2560 2578
          line.putback(c);
2561 2579
          return true;
2562 2580
        }
2563 2581
      }
2564 2582
      return false;
2565 2583
    }
2566 2584

	
2567 2585
    bool readSuccess() {
2568 2586
      return static_cast<bool>(*_is);
2569 2587
    }
2570 2588

	
2571 2589
    void skipSection() {
2572 2590
      char c;
2573 2591
      while (readSuccess() && line >> c && c != '@') {
2574 2592
        readLine();
2575 2593
      }
2576 2594
      if (readSuccess()) {
2577 2595
        line.putback(c);
2578 2596
      }
2579 2597
    }
2580 2598

	
2581 2599
    void readMaps(std::vector<std::string>& maps) {
2582 2600
      char c;
2583 2601
      if (!readLine() || !(line >> c) || c == '@') {
2584 2602
        if (readSuccess() && line) line.putback(c);
2585 2603
        return;
2586 2604
      }
2587 2605
      line.putback(c);
2588 2606
      std::string map;
2589 2607
      while (_reader_bits::readToken(line, map)) {
2590 2608
        maps.push_back(map);
2591 2609
      }
2592 2610
    }
2593 2611

	
2594 2612
    void readAttributes(std::vector<std::string>& attrs) {
2595 2613
      readLine();
2596 2614
      char c;
2597 2615
      while (readSuccess() && line >> c && c != '@') {
2598 2616
        line.putback(c);
2599 2617
        std::string attr;
2600 2618
        _reader_bits::readToken(line, attr);
2601 2619
        attrs.push_back(attr);
2602 2620
        readLine();
2603 2621
      }
2604 2622
      line.putback(c);
2605 2623
    }
2606 2624

	
2607 2625
  public:
2608 2626

	
2609 2627
    /// \name Execution of the contents reader
2610 2628
    /// @{
2611 2629

	
2612 2630
    /// \brief Starts the reading
2613 2631
    ///
2614 2632
    /// This function starts the reading.
2615 2633
    void run() {
2616 2634

	
2617 2635
      readLine();
2618 2636
      skipSection();
2619 2637

	
2620 2638
      while (readSuccess()) {
2621 2639

	
2622 2640
        char c;
2623 2641
        line >> c;
2624 2642

	
2625 2643
        std::string section, caption;
2626 2644
        _reader_bits::readToken(line, section);
2627 2645
        _reader_bits::readToken(line, caption);
2628 2646

	
2629 2647
        if (section == "nodes") {
2630 2648
          _node_sections.push_back(caption);
2631 2649
          _node_maps.push_back(std::vector<std::string>());
2632 2650
          readMaps(_node_maps.back());
2633 2651
          readLine(); skipSection();
2634 2652
        } else if (section == "arcs" || section == "edges") {
2635 2653
          _edge_sections.push_back(caption);
2636 2654
          _arc_sections.push_back(section == "arcs");
2637 2655
          _edge_maps.push_back(std::vector<std::string>());
2638 2656
          readMaps(_edge_maps.back());
2639 2657
          readLine(); skipSection();
2640 2658
        } else if (section == "attributes") {
2641 2659
          _attribute_sections.push_back(caption);
2642 2660
          _attributes.push_back(std::vector<std::string>());
2643 2661
          readAttributes(_attributes.back());
2644 2662
        } else {
2645 2663
          _extra_sections.push_back(section);
2646 2664
          readLine(); skipSection();
2647 2665
        }
2648 2666
      }
2649 2667
    }
2650 2668

	
2651 2669
    /// @}
2652 2670

	
2653 2671
  };
2654 2672
}
2655 2673

	
2656 2674
#endif
Ignore white space 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-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
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" writer.
22 22

	
23 23

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

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

	
31 31
#include <algorithm>
32 32

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

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

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

	
42 42
namespace lemon {
43 43

	
44 44
  namespace _writer_bits {
45 45

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
319 319
      Functor _functor;
320 320

	
321 321
    public:
322 322

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

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

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

	
336 336
      Functor _functor;
337 337

	
338 338
    public:
339 339

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

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

	
348 348
  }
349 349

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

	
353
  /// \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 1536 line context
... ...
@@ -164,923 +164,939 @@
164 164
    void eraseFront() {
165 165
      if (!head.empty()) {
166 166
        head.pop_back();
167 167
      } else {
168 168
        head.clear();
169 169
        int halfsize = tail.size() / 2;
170 170
        head.resize(halfsize);
171 171
        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
172 172
                  head.rbegin());
173 173
        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
174 174
        tail.resize(tail.size() - halfsize - 1);
175 175
      }
176 176
    }
177 177

	
178 178
    /// \brief The last arc of the path
179 179
    const Arc& back() const {
180 180
      return tail.empty() ? head.front() : tail.back();
181 181
    }
182 182

	
183 183
    /// \brief Add a new arc behind the current path
184 184
    void addBack(const Arc& arc) {
185 185
      tail.push_back(arc);
186 186
    }
187 187

	
188 188
    /// \brief Erase the last arc of the path
189 189
    void eraseBack() {
190 190
      if (!tail.empty()) {
191 191
        tail.pop_back();
192 192
      } else {
193 193
        int halfsize = head.size() / 2;
194 194
        tail.resize(halfsize);
195 195
        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
196 196
                  tail.rbegin());
197 197
        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
198 198
        head.resize(head.size() - halfsize - 1);
199 199
      }
200 200
    }
201 201

	
202 202
    typedef True BuildTag;
203 203

	
204 204
    template <typename CPath>
205 205
    void build(const CPath& path) {
206 206
      int len = path.length();
207 207
      tail.reserve(len);
208 208
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
209 209
        tail.push_back(it);
210 210
      }
211 211
    }
212 212

	
213 213
    template <typename CPath>
214 214
    void buildRev(const CPath& path) {
215 215
      int len = path.length();
216 216
      head.reserve(len);
217 217
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
218 218
        head.push_back(it);
219 219
      }
220 220
    }
221 221

	
222 222
  protected:
223 223
    typedef std::vector<Arc> Container;
224 224
    Container head, tail;
225 225

	
226 226
  };
227 227

	
228 228
  /// \brief A structure for representing directed paths in a digraph.
229 229
  ///
230 230
  /// A structure for representing directed path in a digraph.
231 231
  /// \tparam _Digraph The digraph type in which the path is.
232 232
  ///
233 233
  /// In a sense, the path can be treated as a list of arcs. The
234 234
  /// lemon path type stores just this list. As a consequence it
235 235
  /// cannot enumerate the nodes in the path and the zero length paths
236 236
  /// cannot store the source.
237 237
  ///
238 238
  /// This implementation is a just back insertable and erasable path
239 239
  /// type. It can be indexed in O(1) time. The back insertion and
240 240
  /// erasure is amortized O(1) time. This implementation is faster
241 241
  /// then the \c Path type because it use just one vector for the
242 242
  /// arcs.
243 243
  template <typename _Digraph>
244 244
  class SimplePath {
245 245
  public:
246 246

	
247 247
    typedef _Digraph Digraph;
248 248
    typedef typename Digraph::Arc Arc;
249 249

	
250 250
    /// \brief Default constructor
251 251
    ///
252 252
    /// Default constructor
253 253
    SimplePath() {}
254 254

	
255 255
    /// \brief Template copy constructor
256 256
    ///
257 257
    /// This path can be initialized with any other path type. It just
258 258
    /// makes a copy of the given path.
259 259
    template <typename CPath>
260 260
    SimplePath(const CPath& cpath) {
261 261
      copyPath(*this, cpath);
262 262
    }
263 263

	
264 264
    /// \brief Template copy assignment
265 265
    ///
266 266
    /// This path can be initialized with any other path type. It just
267 267
    /// makes a copy of the given path.
268 268
    template <typename CPath>
269 269
    SimplePath& operator=(const CPath& cpath) {
270 270
      copyPath(*this, cpath);
271 271
      return *this;
272 272
    }
273 273

	
274 274
    /// \brief Iterator class to iterate on the arcs of the paths
275 275
    ///
276 276
    /// This class is used to iterate on the arcs of the paths
277 277
    ///
278 278
    /// Of course it converts to Digraph::Arc
279 279
    class ArcIt {
280 280
      friend class SimplePath;
281 281
    public:
282 282
      /// Default constructor
283 283
      ArcIt() {}
284 284
      /// Invalid constructor
285 285
      ArcIt(Invalid) : path(0), idx(-1) {}
286 286
      /// \brief Initializate the constructor to the first arc of path
287 287
      ArcIt(const SimplePath &_path)
288 288
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
289 289

	
290 290
    private:
291 291

	
292 292
      /// Constructor with starting point
293 293
      ArcIt(const SimplePath &_path, int _idx)
294 294
        : idx(_idx), path(&_path) {}
295 295

	
296 296
    public:
297 297

	
298 298
      ///Conversion to Digraph::Arc
299 299
      operator const Arc&() const {
300 300
        return path->nth(idx);
301 301
      }
302 302

	
303 303
      /// Next arc
304 304
      ArcIt& operator++() {
305 305
        ++idx;
306 306
        if (idx >= path->length()) idx = -1;
307 307
        return *this;
308 308
      }
309 309

	
310 310
      /// Comparison operator
311 311
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
312 312
      /// Comparison operator
313 313
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
314 314
      /// Comparison operator
315 315
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
316 316

	
317 317
    private:
318 318
      const SimplePath *path;
319 319
      int idx;
320 320
    };
321 321

	
322 322
    /// \brief Length of the path.
323 323
    int length() const { return data.size(); }
324 324
    /// \brief Return true if the path is empty.
325 325
    bool empty() const { return data.empty(); }
326 326

	
327 327
    /// \brief Reset the path to an empty one.
328 328
    void clear() { data.clear(); }
329 329

	
330 330
    /// \brief The nth arc.
331 331
    ///
332 332
    /// \pre n is in the [0..length() - 1] range
333 333
    const Arc& nth(int n) const {
334 334
      return data[n];
335 335
    }
336 336

	
337 337
    /// \brief  Initializes arc iterator to point to the nth arc.
338 338
    ArcIt nthIt(int n) const {
339 339
      return ArcIt(*this, n);
340 340
    }
341 341

	
342 342
    /// \brief The first arc of the path.
343 343
    const Arc& front() const {
344 344
      return data.front();
345 345
    }
346 346

	
347 347
    /// \brief The last arc of the path.
348 348
    const Arc& back() const {
349 349
      return data.back();
350 350
    }
351 351

	
352 352
    /// \brief Add a new arc behind the current path.
353 353
    void addBack(const Arc& arc) {
354 354
      data.push_back(arc);
355 355
    }
356 356

	
357 357
    /// \brief Erase the last arc of the path
358 358
    void eraseBack() {
359 359
      data.pop_back();
360 360
    }
361 361

	
362 362
    typedef True BuildTag;
363 363

	
364 364
    template <typename CPath>
365 365
    void build(const CPath& path) {
366 366
      int len = path.length();
367 367
      data.resize(len);
368 368
      int index = 0;
369 369
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
370 370
        data[index] = it;;
371 371
        ++index;
372 372
      }
373 373
    }
374 374

	
375 375
    template <typename CPath>
376 376
    void buildRev(const CPath& path) {
377 377
      int len = path.length();
378 378
      data.resize(len);
379 379
      int index = len;
380 380
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
381 381
        --index;
382 382
        data[index] = it;;
383 383
      }
384 384
    }
385 385

	
386 386
  protected:
387 387
    typedef std::vector<Arc> Container;
388 388
    Container data;
389 389

	
390 390
  };
391 391

	
392 392
  /// \brief A structure for representing directed paths in a digraph.
393 393
  ///
394 394
  /// A structure for representing directed path in a digraph.
395 395
  /// \tparam _Digraph The digraph type in which the path is.
396 396
  ///
397 397
  /// In a sense, the path can be treated as a list of arcs. The
398 398
  /// lemon path type stores just this list. As a consequence it
399 399
  /// cannot enumerate the nodes in the path and the zero length paths
400 400
  /// cannot store the source.
401 401
  ///
402 402
  /// This implementation is a back and front insertable and erasable
403 403
  /// path type. It can be indexed in O(k) time, where k is the rank
404 404
  /// of the arc in the path. The length can be computed in O(n)
405 405
  /// time. The front and back insertion and erasure is O(1) time
406 406
  /// and it can be splited and spliced in O(1) time.
407 407
  template <typename _Digraph>
408 408
  class ListPath {
409 409
  public:
410 410

	
411 411
    typedef _Digraph Digraph;
412 412
    typedef typename Digraph::Arc Arc;
413 413

	
414 414
  protected:
415 415

	
416 416
    // the std::list<> is incompatible
417 417
    // hard to create invalid iterator
418 418
    struct Node {
419 419
      Arc arc;
420 420
      Node *next, *prev;
421 421
    };
422 422

	
423 423
    Node *first, *last;
424 424

	
425 425
    std::allocator<Node> alloc;
426 426

	
427 427
  public:
428 428

	
429 429
    /// \brief Default constructor
430 430
    ///
431 431
    /// Default constructor
432 432
    ListPath() : first(0), last(0) {}
433 433

	
434 434
    /// \brief Template copy constructor
435 435
    ///
436 436
    /// This path can be initialized with any other path type. It just
437 437
    /// makes a copy of the given path.
438 438
    template <typename CPath>
439 439
    ListPath(const CPath& cpath) : first(0), last(0) {
440 440
      copyPath(*this, cpath);
441 441
    }
442 442

	
443 443
    /// \brief Destructor of the path
444 444
    ///
445 445
    /// Destructor of the path
446 446
    ~ListPath() {
447 447
      clear();
448 448
    }
449 449

	
450 450
    /// \brief Template copy assignment
451 451
    ///
452 452
    /// This path can be initialized with any other path type. It just
453 453
    /// makes a copy of the given path.
454 454
    template <typename CPath>
455 455
    ListPath& operator=(const CPath& cpath) {
456 456
      copyPath(*this, cpath);
457 457
      return *this;
458 458
    }
459 459

	
460 460
    /// \brief Iterator class to iterate on the arcs of the paths
461 461
    ///
462 462
    /// This class is used to iterate on the arcs of the paths
463 463
    ///
464 464
    /// Of course it converts to Digraph::Arc
465 465
    class ArcIt {
466 466
      friend class ListPath;
467 467
    public:
468 468
      /// Default constructor
469 469
      ArcIt() {}
470 470
      /// Invalid constructor
471 471
      ArcIt(Invalid) : path(0), node(0) {}
472 472
      /// \brief Initializate the constructor to the first arc of path
473 473
      ArcIt(const ListPath &_path)
474 474
        : path(&_path), node(_path.first) {}
475 475

	
476 476
    protected:
477 477

	
478 478
      ArcIt(const ListPath &_path, Node *_node)
479 479
        : path(&_path), node(_node) {}
480 480

	
481 481

	
482 482
    public:
483 483

	
484 484
      ///Conversion to Digraph::Arc
485 485
      operator const Arc&() const {
486 486
        return node->arc;
487 487
      }
488 488

	
489 489
      /// Next arc
490 490
      ArcIt& operator++() {
491 491
        node = node->next;
492 492
        return *this;
493 493
      }
494 494

	
495 495
      /// Comparison operator
496 496
      bool operator==(const ArcIt& e) const { return node==e.node; }
497 497
      /// Comparison operator
498 498
      bool operator!=(const ArcIt& e) const { return node!=e.node; }
499 499
      /// Comparison operator
500 500
      bool operator<(const ArcIt& e) const { return node<e.node; }
501 501

	
502 502
    private:
503 503
      const ListPath *path;
504 504
      Node *node;
505 505
    };
506 506

	
507 507
    /// \brief The nth arc.
508 508
    ///
509 509
    /// This function looks for the nth arc in O(n) time.
510 510
    /// \pre n is in the [0..length() - 1] range
511 511
    const Arc& nth(int n) const {
512 512
      Node *node = first;
513 513
      for (int i = 0; i < n; ++i) {
514 514
        node = node->next;
515 515
      }
516 516
      return node->arc;
517 517
    }
518 518

	
519 519
    /// \brief Initializes arc iterator to point to the nth arc.
520 520
    ArcIt nthIt(int n) const {
521 521
      Node *node = first;
522 522
      for (int i = 0; i < n; ++i) {
523 523
        node = node->next;
524 524
      }
525 525
      return ArcIt(*this, node);
526 526
    }
527 527

	
528 528
    /// \brief Length of the path.
529 529
    int length() const {
530 530
      int len = 0;
531 531
      Node *node = first;
532 532
      while (node != 0) {
533 533
        node = node->next;
534 534
        ++len;
535 535
      }
536 536
      return len;
537 537
    }
538 538

	
539 539
    /// \brief Return true if the path is empty.
540 540
    bool empty() const { return first == 0; }
541 541

	
542 542
    /// \brief Reset the path to an empty one.
543 543
    void clear() {
544 544
      while (first != 0) {
545 545
        last = first->next;
546 546
        alloc.destroy(first);
547 547
        alloc.deallocate(first, 1);
548 548
        first = last;
549 549
      }
550 550
    }
551 551

	
552 552
    /// \brief The first arc of the path
553 553
    const Arc& front() const {
554 554
      return first->arc;
555 555
    }
556 556

	
557 557
    /// \brief Add a new arc before the current path
558 558
    void addFront(const Arc& arc) {
559 559
      Node *node = alloc.allocate(1);
560 560
      alloc.construct(node, Node());
561 561
      node->prev = 0;
562 562
      node->next = first;
563 563
      node->arc = arc;
564 564
      if (first) {
565 565
        first->prev = node;
566 566
        first = node;
567 567
      } else {
568 568
        first = last = node;
569 569
      }
570 570
    }
571 571

	
572 572
    /// \brief Erase the first arc of the path
573 573
    void eraseFront() {
574 574
      Node *node = first;
575 575
      first = first->next;
576 576
      if (first) {
577 577
        first->prev = 0;
578 578
      } else {
579 579
        last = 0;
580 580
      }
581 581
      alloc.destroy(node);
582 582
      alloc.deallocate(node, 1);
583 583
    }
584 584

	
585 585
    /// \brief The last arc of the path.
586 586
    const Arc& back() const {
587 587
      return last->arc;
588 588
    }
589 589

	
590 590
    /// \brief Add a new arc behind the current path.
591 591
    void addBack(const Arc& arc) {
592 592
      Node *node = alloc.allocate(1);
593 593
      alloc.construct(node, Node());
594 594
      node->next = 0;
595 595
      node->prev = last;
596 596
      node->arc = arc;
597 597
      if (last) {
598 598
        last->next = node;
599 599
        last = node;
600 600
      } else {
601 601
        last = first = node;
602 602
      }
603 603
    }
604 604

	
605 605
    /// \brief Erase the last arc of the path
606 606
    void eraseBack() {
607 607
      Node *node = last;
608 608
      last = last->prev;
609 609
      if (last) {
610 610
        last->next = 0;
611 611
      } else {
612 612
        first = 0;
613 613
      }
614 614
      alloc.destroy(node);
615 615
      alloc.deallocate(node, 1);
616 616
    }
617 617

	
618 618
    /// \brief Splice a path to the back of the current path.
619 619
    ///
620 620
    /// It splices \c tpath to the back of the current path and \c
621 621
    /// tpath becomes empty. The time complexity of this function is
622 622
    /// O(1).
623 623
    void spliceBack(ListPath& tpath) {
624 624
      if (first) {
625 625
        if (tpath.first) {
626 626
          last->next = tpath.first;
627 627
          tpath.first->prev = last;
628 628
          last = tpath.last;
629 629
        }
630 630
      } else {
631 631
        first = tpath.first;
632 632
        last = tpath.last;
633 633
      }
634 634
      tpath.first = tpath.last = 0;
635 635
    }
636 636

	
637 637
    /// \brief Splice a path to the front of the current path.
638 638
    ///
639 639
    /// It splices \c tpath before the current path and \c tpath
640 640
    /// becomes empty. The time complexity of this function
641 641
    /// is O(1).
642 642
    void spliceFront(ListPath& tpath) {
643 643
      if (first) {
644 644
        if (tpath.first) {
645 645
          first->prev = tpath.last;
646 646
          tpath.last->next = first;
647 647
          first = tpath.first;
648 648
        }
649 649
      } else {
650 650
        first = tpath.first;
651 651
        last = tpath.last;
652 652
      }
653 653
      tpath.first = tpath.last = 0;
654 654
    }
655 655

	
656 656
    /// \brief Splice a path into the current path.
657 657
    ///
658 658
    /// It splices the \c tpath into the current path before the
659 659
    /// position of \c it iterator and \c tpath becomes empty. The
660 660
    /// time complexity of this function is O(1). If the \c it is
661 661
    /// \c INVALID then it will splice behind the current path.
662 662
    void splice(ArcIt it, ListPath& tpath) {
663 663
      if (it.node) {
664 664
        if (tpath.first) {
665 665
          tpath.first->prev = it.node->prev;
666 666
          if (it.node->prev) {
667 667
            it.node->prev->next = tpath.first;
668 668
          } else {
669 669
            first = tpath.first;
670 670
          }
671 671
          it.node->prev = tpath.last;
672 672
          tpath.last->next = it.node;
673 673
        }
674 674
      } else {
675 675
        if (first) {
676 676
          if (tpath.first) {
677 677
            last->next = tpath.first;
678 678
            tpath.first->prev = last;
679 679
            last = tpath.last;
680 680
          }
681 681
        } else {
682 682
          first = tpath.first;
683 683
          last = tpath.last;
684 684
        }
685 685
      }
686 686
      tpath.first = tpath.last = 0;
687 687
    }
688 688

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

	
713 713

	
714 714
    typedef True BuildTag;
715 715

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

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

	
730 730
  };
731 731

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

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

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

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

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

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

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

	
802 802
    private:
803 803

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

	
808 808
    public:
809 809

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
87 87
namespace lemon {
88 88

	
89 89
  namespace _random_bits {
90 90

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

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

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

	
100 100
      static const int length = 624;
101 101
      static const int shift = 397;
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
    /// \brief Default constructor
544 534
    ///
545 535
    /// Constructor with constant seeding.
546 536
    Random() { core.initState(); }
547 537

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

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

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

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

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

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

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

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

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

	
670 660
    /// @}
671 661

	
672 662
    ///\name Uniform distributions
673 663
    ///
674 664
    /// @{
675 665

	
676 666
    /// \brief Returns a random real number from the range [0, 1)
677 667
    ///
678 668
    /// It returns a random real number from the range [0, 1). The
679 669
    /// default Number type is \c double.
680 670
    template <typename Number>
681 671
    Number real() {
682 672
      return _random_bits::RealConversion<Number, Word>::convert(core);
683 673
    }
684 674

	
685 675
    double real() {
686 676
      return real<double>();
687 677
    }
688 678

	
689 679
    /// \brief Returns a random real number from the range [0, 1)
690 680
    ///
691 681
    /// It returns a random double from the range [0, 1).
692 682
    double operator()() {
693 683
      return real<double>();
694 684
    }
695 685

	
696 686
    /// \brief Returns a random real number from the range [0, b)
697 687
    ///
698 688
    /// It returns a random real number from the range [0, b).
699 689
    double operator()(double b) {
700 690
      return real<double>() * b;
701 691
    }
702 692

	
703 693
    /// \brief Returns a random real number from the range [a, b)
704 694
    ///
705 695
    /// It returns a random real number from the range [a, b).
706 696
    double operator()(double a, double b) {
707 697
      return real<double>() * (b - a) + a;
708 698
    }
709 699

	
710 700
    /// \brief Returns a random integer from a range
711 701
    ///
712 702
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
713 703
    template <typename Number>
714 704
    Number integer(Number b) {
715 705
      return _random_bits::Mapping<Number, Word>::map(core, b);
716 706
    }
717 707

	
718 708
    /// \brief Returns a random integer from a range
719 709
    ///
720 710
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
721 711
    template <typename Number>
722 712
    Number integer(Number a, Number b) {
723 713
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
724 714
    }
725 715

	
726 716
    /// \brief Returns a random integer from a range
727 717
    ///
728 718
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
729 719
    template <typename Number>
730 720
    Number operator[](Number b) {
731 721
      return _random_bits::Mapping<Number, Word>::map(core, b);
732 722
    }
733 723

	
734 724
    /// \brief Returns a random non-negative integer
735 725
    ///
736 726
    /// It returns a random non-negative integer uniformly from the
737 727
    /// whole range of the current \c Number type. The default result
738 728
    /// type of this function is <tt>unsigned int</tt>.
739 729
    template <typename Number>
740 730
    Number uinteger() {
741 731
      return _random_bits::IntConversion<Number, Word>::convert(core);
742 732
    }
743 733

	
744 734
    unsigned int uinteger() {
745 735
      return uinteger<unsigned int>();
746 736
    }
747 737

	
748 738
    /// \brief Returns a random integer
749 739
    ///
750 740
    /// It returns a random integer uniformly from the whole range of
751 741
    /// the current \c Number type. The default result type of this
752 742
    /// function is \c int.
753 743
    template <typename Number>
754 744
    Number integer() {
755 745
      static const int nb = std::numeric_limits<Number>::digits +
756 746
        (std::numeric_limits<Number>::is_signed ? 1 : 0);
757 747
      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
758 748
    }
759 749

	
760 750
    int integer() {
761 751
      return integer<int>();
762 752
    }
763 753

	
764 754
    /// \brief Returns a random bool
765 755
    ///
766 756
    /// It returns a random bool. The generator holds a buffer for
767 757
    /// random bits. Every time when it become empty the generator makes
768 758
    /// a new random word and fill the buffer up.
769 759
    bool boolean() {
770 760
      return bool_producer.convert(core);
771 761
    }
772 762

	
773 763
    /// @}
774 764

	
775 765
    ///\name Non-uniform distributions
776 766
    ///
777 767
    ///@{
778 768

	
779 769
    /// \brief Returns a random bool with given probability of true result.
780 770
    ///
781 771
    /// It returns a random bool with given probability of true result.
782 772
    bool boolean(double p) {
783 773
      return operator()() < p;
784 774
    }
785 775

	
786 776
    /// Standard normal (Gauss) distribution
787 777

	
788 778
    /// Standard normal (Gauss) distribution.
789 779
    /// \note The Cartesian form of the Box-Muller
790 780
    /// transformation is used to generate a random normal distribution.
791 781
    double gauss()
792 782
    {
793 783
      double V1,V2,S;
794 784
      do {
795 785
        V1=2*real<double>()-1;
796 786
        V2=2*real<double>()-1;
797 787
        S=V1*V1+V2*V2;
798 788
      } while(S>=1);
799 789
      return std::sqrt(-2*std::log(S)/S)*V1;
800 790
    }
801 791
    /// Normal (Gauss) distribution with given mean and standard deviation
802 792

	
803 793
    /// Normal (Gauss) distribution with given mean and standard deviation.
804 794
    /// \sa gauss()
805 795
    double gauss(double mean,double std_dev)
806 796
    {
807 797
      return gauss()*std_dev+mean;
808 798
    }
809 799

	
810 800
    /// Lognormal distribution
811 801

	
812 802
    /// Lognormal distribution. The parameters are the mean and the standard
813 803
    /// deviation of <tt>exp(X)</tt>.
814 804
    ///
815 805
    double lognormal(double n_mean,double n_std_dev)
816 806
    {
817 807
      return std::exp(gauss(n_mean,n_std_dev));
818 808
    }
819 809
    /// Lognormal distribution
820 810

	
821 811
    /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
822 812
    /// the mean and the standard deviation of <tt>exp(X)</tt>.
823 813
    ///
824 814
    double lognormal(const std::pair<double,double> &params)
825 815
    {
826 816
      return std::exp(gauss(params.first,params.second));
827 817
    }
828 818
    /// Compute the lognormal parameters from mean and standard deviation
829 819

	
830 820
    /// This function computes the lognormal parameters from mean and
831 821
    /// standard deviation. The return value can direcly be passed to
832 822
    /// lognormal().
833 823
    std::pair<double,double> lognormalParamsFromMD(double mean,
834 824
                                                   double std_dev)
835 825
    {
836 826
      double fr=std_dev/mean;
837 827
      fr*=fr;
838 828
      double lg=std::log(1+fr);
839 829
      return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
840 830
    }
841 831
    /// Lognormal distribution with given mean and standard deviation
842 832

	
843 833
    /// Lognormal distribution with given mean and standard deviation.
844 834
    ///
845 835
    double lognormalMD(double mean,double std_dev)
846 836
    {
847 837
      return lognormal(lognormalParamsFromMD(mean,std_dev));
848 838
    }
849 839

	
850 840
    /// Exponential distribution with given mean
851 841

	
852 842
    /// This function generates an exponential distribution random number
853 843
    /// with mean <tt>1/lambda</tt>.
854 844
    ///
855 845
    double exponential(double lambda=1.0)
856 846
    {
857 847
      return -std::log(1.0-real<double>())/lambda;
858 848
    }
859 849

	
860 850
    /// Gamma distribution with given integer shape
861 851

	
862 852
    /// This function generates a gamma distribution random number.
863 853
    ///
864 854
    ///\param k shape parameter (<tt>k>0</tt> integer)
865 855
    double gamma(int k)
866 856
    {
867 857
      double s = 0;
868 858
      for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
869 859
      return s;
870 860
    }
871 861

	
872 862
    /// Gamma distribution with given shape and scale parameter
873 863

	
874 864
    /// This function generates a gamma distribution random number.
875 865
    ///
876 866
    ///\param k shape parameter (<tt>k>0</tt>)
877 867
    ///\param theta scale parameter
878 868
    ///
879 869
    double gamma(double k,double theta=1.0)
880 870
    {
881 871
      double xi,nu;
882 872
      const double delta = k-std::floor(k);
883 873
      const double v0=E/(E-delta);
884 874
      do {
885 875
        double V0=1.0-real<double>();
886 876
        double V1=1.0-real<double>();
887 877
        double V2=1.0-real<double>();
888 878
        if(V2<=v0)
889 879
          {
890 880
            xi=std::pow(V1,1.0/delta);
891 881
            nu=V0*std::pow(xi,delta-1.0);
892 882
          }
893 883
        else
894 884
          {
895 885
            xi=1.0-std::log(V1);
896 886
            nu=V0*std::exp(-xi);
897 887
          }
898 888
      } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
899 889
      return theta*(xi+gamma(int(std::floor(k))));
900 890
    }
901 891

	
902 892
    /// Weibull distribution
903 893

	
904 894
    /// This function generates a Weibull distribution random number.
905 895
    ///
906 896
    ///\param k shape parameter (<tt>k>0</tt>)
907 897
    ///\param lambda scale parameter (<tt>lambda>0</tt>)
908 898
    ///
909 899
    double weibull(double k,double lambda)
910 900
    {
911 901
      return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
912 902
    }
913 903

	
914 904
    /// Pareto distribution
915 905

	
916 906
    /// This function generates a Pareto distribution random number.
917 907
    ///
918 908
    ///\param k shape parameter (<tt>k>0</tt>)
919 909
    ///\param x_min location parameter (<tt>x_min>0</tt>)
920 910
    ///
921 911
    double pareto(double k,double x_min)
922 912
    {
923 913
      return exponential(gamma(k,1.0/x_min))+x_min;
924 914
    }
925 915

	
926 916
    /// Poisson distribution
927 917

	
928 918
    /// This function generates a Poisson distribution random number with
929 919
    /// parameter \c lambda.
930 920
    ///
931 921
    /// The probability mass function of this distribusion is
932 922
    /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
933 923
    /// \note The algorithm is taken from the book of Donald E. Knuth titled
934 924
    /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
935 925
    /// return value.
936 926

	
937 927
    int poisson(double lambda)
938 928
    {
939 929
      const double l = std::exp(-lambda);
940 930
      int k=0;
941 931
      double p = 1.0;
942 932
      do {
943 933
        k++;
944 934
        p*=real<double>();
945 935
      } while (p>=l);
946 936
      return k-1;
947 937
    }
948 938

	
949 939
    ///@}
950 940

	
951 941
    ///\name Two dimensional distributions
952 942
    ///
953 943
    ///@{
954 944

	
955 945
    /// Uniform distribution on the full unit circle
956 946

	
957 947
    /// Uniform distribution on the full unit circle.
958 948
    ///
959 949
    dim2::Point<double> disc()
960 950
    {
961 951
      double V1,V2;
962 952
      do {
963 953
        V1=2*real<double>()-1;
964 954
        V2=2*real<double>()-1;
965 955

	
966 956
      } while(V1*V1+V2*V2>=1);
967 957
      return dim2::Point<double>(V1,V2);
968 958
    }
969 959
    /// A kind of two dimensional normal (Gauss) distribution
970 960

	
971 961
    /// This function provides a turning symmetric two-dimensional distribution.
972 962
    /// Both coordinates are of standard normal distribution, but they are not
973 963
    /// independent.
974 964
    ///
975 965
    /// \note The coordinates are the two random variables provided by
976 966
    /// the Box-Muller method.
977 967
    dim2::Point<double> gauss2()
978 968
    {
979 969
      double V1,V2,S;
980 970
      do {
981 971
        V1=2*real<double>()-1;
982 972
        V2=2*real<double>()-1;
983 973
        S=V1*V1+V2*V2;
984 974
      } while(S>=1);
985 975
      double W=std::sqrt(-2*std::log(S)/S);
986 976
      return dim2::Point<double>(W*V1,W*V2);
987 977
    }
988 978
    /// A kind of two dimensional exponential distribution
989 979

	
990 980
    /// This function provides a turning symmetric two-dimensional distribution.
991 981
    /// The x-coordinate is of conditionally exponential distribution
992 982
    /// with the condition that x is positive and y=0. If x is negative and
993 983
    /// y=0 then, -x is of exponential distribution. The same is true for the
994 984
    /// y-coordinate.
995 985
    dim2::Point<double> exponential2()
996 986
    {
997 987
      double V1,V2,S;
998 988
      do {
999 989
        V1=2*real<double>()-1;
1000 990
        V2=2*real<double>()-1;
1001 991
        S=V1*V1+V2*V2;
1002 992
      } while(S>=1);
1003 993
      double W=-std::log(S)/S;
1004 994
      return dim2::Point<double>(W*V1,W*V2);
1005 995
    }
1006 996

	
1007 997
    ///@}
1008 998
  };
1009 999

	
1010 1000

	
1011 1001
  extern Random rnd;
1012 1002

	
1013 1003
}
1014 1004

	
1015 1005
#endif
Ignore white space 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-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
#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)