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

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

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

	
10 10
PROJECT(${PROJECT_NAME})
11 11

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

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

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

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

	
26 29
ENABLE_TESTING()
27 30

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

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

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

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

	
47 50
  SET(CPACK_COMPONENTS_ALL headers library html_documentation)
48 51

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

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

	
60 63
  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
61 64

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

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

	
71 74
  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
72 75

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
109 115
AC_OUTPUT
110 116

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

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

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

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

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

	
30 30
namespace lemon {
31 31

	
32 32

	
33 33
  //#ifndef LEMON_USE_DEBUG_MAP
34 34

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

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

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

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

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

	
62 62

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

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

	
74 74

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

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

	
86 86

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

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

	
98 98

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

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

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

	
112 112
#endif
113 113

	
114 114

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

	
121 121

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

	
128 128

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

	
135 135

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

	
142 142
// #else
143 143

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

	
149 149
// #endif
150 150

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

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

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

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

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

	
176 176
  };
177 177

	
178 178
}
179 179

	
180 180
#endif
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 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 192 line context
1 1
/* Define to 1 if you have CPLEX. */
2 2
#undef HAVE_CPLEX
3 3

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

	
7
/* Define to 1 if you have long long */
8
#undef HAVE_LONG_LONG
Ignore white space 192 line context
... ...
@@ -297,392 +297,369 @@
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.
... ...
@@ -1119,354 +1096,365 @@
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

	
... ...
@@ -1951,192 +1939,222 @@
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
Ignore white space 192 line context
... ...
@@ -257,374 +257,356 @@
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,
... ...
@@ -840,347 +822,360 @@
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
... ...
@@ -1441,192 +1436,223 @@
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
    ///
Ignore white space 192 line context
... ...
@@ -836,229 +836,245 @@
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;
Ignore white space 192 line context
... ...
@@ -251,272 +251,262 @@
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
  ///
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_TOLERANCE_H
20 20
#define LEMON_TOLERANCE_H
21 21

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

	
28 28
namespace lemon {
29 29

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

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

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

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

	
64 61
    ///@{
65 62

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

	
77 74
    ///@}
78 75

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

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

	
87 84

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

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

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

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

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

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

	
120 117
    ///@{
121 118

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

	
133 130
    ///@}
134 131

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

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

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

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

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

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

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

	
171 168
    ///@{
172 169

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

	
184 181
    ///@}
185 182

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

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

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

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

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

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

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

	
222 219
    ///@{
223 220

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

	
235 232
    ///@}
236 233

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

	
241
  ///Integer specialization of Tolerance.
242

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

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

	
255
    ///@{
256

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

	
268
    ///@}
269

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

	
274
  ///Unsigned integer specialization of Tolerance.
275

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

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

	
288
    ///@{
289

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

	
301
    ///@}
302

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

	
307

	
308
  ///Long integer specialization of Tolerance.
309

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

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

	
322
    ///@{
323

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

	
335
    ///@}
336

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

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

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

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

	
355
    ///@{
356

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

	
368
    ///@}
369

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

	
374
#if defined __GNUC__ && !defined __STRICT_ANSI__
375

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

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

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

	
392
    ///@{
393

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

	
405
    ///@}
406

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

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

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

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

	
427
    ///@{
428

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

	
440
    ///@}
441

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

	
446
#endif
447

	
448 238
  /// @}
449 239

	
450 240
} //namespace lemon
451 241

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