0
11
1
83
65
90
64
29
13
9
19
9
219
... | ... |
@@ -9,32 +9,33 @@ |
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/.* |
... | ... |
@@ -10,32 +10,35 @@ |
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 |
... | ... |
@@ -11,32 +11,38 @@ |
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 |
... | ... |
@@ -103,32 +109,34 @@ |
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 |
... | ... |
@@ -83,33 +83,33 @@ |
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 |
|
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 |
... | ... |
@@ -15,33 +15,41 @@ |
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 |
{ |
... | ... |
@@ -74,53 +82,41 @@ |
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; |
... | ... |
@@ -377,63 +377,39 @@ |
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, |
... | ... |
@@ -571,38 +547,39 @@ |
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 |
|
... | ... |
@@ -1199,64 +1176,73 @@ |
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 |
|
|
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 |
|
|
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 |
|
|
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 '-'. |
... | ... |
@@ -1357,36 +1343,38 @@ |
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 |
|
... | ... |
@@ -2031,32 +2019,62 @@ |
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 |
... | ... |
@@ -337,64 +337,43 @@ |
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 |
|
|
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 |
... | ... |
@@ -513,38 +492,41 @@ |
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; |
... | ... |
@@ -920,65 +902,75 @@ |
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 |
|
|
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 |
|
|
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. |
... | ... |
@@ -1068,39 +1060,42 @@ |
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; |
... | ... |
@@ -1521,32 +1516,63 @@ |
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 |
... | ... |
@@ -916,69 +916,85 @@ |
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 |
|
|
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 |
|
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 |
|
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. |
... | ... |
@@ -331,112 +331,102 @@ |
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 |
|
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 |
|
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, |
|
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, |
|
372 |
struct ShiftMultiplier<Result, 32> { |
|
383 | 373 |
static const Result multiplier() { |
384 |
return static_cast<Result>(1.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, |
|
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, |
|
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, |
|
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, |
|
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()); |
... | ... |
@@ -25,72 +25,69 @@ |
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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; |
... | ... |
@@ -225,228 +222,21 @@ |
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)