From ef4a319984d22b88a9024ff523700d657621124d Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Tue, 10 Jul 2012 13:44:21 +1000 Subject: Add the LEMON graph library source to the repo I'll likely be using it, so this just makes it easier to get to from elsewhere. If I end up not using it then I can just delete it. --- lemon/AUTHORS | 26 + lemon/CMakeLists.txt | 217 + lemon/INSTALL | 197 + lemon/LICENSE | 32 + lemon/Makefile | 2241 +++ lemon/Makefile.am | 80 + lemon/Makefile.in | 2241 +++ lemon/NEWS | 260 + lemon/README | 50 + lemon/aclocal.m4 | 960 + lemon/build-aux/config.guess | 1511 ++ lemon/build-aux/config.sub | 1705 ++ lemon/build-aux/depcomp | 630 + lemon/build-aux/install-sh | 520 + lemon/build-aux/ltmain.sh | 8406 +++++++++ lemon/build-aux/missing | 376 + lemon/cmake/FindCOIN.cmake | 98 + lemon/cmake/FindCPLEX.cmake | 38 + lemon/cmake/FindGLPK.cmake | 61 + lemon/cmake/FindGhostscript.cmake | 10 + lemon/cmake/LEMONConfig.cmake.in | 13 + lemon/cmake/nsis/lemon.ico | Bin 0 -> 22486 bytes lemon/cmake/nsis/uninstall.ico | Bin 0 -> 15086 bytes lemon/cmake/version.cmake | 1 + lemon/cmake/version.cmake.in | 1 + lemon/config.h | 126 + lemon/config.h.in | 125 + lemon/config.log | 1252 ++ lemon/config.status | 2321 +++ lemon/configure | 18910 +++++++++++++++++++ lemon/configure.ac | 157 + lemon/demo/.deps/arg_parser_demo.Po | 1 + lemon/demo/.deps/graph_to_eps_demo.Po | 1 + lemon/demo/.deps/lgf_demo.Po | 1 + lemon/demo/CMakeLists.txt | 19 + lemon/demo/Makefile | 523 + lemon/demo/Makefile.am | 17 + lemon/demo/Makefile.in | 523 + lemon/demo/arg_parser_demo.cc | 112 + lemon/demo/digraph.lgf | 29 + lemon/demo/graph_to_eps_demo.cc | 206 + lemon/demo/lgf_demo.cc | 70 + lemon/doc/CMakeLists.txt | 74 + lemon/doc/Doxyfile | 291 + lemon/doc/Doxyfile.in | 291 + lemon/doc/DoxygenLayout.xml | 182 + lemon/doc/Makefile.am | 123 + lemon/doc/coding_style.dox | 127 + lemon/doc/dirs.dox | 77 + lemon/doc/groups.dox | 702 + lemon/doc/images/bipartite_matching.eps | 586 + lemon/doc/images/bipartite_partitions.eps | 114 + lemon/doc/images/connected_components.eps | 159 + lemon/doc/images/edge_biconnected_components.eps | 159 + lemon/doc/images/grid_graph.eps | 286 + lemon/doc/images/matching.eps | 130 + lemon/doc/images/node_biconnected_components.eps | 159 + lemon/doc/images/nodeshape_0.eps | 57 + lemon/doc/images/nodeshape_1.eps | 57 + lemon/doc/images/nodeshape_2.eps | 57 + lemon/doc/images/nodeshape_3.eps | 77 + lemon/doc/images/nodeshape_4.eps | 77 + lemon/doc/images/planar.eps | 181 + lemon/doc/images/strongly_connected_components.eps | 180 + lemon/doc/lgf.dox | 118 + lemon/doc/license.dox | 25 + lemon/doc/mainpage.dox | 61 + lemon/doc/mainpage.dox.in | 61 + lemon/doc/migration.dox | 145 + lemon/doc/min_cost_flow.dox | 153 + lemon/doc/named-param.dox | 119 + lemon/doc/namespaces.dox | 30 + lemon/lemon/.deps/.dirstamp | 0 lemon/lemon/.deps/lemon_libemon_la-arg_parser.Plo | 357 + lemon/lemon/.deps/lemon_libemon_la-base.Plo | 348 + lemon/lemon/.deps/lemon_libemon_la-cbc.Plo | 1 + lemon/lemon/.deps/lemon_libemon_la-clp.Plo | 1 + lemon/lemon/.deps/lemon_libemon_la-color.Plo | 399 + lemon/lemon/.deps/lemon_libemon_la-cplex.Plo | 1 + lemon/lemon/.deps/lemon_libemon_la-glpk.Plo | 1 + lemon/lemon/.deps/lemon_libemon_la-lp_base.Plo | 393 + lemon/lemon/.deps/lemon_libemon_la-lp_skeleton.Plo | 395 + lemon/lemon/.deps/lemon_libemon_la-random.Plo | 410 + lemon/lemon/.deps/lemon_libemon_la-soplex.Plo | 1 + lemon/lemon/.dirstamp | 0 lemon/lemon/CMakeLists.txt | 80 + lemon/lemon/Makefile.am | 151 + lemon/lemon/adaptors.h | 3638 ++++ lemon/lemon/arg_parser.cc | 474 + lemon/lemon/arg_parser.h | 440 + lemon/lemon/assert.h | 214 + lemon/lemon/base.cc | 34 + lemon/lemon/bellman_ford.h | 1115 ++ lemon/lemon/bfs.h | 1753 ++ lemon/lemon/bin_heap.h | 347 + lemon/lemon/binomial_heap.h | 445 + lemon/lemon/bits/.deps/.dirstamp | 0 .../lemon/bits/.deps/lemon_libemon_la-windows.Plo | 316 + lemon/lemon/bits/.dirstamp | 0 lemon/lemon/bits/alteration_notifier.h | 467 + lemon/lemon/bits/array_map.h | 351 + lemon/lemon/bits/bezier.h | 174 + lemon/lemon/bits/default_map.h | 182 + lemon/lemon/bits/edge_set_extender.h | 627 + lemon/lemon/bits/enable_if.h | 131 + lemon/lemon/bits/graph_adaptor_extender.h | 401 + lemon/lemon/bits/graph_extender.h | 751 + lemon/lemon/bits/map_extender.h | 332 + lemon/lemon/bits/path_dump.h | 177 + lemon/lemon/bits/solver_bits.h | 193 + lemon/lemon/bits/traits.h | 306 + lemon/lemon/bits/variant.h | 494 + lemon/lemon/bits/vector_map.h | 244 + lemon/lemon/bits/windows.cc | 134 + lemon/lemon/bits/windows.h | 34 + lemon/lemon/bucket_heap.h | 594 + lemon/lemon/capacity_scaling.h | 990 + lemon/lemon/cbc.cc | 475 + lemon/lemon/cbc.h | 130 + lemon/lemon/circulation.h | 808 + lemon/lemon/clp.cc | 466 + lemon/lemon/clp.h | 164 + lemon/lemon/color.cc | 44 + lemon/lemon/color.h | 204 + lemon/lemon/concept_check.h | 61 + lemon/lemon/concepts/digraph.h | 489 + lemon/lemon/concepts/graph.h | 786 + lemon/lemon/concepts/graph_components.h | 1516 ++ lemon/lemon/concepts/heap.h | 323 + lemon/lemon/concepts/maps.h | 217 + lemon/lemon/concepts/path.h | 310 + lemon/lemon/config.h | 27 + lemon/lemon/config.h.cmake | 8 + lemon/lemon/config.h.in | 26 + lemon/lemon/connectivity.h | 1665 ++ lemon/lemon/core.h | 1868 ++ lemon/lemon/cost_scaling.h | 1316 ++ lemon/lemon/counter.h | 249 + lemon/lemon/cplex.cc | 984 + lemon/lemon/cplex.h | 277 + lemon/lemon/cycle_canceling.h | 1170 ++ lemon/lemon/dfs.h | 1636 ++ lemon/lemon/dheap.h | 352 + lemon/lemon/dijkstra.h | 1303 ++ lemon/lemon/dim2.h | 725 + lemon/lemon/dimacs.h | 448 + lemon/lemon/edge_set.h | 1420 ++ lemon/lemon/elevator.h | 982 + lemon/lemon/error.h | 276 + lemon/lemon/euler.h | 287 + lemon/lemon/fib_heap.h | 475 + lemon/lemon/fractional_matching.h | 2139 +++ lemon/lemon/full_graph.h | 628 + lemon/lemon/glpk.cc | 1003 + lemon/lemon/glpk.h | 248 + lemon/lemon/gomory_hu.h | 568 + lemon/lemon/graph_to_eps.h | 1187 ++ lemon/lemon/grid_graph.h | 699 + lemon/lemon/hao_orlin.h | 1005 + lemon/lemon/hartmann_orlin_mmc.h | 650 + lemon/lemon/howard_mmc.h | 605 + lemon/lemon/hypercube_graph.h | 459 + lemon/lemon/karp_mmc.h | 590 + lemon/lemon/kruskal.h | 327 + lemon/lemon/lemon.pc | 10 + lemon/lemon/lemon.pc.cmake | 10 + lemon/lemon/lemon.pc.in | 10 + lemon/lemon/lgf_reader.h | 2750 +++ lemon/lemon/lgf_writer.h | 1835 ++ lemon/lemon/list_graph.h | 1605 ++ lemon/lemon/lp.h | 93 + lemon/lemon/lp_base.cc | 30 + lemon/lemon/lp_base.h | 2102 +++ lemon/lemon/lp_skeleton.cc | 141 + lemon/lemon/lp_skeleton.h | 229 + lemon/lemon/maps.h | 4057 ++++ lemon/lemon/matching.h | 3505 ++++ lemon/lemon/math.h | 72 + lemon/lemon/min_cost_arborescence.h | 808 + lemon/lemon/nauty_reader.h | 113 + lemon/lemon/network_simplex.h | 1621 ++ lemon/lemon/pairing_heap.h | 474 + lemon/lemon/path.h | 1112 ++ lemon/lemon/planarity.h | 2755 +++ lemon/lemon/preflow.h | 985 + lemon/lemon/quad_heap.h | 343 + lemon/lemon/radix_heap.h | 438 + lemon/lemon/radix_sort.h | 487 + lemon/lemon/random.cc | 29 + lemon/lemon/random.h | 1005 + lemon/lemon/smart_graph.h | 817 + lemon/lemon/soplex.cc | 465 + lemon/lemon/soplex.h | 158 + lemon/lemon/stamp-h2 | 1 + lemon/lemon/static_graph.h | 476 + lemon/lemon/suurballe.h | 776 + lemon/lemon/time_measure.h | 552 + lemon/lemon/tolerance.h | 242 + lemon/lemon/unionfind.h | 1824 ++ lemon/libtool | 9055 +++++++++ lemon/m4/libtool.m4 | 7365 ++++++++ lemon/m4/ltoptions.m4 | 368 + lemon/m4/ltsugar.m4 | 123 + lemon/m4/ltversion.m4 | 23 + lemon/m4/lt~obsolete.m4 | 92 + lemon/m4/lx_check_coin.m4 | 136 + lemon/m4/lx_check_cplex.m4 | 81 + lemon/m4/lx_check_glpk.m4 | 84 + lemon/m4/lx_check_soplex.m4 | 73 + lemon/scripts/Makefile.am | 7 + lemon/scripts/bib2dox.py | 816 + lemon/scripts/bootstrap.sh | 157 + lemon/scripts/chg-len.py | 46 + lemon/scripts/mk-release.sh | 49 + lemon/scripts/unify-sources.sh | 390 + lemon/scripts/valgrind-wrapper.sh | 22 + lemon/stamp-h1 | 1 + lemon/test/.deps/adaptors_test.Po | 1 + lemon/test/.deps/bellman_ford_test.Po | 1 + lemon/test/.deps/bfs_test.Po | 1 + lemon/test/.deps/circulation_test.Po | 1 + lemon/test/.deps/connectivity_test.Po | 1 + lemon/test/.deps/counter_test.Po | 1 + lemon/test/.deps/dfs_test.Po | 1 + lemon/test/.deps/digraph_test.Po | 1 + lemon/test/.deps/dijkstra_test.Po | 1 + lemon/test/.deps/dim_test.Po | 1 + lemon/test/.deps/edge_set_test.Po | 1 + lemon/test/.deps/error_test.Po | 1 + lemon/test/.deps/euler_test.Po | 1 + lemon/test/.deps/fractional_matching_test.Po | 1 + lemon/test/.deps/gomory_hu_test.Po | 1 + lemon/test/.deps/graph_copy_test.Po | 1 + lemon/test/.deps/graph_test.Po | 1 + lemon/test/.deps/graph_utils_test.Po | 1 + lemon/test/.deps/hao_orlin_test.Po | 1 + lemon/test/.deps/heap_test.Po | 1 + lemon/test/.deps/kruskal_test.Po | 1 + lemon/test/.deps/lgf_test.Po | 1 + lemon/test/.deps/lp_test.Po | 1 + lemon/test/.deps/maps_test.Po | 1 + lemon/test/.deps/matching_test.Po | 1 + lemon/test/.deps/min_cost_arborescence_test.Po | 1 + lemon/test/.deps/min_cost_flow_test.Po | 1 + lemon/test/.deps/min_mean_cycle_test.Po | 1 + lemon/test/.deps/mip_test.Po | 1 + lemon/test/.deps/path_test.Po | 1 + lemon/test/.deps/planarity_test.Po | 1 + lemon/test/.deps/preflow_test.Po | 1 + lemon/test/.deps/radix_sort_test.Po | 1 + lemon/test/.deps/random_test.Po | 1 + lemon/test/.deps/suurballe_test.Po | 1 + lemon/test/.deps/test_tools_fail.Po | 1 + lemon/test/.deps/test_tools_pass.Po | 1 + lemon/test/.deps/time_measure_test.Po | 1 + lemon/test/.deps/unionfind_test.Po | 1 + lemon/test/CMakeLists.txt | 151 + lemon/test/Makefile.am | 101 + lemon/test/adaptors_test.cc | 1463 ++ lemon/test/bellman_ford_test.cc | 285 + lemon/test/bfs_test.cc | 236 + lemon/test/circulation_test.cc | 168 + lemon/test/connectivity_test.cc | 297 + lemon/test/counter_test.cc | 118 + lemon/test/dfs_test.cc | 234 + lemon/test/digraph_test.cc | 562 + lemon/test/dijkstra_test.cc | 242 + lemon/test/dim_test.cc | 87 + lemon/test/edge_set_test.cc | 380 + lemon/test/error_test.cc | 90 + lemon/test/euler_test.cc | 223 + lemon/test/fractional_matching_test.cc | 525 + lemon/test/gomory_hu_test.cc | 141 + lemon/test/graph_copy_test.cc | 215 + lemon/test/graph_test.cc | 597 + lemon/test/graph_test.h | 293 + lemon/test/graph_utils_test.cc | 217 + lemon/test/hao_orlin_test.cc | 163 + lemon/test/heap_test.cc | 310 + lemon/test/kruskal_test.cc | 147 + lemon/test/lgf_test.cc | 169 + lemon/test/lp_test.cc | 427 + lemon/test/maps_test.cc | 1003 + lemon/test/matching_test.cc | 448 + lemon/test/min_cost_arborescence_test.cc | 206 + lemon/test/min_cost_flow_test.cc | 542 + lemon/test/min_mean_cycle_test.cc | 216 + lemon/test/mip_test.cc | 159 + lemon/test/path_test.cc | 44 + lemon/test/planarity_test.cc | 262 + lemon/test/preflow_test.cc | 276 + lemon/test/radix_sort_test.cc | 147 + lemon/test/random_test.cc | 40 + lemon/test/suurballe_test.cc | 265 + lemon/test/test_tools.h | 50 + lemon/test/test_tools_fail.cc | 25 + lemon/test/test_tools_pass.cc | 25 + lemon/test/time_measure_test.cc | 56 + lemon/test/unionfind_test.cc | 102 + lemon/tools/.deps/.dirstamp | 0 lemon/tools/.deps/dimacs-solver.Po | 543 + lemon/tools/.deps/dimacs-to-lgf.Po | 439 + lemon/tools/.deps/lgf-gen.Po | 567 + lemon/tools/.dirstamp | 0 lemon/tools/CMakeLists.txt | 31 + lemon/tools/Makefile.am | 17 + lemon/tools/dimacs-solver.cc | 280 + lemon/tools/dimacs-to-lgf.cc | 148 + lemon/tools/lemon-0.x-to-1.x.sh | 134 + lemon/tools/lgf-gen.cc | 834 + 310 files changed, 163973 insertions(+) create mode 100644 lemon/AUTHORS create mode 100644 lemon/CMakeLists.txt create mode 100644 lemon/INSTALL create mode 100644 lemon/LICENSE create mode 100644 lemon/Makefile create mode 100644 lemon/Makefile.am create mode 100644 lemon/Makefile.in create mode 100644 lemon/NEWS create mode 100644 lemon/README create mode 100644 lemon/aclocal.m4 create mode 100755 lemon/build-aux/config.guess create mode 100755 lemon/build-aux/config.sub create mode 100755 lemon/build-aux/depcomp create mode 100755 lemon/build-aux/install-sh create mode 100755 lemon/build-aux/ltmain.sh create mode 100755 lemon/build-aux/missing create mode 100644 lemon/cmake/FindCOIN.cmake create mode 100644 lemon/cmake/FindCPLEX.cmake create mode 100644 lemon/cmake/FindGLPK.cmake create mode 100644 lemon/cmake/FindGhostscript.cmake create mode 100644 lemon/cmake/LEMONConfig.cmake.in create mode 100644 lemon/cmake/nsis/lemon.ico create mode 100644 lemon/cmake/nsis/uninstall.ico create mode 100644 lemon/cmake/version.cmake create mode 100644 lemon/cmake/version.cmake.in create mode 100644 lemon/config.h create mode 100644 lemon/config.h.in create mode 100644 lemon/config.log create mode 100755 lemon/config.status create mode 100755 lemon/configure create mode 100644 lemon/configure.ac create mode 100644 lemon/demo/.deps/arg_parser_demo.Po create mode 100644 lemon/demo/.deps/graph_to_eps_demo.Po create mode 100644 lemon/demo/.deps/lgf_demo.Po create mode 100644 lemon/demo/CMakeLists.txt create mode 100644 lemon/demo/Makefile create mode 100644 lemon/demo/Makefile.am create mode 100644 lemon/demo/Makefile.in create mode 100644 lemon/demo/arg_parser_demo.cc create mode 100644 lemon/demo/digraph.lgf create mode 100644 lemon/demo/graph_to_eps_demo.cc create mode 100644 lemon/demo/lgf_demo.cc create mode 100644 lemon/doc/CMakeLists.txt create mode 100644 lemon/doc/Doxyfile create mode 100644 lemon/doc/Doxyfile.in create mode 100644 lemon/doc/DoxygenLayout.xml create mode 100644 lemon/doc/Makefile.am create mode 100644 lemon/doc/coding_style.dox create mode 100644 lemon/doc/dirs.dox create mode 100644 lemon/doc/groups.dox create mode 100644 lemon/doc/images/bipartite_matching.eps create mode 100644 lemon/doc/images/bipartite_partitions.eps create mode 100644 lemon/doc/images/connected_components.eps create mode 100644 lemon/doc/images/edge_biconnected_components.eps create mode 100644 lemon/doc/images/grid_graph.eps create mode 100644 lemon/doc/images/matching.eps create mode 100644 lemon/doc/images/node_biconnected_components.eps create mode 100644 lemon/doc/images/nodeshape_0.eps create mode 100644 lemon/doc/images/nodeshape_1.eps create mode 100644 lemon/doc/images/nodeshape_2.eps create mode 100644 lemon/doc/images/nodeshape_3.eps create mode 100644 lemon/doc/images/nodeshape_4.eps create mode 100644 lemon/doc/images/planar.eps create mode 100644 lemon/doc/images/strongly_connected_components.eps create mode 100644 lemon/doc/lgf.dox create mode 100644 lemon/doc/license.dox create mode 100644 lemon/doc/mainpage.dox create mode 100644 lemon/doc/mainpage.dox.in create mode 100644 lemon/doc/migration.dox create mode 100644 lemon/doc/min_cost_flow.dox create mode 100644 lemon/doc/named-param.dox create mode 100644 lemon/doc/namespaces.dox create mode 100644 lemon/lemon/.deps/.dirstamp create mode 100644 lemon/lemon/.deps/lemon_libemon_la-arg_parser.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-base.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-cbc.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-clp.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-color.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-cplex.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-glpk.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-lp_base.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-lp_skeleton.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-random.Plo create mode 100644 lemon/lemon/.deps/lemon_libemon_la-soplex.Plo create mode 100644 lemon/lemon/.dirstamp create mode 100644 lemon/lemon/CMakeLists.txt create mode 100644 lemon/lemon/Makefile.am create mode 100644 lemon/lemon/adaptors.h create mode 100644 lemon/lemon/arg_parser.cc create mode 100644 lemon/lemon/arg_parser.h create mode 100644 lemon/lemon/assert.h create mode 100644 lemon/lemon/base.cc create mode 100644 lemon/lemon/bellman_ford.h create mode 100644 lemon/lemon/bfs.h create mode 100644 lemon/lemon/bin_heap.h create mode 100644 lemon/lemon/binomial_heap.h create mode 100644 lemon/lemon/bits/.deps/.dirstamp create mode 100644 lemon/lemon/bits/.deps/lemon_libemon_la-windows.Plo create mode 100644 lemon/lemon/bits/.dirstamp create mode 100644 lemon/lemon/bits/alteration_notifier.h create mode 100644 lemon/lemon/bits/array_map.h create mode 100644 lemon/lemon/bits/bezier.h create mode 100644 lemon/lemon/bits/default_map.h create mode 100644 lemon/lemon/bits/edge_set_extender.h create mode 100644 lemon/lemon/bits/enable_if.h create mode 100644 lemon/lemon/bits/graph_adaptor_extender.h create mode 100644 lemon/lemon/bits/graph_extender.h create mode 100644 lemon/lemon/bits/map_extender.h create mode 100644 lemon/lemon/bits/path_dump.h create mode 100644 lemon/lemon/bits/solver_bits.h create mode 100644 lemon/lemon/bits/traits.h create mode 100644 lemon/lemon/bits/variant.h create mode 100644 lemon/lemon/bits/vector_map.h create mode 100644 lemon/lemon/bits/windows.cc create mode 100644 lemon/lemon/bits/windows.h create mode 100644 lemon/lemon/bucket_heap.h create mode 100644 lemon/lemon/capacity_scaling.h create mode 100644 lemon/lemon/cbc.cc create mode 100644 lemon/lemon/cbc.h create mode 100644 lemon/lemon/circulation.h create mode 100644 lemon/lemon/clp.cc create mode 100644 lemon/lemon/clp.h create mode 100644 lemon/lemon/color.cc create mode 100644 lemon/lemon/color.h create mode 100644 lemon/lemon/concept_check.h create mode 100644 lemon/lemon/concepts/digraph.h create mode 100644 lemon/lemon/concepts/graph.h create mode 100644 lemon/lemon/concepts/graph_components.h create mode 100644 lemon/lemon/concepts/heap.h create mode 100644 lemon/lemon/concepts/maps.h create mode 100644 lemon/lemon/concepts/path.h create mode 100644 lemon/lemon/config.h create mode 100644 lemon/lemon/config.h.cmake create mode 100644 lemon/lemon/config.h.in create mode 100644 lemon/lemon/connectivity.h create mode 100644 lemon/lemon/core.h create mode 100644 lemon/lemon/cost_scaling.h create mode 100644 lemon/lemon/counter.h create mode 100644 lemon/lemon/cplex.cc create mode 100644 lemon/lemon/cplex.h create mode 100644 lemon/lemon/cycle_canceling.h create mode 100644 lemon/lemon/dfs.h create mode 100644 lemon/lemon/dheap.h create mode 100644 lemon/lemon/dijkstra.h create mode 100644 lemon/lemon/dim2.h create mode 100644 lemon/lemon/dimacs.h create mode 100644 lemon/lemon/edge_set.h create mode 100644 lemon/lemon/elevator.h create mode 100644 lemon/lemon/error.h create mode 100644 lemon/lemon/euler.h create mode 100644 lemon/lemon/fib_heap.h create mode 100644 lemon/lemon/fractional_matching.h create mode 100644 lemon/lemon/full_graph.h create mode 100644 lemon/lemon/glpk.cc create mode 100644 lemon/lemon/glpk.h create mode 100644 lemon/lemon/gomory_hu.h create mode 100644 lemon/lemon/graph_to_eps.h create mode 100644 lemon/lemon/grid_graph.h create mode 100644 lemon/lemon/hao_orlin.h create mode 100644 lemon/lemon/hartmann_orlin_mmc.h create mode 100644 lemon/lemon/howard_mmc.h create mode 100644 lemon/lemon/hypercube_graph.h create mode 100644 lemon/lemon/karp_mmc.h create mode 100644 lemon/lemon/kruskal.h create mode 100644 lemon/lemon/lemon.pc create mode 100644 lemon/lemon/lemon.pc.cmake create mode 100644 lemon/lemon/lemon.pc.in create mode 100644 lemon/lemon/lgf_reader.h create mode 100644 lemon/lemon/lgf_writer.h create mode 100644 lemon/lemon/list_graph.h create mode 100644 lemon/lemon/lp.h create mode 100644 lemon/lemon/lp_base.cc create mode 100644 lemon/lemon/lp_base.h create mode 100644 lemon/lemon/lp_skeleton.cc create mode 100644 lemon/lemon/lp_skeleton.h create mode 100644 lemon/lemon/maps.h create mode 100644 lemon/lemon/matching.h create mode 100644 lemon/lemon/math.h create mode 100644 lemon/lemon/min_cost_arborescence.h create mode 100644 lemon/lemon/nauty_reader.h create mode 100644 lemon/lemon/network_simplex.h create mode 100644 lemon/lemon/pairing_heap.h create mode 100644 lemon/lemon/path.h create mode 100644 lemon/lemon/planarity.h create mode 100644 lemon/lemon/preflow.h create mode 100644 lemon/lemon/quad_heap.h create mode 100644 lemon/lemon/radix_heap.h create mode 100644 lemon/lemon/radix_sort.h create mode 100644 lemon/lemon/random.cc create mode 100644 lemon/lemon/random.h create mode 100644 lemon/lemon/smart_graph.h create mode 100644 lemon/lemon/soplex.cc create mode 100644 lemon/lemon/soplex.h create mode 100644 lemon/lemon/stamp-h2 create mode 100644 lemon/lemon/static_graph.h create mode 100644 lemon/lemon/suurballe.h create mode 100644 lemon/lemon/time_measure.h create mode 100644 lemon/lemon/tolerance.h create mode 100644 lemon/lemon/unionfind.h create mode 100755 lemon/libtool create mode 100644 lemon/m4/libtool.m4 create mode 100644 lemon/m4/ltoptions.m4 create mode 100644 lemon/m4/ltsugar.m4 create mode 100644 lemon/m4/ltversion.m4 create mode 100644 lemon/m4/lt~obsolete.m4 create mode 100644 lemon/m4/lx_check_coin.m4 create mode 100644 lemon/m4/lx_check_cplex.m4 create mode 100644 lemon/m4/lx_check_glpk.m4 create mode 100644 lemon/m4/lx_check_soplex.m4 create mode 100644 lemon/scripts/Makefile.am create mode 100755 lemon/scripts/bib2dox.py create mode 100755 lemon/scripts/bootstrap.sh create mode 100755 lemon/scripts/chg-len.py create mode 100755 lemon/scripts/mk-release.sh create mode 100755 lemon/scripts/unify-sources.sh create mode 100755 lemon/scripts/valgrind-wrapper.sh create mode 100644 lemon/stamp-h1 create mode 100644 lemon/test/.deps/adaptors_test.Po create mode 100644 lemon/test/.deps/bellman_ford_test.Po create mode 100644 lemon/test/.deps/bfs_test.Po create mode 100644 lemon/test/.deps/circulation_test.Po create mode 100644 lemon/test/.deps/connectivity_test.Po create mode 100644 lemon/test/.deps/counter_test.Po create mode 100644 lemon/test/.deps/dfs_test.Po create mode 100644 lemon/test/.deps/digraph_test.Po create mode 100644 lemon/test/.deps/dijkstra_test.Po create mode 100644 lemon/test/.deps/dim_test.Po create mode 100644 lemon/test/.deps/edge_set_test.Po create mode 100644 lemon/test/.deps/error_test.Po create mode 100644 lemon/test/.deps/euler_test.Po create mode 100644 lemon/test/.deps/fractional_matching_test.Po create mode 100644 lemon/test/.deps/gomory_hu_test.Po create mode 100644 lemon/test/.deps/graph_copy_test.Po create mode 100644 lemon/test/.deps/graph_test.Po create mode 100644 lemon/test/.deps/graph_utils_test.Po create mode 100644 lemon/test/.deps/hao_orlin_test.Po create mode 100644 lemon/test/.deps/heap_test.Po create mode 100644 lemon/test/.deps/kruskal_test.Po create mode 100644 lemon/test/.deps/lgf_test.Po create mode 100644 lemon/test/.deps/lp_test.Po create mode 100644 lemon/test/.deps/maps_test.Po create mode 100644 lemon/test/.deps/matching_test.Po create mode 100644 lemon/test/.deps/min_cost_arborescence_test.Po create mode 100644 lemon/test/.deps/min_cost_flow_test.Po create mode 100644 lemon/test/.deps/min_mean_cycle_test.Po create mode 100644 lemon/test/.deps/mip_test.Po create mode 100644 lemon/test/.deps/path_test.Po create mode 100644 lemon/test/.deps/planarity_test.Po create mode 100644 lemon/test/.deps/preflow_test.Po create mode 100644 lemon/test/.deps/radix_sort_test.Po create mode 100644 lemon/test/.deps/random_test.Po create mode 100644 lemon/test/.deps/suurballe_test.Po create mode 100644 lemon/test/.deps/test_tools_fail.Po create mode 100644 lemon/test/.deps/test_tools_pass.Po create mode 100644 lemon/test/.deps/time_measure_test.Po create mode 100644 lemon/test/.deps/unionfind_test.Po create mode 100644 lemon/test/CMakeLists.txt create mode 100644 lemon/test/Makefile.am create mode 100644 lemon/test/adaptors_test.cc create mode 100644 lemon/test/bellman_ford_test.cc create mode 100644 lemon/test/bfs_test.cc create mode 100644 lemon/test/circulation_test.cc create mode 100644 lemon/test/connectivity_test.cc create mode 100644 lemon/test/counter_test.cc create mode 100644 lemon/test/dfs_test.cc create mode 100644 lemon/test/digraph_test.cc create mode 100644 lemon/test/dijkstra_test.cc create mode 100644 lemon/test/dim_test.cc create mode 100644 lemon/test/edge_set_test.cc create mode 100644 lemon/test/error_test.cc create mode 100644 lemon/test/euler_test.cc create mode 100644 lemon/test/fractional_matching_test.cc create mode 100644 lemon/test/gomory_hu_test.cc create mode 100644 lemon/test/graph_copy_test.cc create mode 100644 lemon/test/graph_test.cc create mode 100644 lemon/test/graph_test.h create mode 100644 lemon/test/graph_utils_test.cc create mode 100644 lemon/test/hao_orlin_test.cc create mode 100644 lemon/test/heap_test.cc create mode 100644 lemon/test/kruskal_test.cc create mode 100644 lemon/test/lgf_test.cc create mode 100644 lemon/test/lp_test.cc create mode 100644 lemon/test/maps_test.cc create mode 100644 lemon/test/matching_test.cc create mode 100644 lemon/test/min_cost_arborescence_test.cc create mode 100644 lemon/test/min_cost_flow_test.cc create mode 100644 lemon/test/min_mean_cycle_test.cc create mode 100644 lemon/test/mip_test.cc create mode 100644 lemon/test/path_test.cc create mode 100644 lemon/test/planarity_test.cc create mode 100644 lemon/test/preflow_test.cc create mode 100644 lemon/test/radix_sort_test.cc create mode 100644 lemon/test/random_test.cc create mode 100644 lemon/test/suurballe_test.cc create mode 100644 lemon/test/test_tools.h create mode 100644 lemon/test/test_tools_fail.cc create mode 100644 lemon/test/test_tools_pass.cc create mode 100644 lemon/test/time_measure_test.cc create mode 100644 lemon/test/unionfind_test.cc create mode 100644 lemon/tools/.deps/.dirstamp create mode 100644 lemon/tools/.deps/dimacs-solver.Po create mode 100644 lemon/tools/.deps/dimacs-to-lgf.Po create mode 100644 lemon/tools/.deps/lgf-gen.Po create mode 100644 lemon/tools/.dirstamp create mode 100644 lemon/tools/CMakeLists.txt create mode 100644 lemon/tools/Makefile.am create mode 100644 lemon/tools/dimacs-solver.cc create mode 100644 lemon/tools/dimacs-to-lgf.cc create mode 100755 lemon/tools/lemon-0.x-to-1.x.sh create mode 100644 lemon/tools/lgf-gen.cc diff --git a/lemon/AUTHORS b/lemon/AUTHORS new file mode 100644 index 0000000..749edd3 --- /dev/null +++ b/lemon/AUTHORS @@ -0,0 +1,26 @@ +The authors of the 1.x series are + + * Balazs Dezso + * Alpar Juttner + * Peter Kovacs + * Akos Ladanyi + +For more details on the actual contribution, please visit the history +of the main LEMON source repository: http://lemon.cs.elte.hu/hg/lemon + +Moreover, this version is heavily based on the 0.x series of +LEMON. Here is the list of people who contributed to those versions. + + * Mihaly Barasz + * Johanna Becker + * Attila Bernath + * Balazs Dezso + * Peter Hegyi + * Alpar Juttner + * Peter Kovacs + * Akos Ladanyi + * Marton Makai + * Jacint Szabo + +Again, please visit the history of the old LEMON repository for more +details: http://lemon.cs.elte.hu/hg/lemon-0.x \ No newline at end of file diff --git a/lemon/CMakeLists.txt b/lemon/CMakeLists.txt new file mode 100644 index 0000000..8cb6521 --- /dev/null +++ b/lemon/CMakeLists.txt @@ -0,0 +1,217 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(PROJECT_NAME "LEMON") +PROJECT(${PROJECT_NAME}) + +INCLUDE(FindPythonInterp) +INCLUDE(FindWget) + +IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake) + INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake) +ELSEIF(DEFINED ENV{LEMON_VERSION}) + SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.") +ELSE() + EXECUTE_PROCESS( + COMMAND ${PYTHON_EXECUTABLE} ./scripts/chg-len.py + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE HG_REVISION_PATH + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + EXECUTE_PROCESS( + COMMAND hg id -i + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE HG_REVISION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + IF(HG_REVISION STREQUAL "") + SET(HG_REVISION_ID "hg-tip") + ELSE() + IF(HG_REVISION_PATH STREQUAL "") + SET(HG_REVISION_ID ${HG_REVISION}) + ELSE() + SET(HG_REVISION_ID ${HG_REVISION_PATH}.${HG_REVISION}) + ENDIF() + ENDIF() + SET(LEMON_VERSION ${HG_REVISION_ID} CACHE STRING "LEMON version string.") +ENDIF() + +SET(PROJECT_VERSION ${LEMON_VERSION}) + +SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +FIND_PACKAGE(Doxygen) +FIND_PACKAGE(Ghostscript) +FIND_PACKAGE(GLPK 4.33) +FIND_PACKAGE(CPLEX) +FIND_PACKAGE(COIN) + +IF(DEFINED ENV{LEMON_CXX_WARNING}) + SET(CXX_WARNING $ENV{LEMON_CXX_WARNING}) +ELSE() + IF(CMAKE_COMPILER_IS_GNUCXX) + SET(CXX_WARNING "-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 -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas") + SET(CMAKE_CXX_FLAGS_DEBUG CACHE STRING "-ggdb") + SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb") + ELSEIF(MSVC) + # This part is unnecessary 'casue the same is set by the lemon/core.h. + # Still keep it as an example. + SET(CXX_WARNING "/wd4250 /wd4355 /wd4503 /wd4800 /wd4996") + # Suppressed warnings: + # C4250: 'class1' : inherits 'class2::member' via dominance + # C4355: 'this' : used in base member initializer list + # C4503: 'function' : decorated name length exceeded, name was truncated + # C4800: 'type' : forcing value to bool 'true' or 'false' + # (performance warning) + # C4996: 'function': was declared deprecated + ELSE() + SET(CXX_WARNING "-Wall -W") + ENDIF() +ENDIF() +SET(LEMON_CXX_WARNING_FLAGS ${CXX_WARNING} CACHE STRING "LEMON warning flags.") + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}") + +SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb" CACHE STRING + "Flags used by the C++ compiler during maintainer builds." + FORCE ) +SET( CMAKE_C_FLAGS_MAINTAINER "-Werror" CACHE STRING + "Flags used by the C compiler during maintainer builds." + FORCE ) +SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER + "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING + "Flags used for linking binaries during maintainer builds." + FORCE ) +SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER + "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING + "Flags used by the shared libraries linker during maintainer builds." + FORCE ) +MARK_AS_ADVANCED( + CMAKE_CXX_FLAGS_MAINTAINER + CMAKE_C_FLAGS_MAINTAINER + CMAKE_EXE_LINKER_FLAGS_MAINTAINER + CMAKE_SHARED_LINKER_FLAGS_MAINTAINER ) + +IF(CMAKE_CONFIGURATION_TYPES) + LIST(APPEND CMAKE_CONFIGURATION_TYPES Maintainer) + LIST(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES) + SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING + "Add the configurations that we need" + FORCE) + endif() + +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "Release") +ENDIF() + +SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING + "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel Maintainer." + FORCE ) + + +INCLUDE(CheckTypeSize) +CHECK_TYPE_SIZE("long long" LONG_LONG) +SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG}) + +INCLUDE(FindPythonInterp) + +ENABLE_TESTING() + +IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") + ADD_CUSTOM_TARGET(check ALL COMMAND ${CMAKE_CTEST_COMMAND}) +ELSE() + ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND}) +ENDIF() + +ADD_SUBDIRECTORY(lemon) +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) + ADD_SUBDIRECTORY(demo) + ADD_SUBDIRECTORY(tools) + ADD_SUBDIRECTORY(doc) + ADD_SUBDIRECTORY(test) +ENDIF() + +CONFIGURE_FILE( + ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in + ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake + @ONLY +) +IF(UNIX) + INSTALL( + FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake + DESTINATION share/lemon/cmake + ) +ELSEIF(WIN32) + INSTALL( + FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake + DESTINATION cmake + ) +ENDIF() + +IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR}) + SET(CPACK_PACKAGE_NAME ${PROJECT_NAME}) + SET(CPACK_PACKAGE_VENDOR "EGRES") + SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "LEMON - Library for Efficient Modeling and Optimization in Networks") + SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") + + SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) + + SET(CPACK_PACKAGE_INSTALL_DIRECTORY + "${PROJECT_NAME} ${PROJECT_VERSION}") + SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY + "${PROJECT_NAME} ${PROJECT_VERSION}") + + SET(CPACK_COMPONENTS_ALL headers library html_documentation bin) + + SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers") + SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library") + SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities") + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation") + + SET(CPACK_COMPONENT_HEADERS_DESCRIPTION + "C++ header files") + SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION + "DLL and import library") + SET(CPACK_COMPONENT_BIN_DESCRIPTION + "Command line utilities") + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION + "Doxygen generated documentation") + + SET(CPACK_COMPONENT_HEADERS_DEPENDS library) + + SET(CPACK_COMPONENT_HEADERS_GROUP "Development") + SET(CPACK_COMPONENT_LIBRARY_GROUP "Development") + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation") + + SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION + "Components needed to develop software using LEMON") + SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION + "Documentation of LEMON") + + SET(CPACK_ALL_INSTALL_TYPES Full Developer) + + SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full) + SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full) + SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full) + + SET(CPACK_GENERATOR "NSIS") + SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico") + SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico") + #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp") + SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico") + SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}") + SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu") + SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu") + SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu") + SET(CPACK_NSIS_CREATE_ICONS_EXTRA " + CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\" + ") + SET(CPACK_NSIS_DELETE_ICONS_EXTRA " + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\" + ") + + INCLUDE(CPack) +ENDIF() diff --git a/lemon/INSTALL b/lemon/INSTALL new file mode 100644 index 0000000..58adb74 --- /dev/null +++ b/lemon/INSTALL @@ -0,0 +1,197 @@ +Installation Instructions +========================= + +Since you are reading this I assume you already obtained one of the release +tarballs and successfully extracted it. The latest version of LEMON is +available at our web page (http://lemon.cs.elte.hu/). + +LEMON provides two different build environments, one is based on "autotool", +while the other is based on "cmake". This file contains instructions only for +the former one, which is the recommended build environment on Linux, Mac OSX +and other unices or if you use Cygwin on Windows. For cmake installation +instructions visit http://lemon.cs.elte.hu. + +In order to install LEMON from the extracted source tarball you have to +issue the following commands: + + 1. `cd lemon-x.y.z' + + This command changes to the directory which was created when you + extracted the sources. The x.y.z part is a version number. + + 2. `./configure' + + This command runs the configure shell script, which does some checks and + creates the makefiles. + + 3. `make' + + This command compiles the non-template part of LEMON into libemon.a + file. It also compiles the programs in the tools subdirectory by + default. + + 4. `make check' + + This step is optional, but recommended. It runs the test programs that + we developed for LEMON to check whether the library works properly on + your platform. + + 5. `make install' + + This command installs LEMON under /usr/local (you will need root + privileges to be able to do that). If you want to install it to some + other location, then pass the --prefix=DIRECTORY flag to configure in + step 2. For example: `./configure --prefix=/home/username/lemon'. + + 6. `make install-html' + + This command installs the documentation under share/doc/lemon/docs. The + generated documentation is included in the tarball. If you want to + generate it yourself, then run `make html'. Note that for this you need + to have the following programs installed: Doxygen, Graphviz, Ghostscript, + Latex. + + +Configure Options and Variables +=============================== + +In step 2 you can customize the actions of configure by setting variables +and passing options to it. This can be done like this: +`./configure [OPTION]... [VARIABLE=VALUE]...' + +Below you will find some useful variables and options (see `./configure --help' +for more): + +CXX='comp' + + Change the C++ compiler to 'comp'. + +CXXFLAGS='flags' + + Pass the 'flags' to the compiler. For example CXXFLAGS='-O3 -march=pentium-m' + turns on generation of aggressively optimized Pentium-M specific code. + +--prefix=PREFIX + + Set the installation prefix to PREFIX. By default it is /usr/local. + +--enable-tools + + Build the programs in the tools subdirectory (default). + +--disable-tools + + Do not build the programs in the tools subdirectory. + +--with-glpk[=PREFIX] + + Enable GLPK support (default). You should specify the prefix too if + you installed GLPK to some non-standard location (e.g. your home + directory). If it is not found, GLPK support will be disabled. + +--with-glpk-includedir=DIR + + The directory where the GLPK header files are located. This is only + useful when the GLPK headers and libraries are not under the same + prefix (which is unlikely). + +--with-glpk-libdir=DIR + + The directory where the GLPK libraries are located. This is only + useful when the GLPK headers and libraries are not under the same + prefix (which is unlikely). + +--without-glpk + + Disable GLPK support. + +--with-cplex[=PREFIX] + + Enable CPLEX support (default). You should specify the prefix too + if you installed CPLEX to some non-standard location + (e.g. /opt/ilog/cplex75). If it is not found, CPLEX support will be + disabled. + +--with-cplex-includedir=DIR + + The directory where the CPLEX header files are located. This is + only useful when the CPLEX headers and libraries are not under the + same prefix (e.g. /usr/local/cplex/cplex75/include). + +--with-cplex-libdir=DIR + + The directory where the CPLEX libraries are located. This is only + useful when the CPLEX headers and libraries are not under the same + prefix (e.g. + /usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_pic_mt). + +--without-cplex + + Disable CPLEX support. + +--with-soplex[=PREFIX] + + Enable SoPlex support (default). You should specify the prefix too if + you installed SoPlex to some non-standard location (e.g. your home + directory). If it is not found, SoPlex support will be disabled. + +--with-soplex-includedir=DIR + + The directory where the SoPlex header files are located. This is only + useful when the SoPlex headers and libraries are not under the same + prefix (which is unlikely). + +--with-soplex-libdir=DIR + + The directory where the SoPlex libraries are located. This is only + useful when the SoPlex headers and libraries are not under the same + prefix (which is unlikely). + +--without-soplex + + Disable SoPlex support. + +--with-coin[=PREFIX] + + Enable support for COIN-OR solvers (CLP and CBC). You should + specify the prefix too. (by default, COIN-OR tools install + themselves to the source code directory). This command enables the + solvers that are actually found. + +--with-coin-includedir=DIR + + The directory where the COIN-OR header files are located. This is + only useful when the COIN-OR headers and libraries are not under + the same prefix (which is unlikely). + +--with-coin-libdir=DIR + + The directory where the COIN-OR libraries are located. This is only + useful when the COIN-OR headers and libraries are not under the + same prefix (which is unlikely). + +--without-coin + + Disable COIN-OR support. + + +Makefile Variables +================== + +Some Makefile variables are reserved by the GNU Coding Standards for +the use of the "user" - the person building the package. For instance, +CXX and CXXFLAGS are such variables, and have the same meaning as +explained in the previous section. These variables can be set on the +command line when invoking `make' like this: +`make [VARIABLE=VALUE]...' + +WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us +to hold several compiler flags related to warnings. Its default value +can be overridden when invoking `make'. For example to disable all +warning flags use `make WARNINGCXXFLAGS='. + +In order to turn off a single flag from the default set of warning +flags, you can use the CXXFLAGS variable, since this is passed after +WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is +used by default when g++ is detected) you can use +`make CXXFLAGS="-g -O2 -Wno-old-style-cast"'. diff --git a/lemon/LICENSE b/lemon/LICENSE new file mode 100644 index 0000000..dde0229 --- /dev/null +++ b/lemon/LICENSE @@ -0,0 +1,32 @@ +LEMON code without an explicit copyright notice is covered by the following +copyright/license. + +Copyright (C) 2003-2010 Egervary Jeno Kombinatorikus Optimalizalasi +Kutatocsoport (Egervary Combinatorial Optimization Research Group, +EGRES). + +=========================================================================== +Boost Software License, Version 1.0 +=========================================================================== + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/lemon/Makefile b/lemon/Makefile new file mode 100644 index 0000000..01f291b --- /dev/null +++ b/lemon/Makefile @@ -0,0 +1,2241 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + + + + +pkgdatadir = $(datadir)/lemon +pkgincludedir = $(includedir)/lemon +pkglibdir = $(libdir)/lemon +pkglibexecdir = $(libexecdir)/lemon +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-unknown-linux-gnu +host_triplet = x86_64-unknown-linux-gnu +noinst_PROGRAMS = +bin_PROGRAMS = $(am__EXEEXT_1) +check_PROGRAMS = test/adaptors_test$(EXEEXT) \ + test/bellman_ford_test$(EXEEXT) test/bfs_test$(EXEEXT) \ + test/circulation_test$(EXEEXT) test/connectivity_test$(EXEEXT) \ + test/counter_test$(EXEEXT) test/dfs_test$(EXEEXT) \ + test/digraph_test$(EXEEXT) test/dijkstra_test$(EXEEXT) \ + test/dim_test$(EXEEXT) test/edge_set_test$(EXEEXT) \ + test/error_test$(EXEEXT) test/euler_test$(EXEEXT) \ + test/fractional_matching_test$(EXEEXT) \ + test/gomory_hu_test$(EXEEXT) test/graph_copy_test$(EXEEXT) \ + test/graph_test$(EXEEXT) test/graph_utils_test$(EXEEXT) \ + test/hao_orlin_test$(EXEEXT) test/heap_test$(EXEEXT) \ + test/kruskal_test$(EXEEXT) test/lgf_test$(EXEEXT) \ + test/maps_test$(EXEEXT) test/matching_test$(EXEEXT) \ + test/min_cost_arborescence_test$(EXEEXT) \ + test/min_cost_flow_test$(EXEEXT) \ + test/min_mean_cycle_test$(EXEEXT) test/path_test$(EXEEXT) \ + test/planarity_test$(EXEEXT) test/preflow_test$(EXEEXT) \ + test/radix_sort_test$(EXEEXT) test/random_test$(EXEEXT) \ + test/suurballe_test$(EXEEXT) test/test_tools_fail$(EXEEXT) \ + test/test_tools_pass$(EXEEXT) test/time_measure_test$(EXEEXT) \ + test/unionfind_test$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) +DIST_COMMON = README $(am__configure_deps) \ + $(am__dist_bin_SCRIPTS_DIST) $(bits_HEADERS) \ + $(concept_HEADERS) $(lemon_HEADERS) $(noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/config.h.in $(srcdir)/doc/Makefile.am \ + $(srcdir)/lemon/Makefile.am $(srcdir)/scripts/Makefile.am \ + $(srcdir)/test/Makefile.am $(srcdir)/tools/Makefile.am \ + $(top_srcdir)/cmake/version.cmake.in $(top_srcdir)/configure \ + $(top_srcdir)/doc/Doxyfile.in \ + $(top_srcdir)/doc/mainpage.dox.in \ + $(top_srcdir)/lemon/config.h.in \ + $(top_srcdir)/lemon/lemon.pc.in AUTHORS INSTALL NEWS \ + build-aux/config.guess build-aux/config.sub build-aux/depcomp \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing +#am__append_1 = lemon/glpk.cc +#am__append_2 = lemon/cplex.cc +#am__append_3 = lemon/soplex.cc +#am__append_4 = lemon/clp.cc +#am__append_5 = lemon/cbc.cc +#am__append_6 = test/lp_test +#am__append_7 = test/mip_test +am__append_8 = \ + tools/dimacs-solver \ + tools/dimacs-to-lgf \ + tools/lgf-gen + +am__append_9 = tools/lemon-0.x-to-1.x.sh +subdir = . +SUBDIRS = +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/lx_check_coin.m4 \ + $(top_srcdir)/m4/lx_check_cplex.m4 \ + $(top_srcdir)/m4/lx_check_glpk.m4 \ + $(top_srcdir)/m4/lx_check_soplex.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h $(top_builddir)/lemon/config.h +CONFIG_CLEAN_FILES = cmake/version.cmake doc/Doxyfile doc/mainpage.dox \ + lemon/lemon.pc +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(bitsdir)" "$(DESTDIR)$(conceptdir)" \ + "$(DESTDIR)$(lemondir)" "$(DESTDIR)$(lemondir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +lemon_libemon_la_LIBADD = +am__lemon_libemon_la_SOURCES_DIST = lemon/arg_parser.cc lemon/base.cc \ + lemon/color.cc lemon/lp_base.cc lemon/lp_skeleton.cc \ + lemon/random.cc lemon/bits/windows.cc lemon/glpk.cc \ + lemon/cplex.cc lemon/soplex.cc lemon/clp.cc lemon/cbc.cc +am__dirstamp = $(am__leading_dot)dirstamp +#am__objects_1 = lemon/lemon_libemon_la-glpk.lo +#am__objects_2 = lemon/lemon_libemon_la-cplex.lo +#am__objects_3 = lemon/lemon_libemon_la-soplex.lo +#am__objects_4 = lemon/lemon_libemon_la-clp.lo +#am__objects_5 = lemon/lemon_libemon_la-cbc.lo +am_lemon_libemon_la_OBJECTS = lemon/lemon_libemon_la-arg_parser.lo \ + lemon/lemon_libemon_la-base.lo lemon/lemon_libemon_la-color.lo \ + lemon/lemon_libemon_la-lp_base.lo \ + lemon/lemon_libemon_la-lp_skeleton.lo \ + lemon/lemon_libemon_la-random.lo \ + lemon/bits/lemon_libemon_la-windows.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) \ + $(am__objects_5) +lemon_libemon_la_OBJECTS = $(am_lemon_libemon_la_OBJECTS) +lemon_libemon_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) \ + $(lemon_libemon_la_LDFLAGS) $(LDFLAGS) -o $@ +am__EXEEXT_1 = tools/dimacs-solver$(EXEEXT) \ + tools/dimacs-to-lgf$(EXEEXT) \ + tools/lgf-gen$(EXEEXT) +#am__EXEEXT_2 = test/lp_test$(EXEEXT) +#am__EXEEXT_3 = test/mip_test$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am_test_adaptors_test_OBJECTS = test/adaptors_test.$(OBJEXT) +test_adaptors_test_OBJECTS = $(am_test_adaptors_test_OBJECTS) +test_adaptors_test_LDADD = $(LDADD) +test_adaptors_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_bellman_ford_test_OBJECTS = test/bellman_ford_test.$(OBJEXT) +test_bellman_ford_test_OBJECTS = $(am_test_bellman_ford_test_OBJECTS) +test_bellman_ford_test_LDADD = $(LDADD) +test_bellman_ford_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_bfs_test_OBJECTS = test/bfs_test.$(OBJEXT) +test_bfs_test_OBJECTS = $(am_test_bfs_test_OBJECTS) +test_bfs_test_LDADD = $(LDADD) +test_bfs_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_circulation_test_OBJECTS = test/circulation_test.$(OBJEXT) +test_circulation_test_OBJECTS = $(am_test_circulation_test_OBJECTS) +test_circulation_test_LDADD = $(LDADD) +test_circulation_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_connectivity_test_OBJECTS = test/connectivity_test.$(OBJEXT) +test_connectivity_test_OBJECTS = $(am_test_connectivity_test_OBJECTS) +test_connectivity_test_LDADD = $(LDADD) +test_connectivity_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_counter_test_OBJECTS = test/counter_test.$(OBJEXT) +test_counter_test_OBJECTS = $(am_test_counter_test_OBJECTS) +test_counter_test_LDADD = $(LDADD) +test_counter_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_dfs_test_OBJECTS = test/dfs_test.$(OBJEXT) +test_dfs_test_OBJECTS = $(am_test_dfs_test_OBJECTS) +test_dfs_test_LDADD = $(LDADD) +test_dfs_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_digraph_test_OBJECTS = test/digraph_test.$(OBJEXT) +test_digraph_test_OBJECTS = $(am_test_digraph_test_OBJECTS) +test_digraph_test_LDADD = $(LDADD) +test_digraph_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_dijkstra_test_OBJECTS = test/dijkstra_test.$(OBJEXT) +test_dijkstra_test_OBJECTS = $(am_test_dijkstra_test_OBJECTS) +test_dijkstra_test_LDADD = $(LDADD) +test_dijkstra_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_dim_test_OBJECTS = test/dim_test.$(OBJEXT) +test_dim_test_OBJECTS = $(am_test_dim_test_OBJECTS) +test_dim_test_LDADD = $(LDADD) +test_dim_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_edge_set_test_OBJECTS = test/edge_set_test.$(OBJEXT) +test_edge_set_test_OBJECTS = $(am_test_edge_set_test_OBJECTS) +test_edge_set_test_LDADD = $(LDADD) +test_edge_set_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_error_test_OBJECTS = test/error_test.$(OBJEXT) +test_error_test_OBJECTS = $(am_test_error_test_OBJECTS) +test_error_test_LDADD = $(LDADD) +test_error_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_euler_test_OBJECTS = test/euler_test.$(OBJEXT) +test_euler_test_OBJECTS = $(am_test_euler_test_OBJECTS) +test_euler_test_LDADD = $(LDADD) +test_euler_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_fractional_matching_test_OBJECTS = \ + test/fractional_matching_test.$(OBJEXT) +test_fractional_matching_test_OBJECTS = \ + $(am_test_fractional_matching_test_OBJECTS) +test_fractional_matching_test_LDADD = $(LDADD) +test_fractional_matching_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_gomory_hu_test_OBJECTS = test/gomory_hu_test.$(OBJEXT) +test_gomory_hu_test_OBJECTS = $(am_test_gomory_hu_test_OBJECTS) +test_gomory_hu_test_LDADD = $(LDADD) +test_gomory_hu_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_graph_copy_test_OBJECTS = test/graph_copy_test.$(OBJEXT) +test_graph_copy_test_OBJECTS = $(am_test_graph_copy_test_OBJECTS) +test_graph_copy_test_LDADD = $(LDADD) +test_graph_copy_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_graph_test_OBJECTS = test/graph_test.$(OBJEXT) +test_graph_test_OBJECTS = $(am_test_graph_test_OBJECTS) +test_graph_test_LDADD = $(LDADD) +test_graph_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_graph_utils_test_OBJECTS = test/graph_utils_test.$(OBJEXT) +test_graph_utils_test_OBJECTS = $(am_test_graph_utils_test_OBJECTS) +test_graph_utils_test_LDADD = $(LDADD) +test_graph_utils_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_hao_orlin_test_OBJECTS = test/hao_orlin_test.$(OBJEXT) +test_hao_orlin_test_OBJECTS = $(am_test_hao_orlin_test_OBJECTS) +test_hao_orlin_test_LDADD = $(LDADD) +test_hao_orlin_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_heap_test_OBJECTS = test/heap_test.$(OBJEXT) +test_heap_test_OBJECTS = $(am_test_heap_test_OBJECTS) +test_heap_test_LDADD = $(LDADD) +test_heap_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_kruskal_test_OBJECTS = test/kruskal_test.$(OBJEXT) +test_kruskal_test_OBJECTS = $(am_test_kruskal_test_OBJECTS) +test_kruskal_test_LDADD = $(LDADD) +test_kruskal_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_lgf_test_OBJECTS = test/lgf_test.$(OBJEXT) +test_lgf_test_OBJECTS = $(am_test_lgf_test_OBJECTS) +test_lgf_test_LDADD = $(LDADD) +test_lgf_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_lp_test_OBJECTS = test/lp_test.$(OBJEXT) +test_lp_test_OBJECTS = $(am_test_lp_test_OBJECTS) +test_lp_test_LDADD = $(LDADD) +test_lp_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_maps_test_OBJECTS = test/maps_test.$(OBJEXT) +test_maps_test_OBJECTS = $(am_test_maps_test_OBJECTS) +test_maps_test_LDADD = $(LDADD) +test_maps_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_matching_test_OBJECTS = test/matching_test.$(OBJEXT) +test_matching_test_OBJECTS = $(am_test_matching_test_OBJECTS) +test_matching_test_LDADD = $(LDADD) +test_matching_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_min_cost_arborescence_test_OBJECTS = \ + test/min_cost_arborescence_test.$(OBJEXT) +test_min_cost_arborescence_test_OBJECTS = \ + $(am_test_min_cost_arborescence_test_OBJECTS) +test_min_cost_arborescence_test_LDADD = $(LDADD) +test_min_cost_arborescence_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_min_cost_flow_test_OBJECTS = \ + test/min_cost_flow_test.$(OBJEXT) +test_min_cost_flow_test_OBJECTS = \ + $(am_test_min_cost_flow_test_OBJECTS) +test_min_cost_flow_test_LDADD = $(LDADD) +test_min_cost_flow_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_min_mean_cycle_test_OBJECTS = \ + test/min_mean_cycle_test.$(OBJEXT) +test_min_mean_cycle_test_OBJECTS = \ + $(am_test_min_mean_cycle_test_OBJECTS) +test_min_mean_cycle_test_LDADD = $(LDADD) +test_min_mean_cycle_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_mip_test_OBJECTS = test/mip_test.$(OBJEXT) +test_mip_test_OBJECTS = $(am_test_mip_test_OBJECTS) +test_mip_test_LDADD = $(LDADD) +test_mip_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_path_test_OBJECTS = test/path_test.$(OBJEXT) +test_path_test_OBJECTS = $(am_test_path_test_OBJECTS) +test_path_test_LDADD = $(LDADD) +test_path_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_planarity_test_OBJECTS = test/planarity_test.$(OBJEXT) +test_planarity_test_OBJECTS = $(am_test_planarity_test_OBJECTS) +test_planarity_test_LDADD = $(LDADD) +test_planarity_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_preflow_test_OBJECTS = test/preflow_test.$(OBJEXT) +test_preflow_test_OBJECTS = $(am_test_preflow_test_OBJECTS) +test_preflow_test_LDADD = $(LDADD) +test_preflow_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_radix_sort_test_OBJECTS = test/radix_sort_test.$(OBJEXT) +test_radix_sort_test_OBJECTS = $(am_test_radix_sort_test_OBJECTS) +test_radix_sort_test_LDADD = $(LDADD) +test_radix_sort_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_random_test_OBJECTS = test/random_test.$(OBJEXT) +test_random_test_OBJECTS = $(am_test_random_test_OBJECTS) +test_random_test_LDADD = $(LDADD) +test_random_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_suurballe_test_OBJECTS = test/suurballe_test.$(OBJEXT) +test_suurballe_test_OBJECTS = $(am_test_suurballe_test_OBJECTS) +test_suurballe_test_LDADD = $(LDADD) +test_suurballe_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_test_tools_fail_OBJECTS = test/test_tools_fail.$(OBJEXT) +test_test_tools_fail_OBJECTS = $(am_test_test_tools_fail_OBJECTS) +test_test_tools_fail_LDADD = $(LDADD) +test_test_tools_fail_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_test_tools_pass_OBJECTS = test/test_tools_pass.$(OBJEXT) +test_test_tools_pass_OBJECTS = $(am_test_test_tools_pass_OBJECTS) +test_test_tools_pass_LDADD = $(LDADD) +am_test_time_measure_test_OBJECTS = test/time_measure_test.$(OBJEXT) +test_time_measure_test_OBJECTS = $(am_test_time_measure_test_OBJECTS) +test_time_measure_test_LDADD = $(LDADD) +test_time_measure_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_unionfind_test_OBJECTS = test/unionfind_test.$(OBJEXT) +test_unionfind_test_OBJECTS = $(am_test_unionfind_test_OBJECTS) +test_unionfind_test_LDADD = $(LDADD) +test_unionfind_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_tools_dimacs_solver_OBJECTS = tools/dimacs-solver.$(OBJEXT) +tools_dimacs_solver_OBJECTS = $(am_tools_dimacs_solver_OBJECTS) +tools_dimacs_solver_LDADD = $(LDADD) +tools_dimacs_solver_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_tools_dimacs_to_lgf_OBJECTS = tools/dimacs-to-lgf.$(OBJEXT) +tools_dimacs_to_lgf_OBJECTS = $(am_tools_dimacs_to_lgf_OBJECTS) +tools_dimacs_to_lgf_LDADD = $(LDADD) +tools_dimacs_to_lgf_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_tools_lgf_gen_OBJECTS = tools/lgf-gen.$(OBJEXT) +tools_lgf_gen_OBJECTS = $(am_tools_lgf_gen_OBJECTS) +tools_lgf_gen_LDADD = $(LDADD) +tools_lgf_gen_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am__dist_bin_SCRIPTS_DIST = tools/lemon-0.x-to-1.x.sh +SCRIPTS = $(dist_bin_SCRIPTS) +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(lemon_libemon_la_SOURCES) $(test_adaptors_test_SOURCES) \ + $(test_bellman_ford_test_SOURCES) $(test_bfs_test_SOURCES) \ + $(test_circulation_test_SOURCES) \ + $(test_connectivity_test_SOURCES) $(test_counter_test_SOURCES) \ + $(test_dfs_test_SOURCES) $(test_digraph_test_SOURCES) \ + $(test_dijkstra_test_SOURCES) $(test_dim_test_SOURCES) \ + $(test_edge_set_test_SOURCES) $(test_error_test_SOURCES) \ + $(test_euler_test_SOURCES) \ + $(test_fractional_matching_test_SOURCES) \ + $(test_gomory_hu_test_SOURCES) $(test_graph_copy_test_SOURCES) \ + $(test_graph_test_SOURCES) $(test_graph_utils_test_SOURCES) \ + $(test_hao_orlin_test_SOURCES) $(test_heap_test_SOURCES) \ + $(test_kruskal_test_SOURCES) $(test_lgf_test_SOURCES) \ + $(test_lp_test_SOURCES) $(test_maps_test_SOURCES) \ + $(test_matching_test_SOURCES) \ + $(test_min_cost_arborescence_test_SOURCES) \ + $(test_min_cost_flow_test_SOURCES) \ + $(test_min_mean_cycle_test_SOURCES) $(test_mip_test_SOURCES) \ + $(test_path_test_SOURCES) $(test_planarity_test_SOURCES) \ + $(test_preflow_test_SOURCES) $(test_radix_sort_test_SOURCES) \ + $(test_random_test_SOURCES) $(test_suurballe_test_SOURCES) \ + $(test_test_tools_fail_SOURCES) \ + $(test_test_tools_pass_SOURCES) \ + $(test_time_measure_test_SOURCES) \ + $(test_unionfind_test_SOURCES) $(tools_dimacs_solver_SOURCES) \ + $(tools_dimacs_to_lgf_SOURCES) $(tools_lgf_gen_SOURCES) +DIST_SOURCES = $(am__lemon_libemon_la_SOURCES_DIST) \ + $(test_adaptors_test_SOURCES) \ + $(test_bellman_ford_test_SOURCES) $(test_bfs_test_SOURCES) \ + $(test_circulation_test_SOURCES) \ + $(test_connectivity_test_SOURCES) $(test_counter_test_SOURCES) \ + $(test_dfs_test_SOURCES) $(test_digraph_test_SOURCES) \ + $(test_dijkstra_test_SOURCES) $(test_dim_test_SOURCES) \ + $(test_edge_set_test_SOURCES) $(test_error_test_SOURCES) \ + $(test_euler_test_SOURCES) \ + $(test_fractional_matching_test_SOURCES) \ + $(test_gomory_hu_test_SOURCES) $(test_graph_copy_test_SOURCES) \ + $(test_graph_test_SOURCES) $(test_graph_utils_test_SOURCES) \ + $(test_hao_orlin_test_SOURCES) $(test_heap_test_SOURCES) \ + $(test_kruskal_test_SOURCES) $(test_lgf_test_SOURCES) \ + $(test_lp_test_SOURCES) $(test_maps_test_SOURCES) \ + $(test_matching_test_SOURCES) \ + $(test_min_cost_arborescence_test_SOURCES) \ + $(test_min_cost_flow_test_SOURCES) \ + $(test_min_mean_cycle_test_SOURCES) $(test_mip_test_SOURCES) \ + $(test_path_test_SOURCES) $(test_planarity_test_SOURCES) \ + $(test_preflow_test_SOURCES) $(test_radix_sort_test_SOURCES) \ + $(test_random_test_SOURCES) $(test_suurballe_test_SOURCES) \ + $(test_test_tools_fail_SOURCES) \ + $(test_test_tools_pass_SOURCES) \ + $(test_time_measure_test_SOURCES) \ + $(test_unionfind_test_SOURCES) $(tools_dimacs_solver_SOURCES) \ + $(tools_dimacs_to_lgf_SOURCES) $(tools_lgf_gen_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +DATA = $(pkgconfig_DATA) +HEADERS = $(bits_HEADERS) $(concept_HEADERS) $(lemon_HEADERS) \ + $(nodist_lemon_HEADERS) $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run aclocal-1.11 +AMTAR = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run tar +AR = ar +AUTOCONF = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoconf +AUTOHEADER = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoheader +AUTOMAKE = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run automake-1.11 +AWK = mawk +CBC_CXXFLAGS = +CBC_LIBS = +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CLP_CXXFLAGS = +CLP_LIBS = +CONFIG_STATUS_DEPENDENCIES = $(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in +CPLEX_CFLAGS = +CPLEX_LIBS = +CPPFLAGS = +CXX = g++ +CXXCPP = g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -g -O2 +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DSYMUTIL = +DUMPBIN = +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +FGREP = /bin/grep -F +GLPK_CFLAGS = +GLPK_LIBS = +GREP = /bin/grep +HAVE_VALGRIND = +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LD = /usr/bin/ld -m elf_x86_64 +LDFLAGS = +LIBOBJS = +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIPO = +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +NM = /usr/bin/nm -B +NMEDIT = +OBJDUMP = objdump +OBJEXT = o +OTOOL = +OTOOL64 = +PACKAGE = lemon +PACKAGE_BUGREPORT = lemon-user@lemon.cs.elte.hu +PACKAGE_NAME = LEMON +PACKAGE_STRING = LEMON 1.2.3 +PACKAGE_TARNAME = lemon +PACKAGE_URL = +PACKAGE_VERSION = 1.2.3 +PATH_SEPARATOR = : +RANLIB = ranlib +SED = /bin/sed +SET_MAKE = +SHELL = /bin/bash +SOPLEX_CXXFLAGS = +SOPLEX_LIBS = +STRIP = strip +VERSION = 1.2.3 +WARNINGCXXFLAGS = -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas +abs_builddir = /home/carlo/honours/lemon +abs_srcdir = /home/carlo/honours/lemon +abs_top_builddir = /home/carlo/honours/lemon +abs_top_srcdir = /home/carlo/honours/lemon +ac_ct_CC = gcc +ac_ct_CXX = g++ +ac_ct_DUMPBIN = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = x86_64-unknown-linux-gnu +build_alias = +build_cpu = x86_64 +build_os = linux-gnu +build_vendor = unknown +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +doxygen_found = no +dvidir = ${docdir} +exec_prefix = ${prefix} +gs_found = yes +host = x86_64-unknown-linux-gnu +host_alias = +host_cpu = x86_64 +host_os = linux-gnu +host_vendor = unknown +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/carlo/honours/lemon/build-aux/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +lt_ECHO = echo +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +python_found = yes +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = +top_builddir = . +top_srcdir = . +ACLOCAL_AMFLAGS = -I m4 +AM_CXXFLAGS = $(WARNINGCXXFLAGS) +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) +LDADD = $(top_builddir)/lemon/libemon.la +EXTRA_DIST = AUTHORS LICENSE m4/lx_check_cplex.m4 m4/lx_check_glpk.m4 \ + m4/lx_check_soplex.m4 m4/lx_check_coin.m4 CMakeLists.txt \ + cmake/FindGhostscript.cmake cmake/FindCPLEX.cmake \ + cmake/FindGLPK.cmake cmake/FindCOIN.cmake \ + cmake/LEMONConfig.cmake.in cmake/version.cmake.in \ + cmake/version.cmake cmake/nsis/lemon.ico \ + cmake/nsis/uninstall.ico lemon/lemon.pc.in \ + lemon/lemon.pc.cmake lemon/CMakeLists.txt lemon/config.h.cmake \ + test/CMakeLists.txt doc/Doxyfile.in doc/DoxygenLayout.xml \ + doc/coding_style.dox doc/dirs.dox doc/groups.dox doc/lgf.dox \ + doc/license.dox doc/mainpage.dox doc/migration.dox \ + doc/min_cost_flow.dox doc/named-param.dox doc/namespaces.dox \ + doc/html doc/CMakeLists.txt $(DOC_EPS_IMAGES:%=doc/images/%) \ + tools/CMakeLists.txt scripts/bib2dox.py scripts/bootstrap.sh \ + scripts/chg-len.py scripts/mk-release.sh \ + scripts/unify-sources.sh scripts/valgrind-wrapper.sh +pkgconfigdir = $(libdir)/pkgconfig +lemondir = $(pkgincludedir) +bitsdir = $(lemondir)/bits +conceptdir = $(lemondir)/concepts +pkgconfig_DATA = lemon/lemon.pc +lib_LTLIBRARIES = lemon/libemon.la +lemon_HEADERS = lemon/adaptors.h lemon/arg_parser.h lemon/assert.h \ + lemon/bellman_ford.h lemon/bfs.h lemon/bin_heap.h \ + lemon/binomial_heap.h lemon/bucket_heap.h \ + lemon/capacity_scaling.h lemon/cbc.h lemon/circulation.h \ + lemon/clp.h lemon/color.h lemon/concept_check.h \ + lemon/connectivity.h lemon/core.h lemon/cost_scaling.h \ + lemon/counter.h lemon/cplex.h lemon/cycle_canceling.h \ + lemon/dfs.h lemon/dheap.h lemon/dijkstra.h lemon/dim2.h \ + lemon/dimacs.h lemon/edge_set.h lemon/elevator.h lemon/error.h \ + lemon/euler.h lemon/fib_heap.h lemon/fractional_matching.h \ + lemon/full_graph.h lemon/glpk.h lemon/gomory_hu.h \ + lemon/graph_to_eps.h lemon/grid_graph.h \ + lemon/hartmann_orlin_mmc.h lemon/howard_mmc.h \ + lemon/hypercube_graph.h lemon/karp_mmc.h lemon/kruskal.h \ + lemon/hao_orlin.h lemon/lgf_reader.h lemon/lgf_writer.h \ + lemon/list_graph.h lemon/lp.h lemon/lp_base.h \ + lemon/lp_skeleton.h lemon/maps.h lemon/matching.h lemon/math.h \ + lemon/min_cost_arborescence.h lemon/nauty_reader.h \ + lemon/network_simplex.h lemon/pairing_heap.h lemon/path.h \ + lemon/planarity.h lemon/preflow.h lemon/quad_heap.h \ + lemon/radix_heap.h lemon/radix_sort.h lemon/random.h \ + lemon/smart_graph.h lemon/soplex.h lemon/static_graph.h \ + lemon/suurballe.h lemon/time_measure.h lemon/tolerance.h \ + lemon/unionfind.h lemon/bits/windows.h +bits_HEADERS = lemon/bits/alteration_notifier.h lemon/bits/array_map.h \ + lemon/bits/bezier.h lemon/bits/default_map.h \ + lemon/bits/edge_set_extender.h lemon/bits/enable_if.h \ + lemon/bits/graph_adaptor_extender.h \ + lemon/bits/graph_extender.h lemon/bits/map_extender.h \ + lemon/bits/path_dump.h lemon/bits/solver_bits.h \ + lemon/bits/traits.h lemon/bits/variant.h \ + lemon/bits/vector_map.h +concept_HEADERS = lemon/concepts/digraph.h lemon/concepts/graph.h \ + lemon/concepts/graph_components.h lemon/concepts/heap.h \ + lemon/concepts/maps.h lemon/concepts/path.h +noinst_HEADERS = test/graph_test.h test/test_tools.h +dist_bin_SCRIPTS = $(am__append_9) +TESTS = $(check_PROGRAMS) +XFAIL_TESTS = test/test_tools_fail$(EXEEXT) +lemon_libemon_la_SOURCES = lemon/arg_parser.cc lemon/base.cc \ + lemon/color.cc lemon/lp_base.cc lemon/lp_skeleton.cc \ + lemon/random.cc lemon/bits/windows.cc $(am__append_1) \ + $(am__append_2) $(am__append_3) $(am__append_4) \ + $(am__append_5) +nodist_lemon_HEADERS = lemon/config.h +lemon_libemon_la_CXXFLAGS = \ + $(AM_CXXFLAGS) \ + $(GLPK_CFLAGS) \ + $(CPLEX_CFLAGS) \ + $(SOPLEX_CXXFLAGS) \ + $(CLP_CXXFLAGS) \ + $(CBC_CXXFLAGS) + +lemon_libemon_la_LDFLAGS = \ + $(GLPK_LIBS) \ + $(CPLEX_LIBS) \ + $(SOPLEX_LIBS) \ + $(CLP_LIBS) \ + $(CBC_LIBS) + +#TESTS_ENVIRONMENT = $(top_srcdir)/scripts/valgrind-wrapper.sh +test_test_tools_pass_DEPENDENCIES = demo +test_adaptors_test_SOURCES = test/adaptors_test.cc +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc +test_bfs_test_SOURCES = test/bfs_test.cc +test_circulation_test_SOURCES = test/circulation_test.cc +test_counter_test_SOURCES = test/counter_test.cc +test_connectivity_test_SOURCES = test/connectivity_test.cc +test_dfs_test_SOURCES = test/dfs_test.cc +test_digraph_test_SOURCES = test/digraph_test.cc +test_dijkstra_test_SOURCES = test/dijkstra_test.cc +test_dim_test_SOURCES = test/dim_test.cc +test_edge_set_test_SOURCES = test/edge_set_test.cc +test_error_test_SOURCES = test/error_test.cc +test_euler_test_SOURCES = test/euler_test.cc +test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc +test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc +test_graph_copy_test_SOURCES = test/graph_copy_test.cc +test_graph_test_SOURCES = test/graph_test.cc +test_graph_utils_test_SOURCES = test/graph_utils_test.cc +test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc +test_heap_test_SOURCES = test/heap_test.cc +test_kruskal_test_SOURCES = test/kruskal_test.cc +test_lgf_test_SOURCES = test/lgf_test.cc +test_lp_test_SOURCES = test/lp_test.cc +test_maps_test_SOURCES = test/maps_test.cc +test_mip_test_SOURCES = test/mip_test.cc +test_matching_test_SOURCES = test/matching_test.cc +test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc +test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc +test_path_test_SOURCES = test/path_test.cc +test_planarity_test_SOURCES = test/planarity_test.cc +test_preflow_test_SOURCES = test/preflow_test.cc +test_radix_sort_test_SOURCES = test/radix_sort_test.cc +test_suurballe_test_SOURCES = test/suurballe_test.cc +test_random_test_SOURCES = test/random_test.cc +test_test_tools_fail_SOURCES = test/test_tools_fail.cc +test_test_tools_pass_SOURCES = test/test_tools_pass.cc +test_time_measure_test_SOURCES = test/time_measure_test.cc +test_unionfind_test_SOURCES = test/unionfind_test.cc +DOC_EPS_IMAGES18 = \ + grid_graph.eps \ + nodeshape_0.eps \ + nodeshape_1.eps \ + nodeshape_2.eps \ + nodeshape_3.eps \ + nodeshape_4.eps + +DOC_EPS_IMAGES27 = \ + bipartite_matching.eps \ + bipartite_partitions.eps \ + connected_components.eps \ + edge_biconnected_components.eps \ + matching.eps \ + node_biconnected_components.eps \ + planar.eps \ + strongly_connected_components.eps + +DOC_EPS_IMAGES = \ + $(DOC_EPS_IMAGES18) \ + $(DOC_EPS_IMAGES27) + +DOC_PNG_IMAGES = \ + $(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png) + +GS_COMMAND = gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 +tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc +tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc +tools_lgf_gen_SOURCES = tools/lgf-gen.cc +DIST_SUBDIRS = demo +MRPROPERFILES = \ + aclocal.m4 \ + config.h.in \ + config.h.in~ \ + configure \ + Makefile.in \ + build-aux/config.guess \ + build-aux/config.sub \ + build-aux/depcomp \ + build-aux/install-sh \ + build-aux/ltmain.sh \ + build-aux/missing \ + doc/doxygen.log + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/lemon/Makefile.am $(srcdir)/test/Makefile.am $(srcdir)/doc/Makefile.am $(srcdir)/tools/Makefile.am $(srcdir)/scripts/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +lemon/config.h: lemon/stamp-h2 + @if test ! -f $@; then \ + rm -f lemon/stamp-h2; \ + $(MAKE) $(AM_MAKEFLAGS) lemon/stamp-h2; \ + else :; fi + +lemon/stamp-h2: $(top_srcdir)/lemon/config.h.in $(top_builddir)/config.status + @rm -f lemon/stamp-h2 + cd $(top_builddir) && $(SHELL) ./config.status lemon/config.h + +distclean-hdr: + -rm -f config.h stamp-h1 lemon/config.h lemon/stamp-h2 +cmake/version.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/version.cmake.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +doc/Doxyfile: $(top_builddir)/config.status $(top_srcdir)/doc/Doxyfile.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +doc/mainpage.dox: $(top_builddir)/config.status $(top_srcdir)/doc/mainpage.dox.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +lemon/lemon.pc: $(top_builddir)/config.status $(top_srcdir)/lemon/lemon.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +lemon/$(am__dirstamp): + @$(MKDIR_P) lemon + @: > lemon/$(am__dirstamp) +lemon/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) lemon/$(DEPDIR) + @: > lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-arg_parser.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-base.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-color.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-lp_base.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-lp_skeleton.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-random.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/bits/$(am__dirstamp): + @$(MKDIR_P) lemon/bits + @: > lemon/bits/$(am__dirstamp) +lemon/bits/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) lemon/bits/$(DEPDIR) + @: > lemon/bits/$(DEPDIR)/$(am__dirstamp) +lemon/bits/lemon_libemon_la-windows.lo: lemon/bits/$(am__dirstamp) \ + lemon/bits/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-glpk.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-cplex.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-soplex.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-clp.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-cbc.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/libemon.la: $(lemon_libemon_la_OBJECTS) $(lemon_libemon_la_DEPENDENCIES) lemon/$(am__dirstamp) + $(lemon_libemon_la_LINK) -rpath $(libdir) $(lemon_libemon_la_OBJECTS) $(lemon_libemon_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +test/$(am__dirstamp): + @$(MKDIR_P) test + @: > test/$(am__dirstamp) +test/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) test/$(DEPDIR) + @: > test/$(DEPDIR)/$(am__dirstamp) +test/adaptors_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/adaptors_test$(EXEEXT): $(test_adaptors_test_OBJECTS) $(test_adaptors_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/adaptors_test$(EXEEXT) + $(CXXLINK) $(test_adaptors_test_OBJECTS) $(test_adaptors_test_LDADD) $(LIBS) +test/bellman_ford_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/bellman_ford_test$(EXEEXT): $(test_bellman_ford_test_OBJECTS) $(test_bellman_ford_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/bellman_ford_test$(EXEEXT) + $(CXXLINK) $(test_bellman_ford_test_OBJECTS) $(test_bellman_ford_test_LDADD) $(LIBS) +test/bfs_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/bfs_test$(EXEEXT): $(test_bfs_test_OBJECTS) $(test_bfs_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/bfs_test$(EXEEXT) + $(CXXLINK) $(test_bfs_test_OBJECTS) $(test_bfs_test_LDADD) $(LIBS) +test/circulation_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/circulation_test$(EXEEXT): $(test_circulation_test_OBJECTS) $(test_circulation_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/circulation_test$(EXEEXT) + $(CXXLINK) $(test_circulation_test_OBJECTS) $(test_circulation_test_LDADD) $(LIBS) +test/connectivity_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/connectivity_test$(EXEEXT): $(test_connectivity_test_OBJECTS) $(test_connectivity_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/connectivity_test$(EXEEXT) + $(CXXLINK) $(test_connectivity_test_OBJECTS) $(test_connectivity_test_LDADD) $(LIBS) +test/counter_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/counter_test$(EXEEXT): $(test_counter_test_OBJECTS) $(test_counter_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/counter_test$(EXEEXT) + $(CXXLINK) $(test_counter_test_OBJECTS) $(test_counter_test_LDADD) $(LIBS) +test/dfs_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/dfs_test$(EXEEXT): $(test_dfs_test_OBJECTS) $(test_dfs_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/dfs_test$(EXEEXT) + $(CXXLINK) $(test_dfs_test_OBJECTS) $(test_dfs_test_LDADD) $(LIBS) +test/digraph_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/digraph_test$(EXEEXT): $(test_digraph_test_OBJECTS) $(test_digraph_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/digraph_test$(EXEEXT) + $(CXXLINK) $(test_digraph_test_OBJECTS) $(test_digraph_test_LDADD) $(LIBS) +test/dijkstra_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/dijkstra_test$(EXEEXT): $(test_dijkstra_test_OBJECTS) $(test_dijkstra_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/dijkstra_test$(EXEEXT) + $(CXXLINK) $(test_dijkstra_test_OBJECTS) $(test_dijkstra_test_LDADD) $(LIBS) +test/dim_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/dim_test$(EXEEXT): $(test_dim_test_OBJECTS) $(test_dim_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/dim_test$(EXEEXT) + $(CXXLINK) $(test_dim_test_OBJECTS) $(test_dim_test_LDADD) $(LIBS) +test/edge_set_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/edge_set_test$(EXEEXT): $(test_edge_set_test_OBJECTS) $(test_edge_set_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/edge_set_test$(EXEEXT) + $(CXXLINK) $(test_edge_set_test_OBJECTS) $(test_edge_set_test_LDADD) $(LIBS) +test/error_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/error_test$(EXEEXT): $(test_error_test_OBJECTS) $(test_error_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/error_test$(EXEEXT) + $(CXXLINK) $(test_error_test_OBJECTS) $(test_error_test_LDADD) $(LIBS) +test/euler_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/euler_test$(EXEEXT): $(test_euler_test_OBJECTS) $(test_euler_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/euler_test$(EXEEXT) + $(CXXLINK) $(test_euler_test_OBJECTS) $(test_euler_test_LDADD) $(LIBS) +test/fractional_matching_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/fractional_matching_test$(EXEEXT): $(test_fractional_matching_test_OBJECTS) $(test_fractional_matching_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/fractional_matching_test$(EXEEXT) + $(CXXLINK) $(test_fractional_matching_test_OBJECTS) $(test_fractional_matching_test_LDADD) $(LIBS) +test/gomory_hu_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/gomory_hu_test$(EXEEXT): $(test_gomory_hu_test_OBJECTS) $(test_gomory_hu_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/gomory_hu_test$(EXEEXT) + $(CXXLINK) $(test_gomory_hu_test_OBJECTS) $(test_gomory_hu_test_LDADD) $(LIBS) +test/graph_copy_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/graph_copy_test$(EXEEXT): $(test_graph_copy_test_OBJECTS) $(test_graph_copy_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/graph_copy_test$(EXEEXT) + $(CXXLINK) $(test_graph_copy_test_OBJECTS) $(test_graph_copy_test_LDADD) $(LIBS) +test/graph_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/graph_test$(EXEEXT): $(test_graph_test_OBJECTS) $(test_graph_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/graph_test$(EXEEXT) + $(CXXLINK) $(test_graph_test_OBJECTS) $(test_graph_test_LDADD) $(LIBS) +test/graph_utils_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/graph_utils_test$(EXEEXT): $(test_graph_utils_test_OBJECTS) $(test_graph_utils_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/graph_utils_test$(EXEEXT) + $(CXXLINK) $(test_graph_utils_test_OBJECTS) $(test_graph_utils_test_LDADD) $(LIBS) +test/hao_orlin_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/hao_orlin_test$(EXEEXT): $(test_hao_orlin_test_OBJECTS) $(test_hao_orlin_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/hao_orlin_test$(EXEEXT) + $(CXXLINK) $(test_hao_orlin_test_OBJECTS) $(test_hao_orlin_test_LDADD) $(LIBS) +test/heap_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/heap_test$(EXEEXT): $(test_heap_test_OBJECTS) $(test_heap_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/heap_test$(EXEEXT) + $(CXXLINK) $(test_heap_test_OBJECTS) $(test_heap_test_LDADD) $(LIBS) +test/kruskal_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/kruskal_test$(EXEEXT): $(test_kruskal_test_OBJECTS) $(test_kruskal_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/kruskal_test$(EXEEXT) + $(CXXLINK) $(test_kruskal_test_OBJECTS) $(test_kruskal_test_LDADD) $(LIBS) +test/lgf_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/lgf_test$(EXEEXT): $(test_lgf_test_OBJECTS) $(test_lgf_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/lgf_test$(EXEEXT) + $(CXXLINK) $(test_lgf_test_OBJECTS) $(test_lgf_test_LDADD) $(LIBS) +test/lp_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/lp_test$(EXEEXT): $(test_lp_test_OBJECTS) $(test_lp_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/lp_test$(EXEEXT) + $(CXXLINK) $(test_lp_test_OBJECTS) $(test_lp_test_LDADD) $(LIBS) +test/maps_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/maps_test$(EXEEXT): $(test_maps_test_OBJECTS) $(test_maps_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/maps_test$(EXEEXT) + $(CXXLINK) $(test_maps_test_OBJECTS) $(test_maps_test_LDADD) $(LIBS) +test/matching_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/matching_test$(EXEEXT): $(test_matching_test_OBJECTS) $(test_matching_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/matching_test$(EXEEXT) + $(CXXLINK) $(test_matching_test_OBJECTS) $(test_matching_test_LDADD) $(LIBS) +test/min_cost_arborescence_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/min_cost_arborescence_test$(EXEEXT): $(test_min_cost_arborescence_test_OBJECTS) $(test_min_cost_arborescence_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/min_cost_arborescence_test$(EXEEXT) + $(CXXLINK) $(test_min_cost_arborescence_test_OBJECTS) $(test_min_cost_arborescence_test_LDADD) $(LIBS) +test/min_cost_flow_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/min_cost_flow_test$(EXEEXT): $(test_min_cost_flow_test_OBJECTS) $(test_min_cost_flow_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/min_cost_flow_test$(EXEEXT) + $(CXXLINK) $(test_min_cost_flow_test_OBJECTS) $(test_min_cost_flow_test_LDADD) $(LIBS) +test/min_mean_cycle_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/min_mean_cycle_test$(EXEEXT): $(test_min_mean_cycle_test_OBJECTS) $(test_min_mean_cycle_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/min_mean_cycle_test$(EXEEXT) + $(CXXLINK) $(test_min_mean_cycle_test_OBJECTS) $(test_min_mean_cycle_test_LDADD) $(LIBS) +test/mip_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/mip_test$(EXEEXT): $(test_mip_test_OBJECTS) $(test_mip_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/mip_test$(EXEEXT) + $(CXXLINK) $(test_mip_test_OBJECTS) $(test_mip_test_LDADD) $(LIBS) +test/path_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/path_test$(EXEEXT): $(test_path_test_OBJECTS) $(test_path_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/path_test$(EXEEXT) + $(CXXLINK) $(test_path_test_OBJECTS) $(test_path_test_LDADD) $(LIBS) +test/planarity_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/planarity_test$(EXEEXT): $(test_planarity_test_OBJECTS) $(test_planarity_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/planarity_test$(EXEEXT) + $(CXXLINK) $(test_planarity_test_OBJECTS) $(test_planarity_test_LDADD) $(LIBS) +test/preflow_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/preflow_test$(EXEEXT): $(test_preflow_test_OBJECTS) $(test_preflow_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/preflow_test$(EXEEXT) + $(CXXLINK) $(test_preflow_test_OBJECTS) $(test_preflow_test_LDADD) $(LIBS) +test/radix_sort_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/radix_sort_test$(EXEEXT): $(test_radix_sort_test_OBJECTS) $(test_radix_sort_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/radix_sort_test$(EXEEXT) + $(CXXLINK) $(test_radix_sort_test_OBJECTS) $(test_radix_sort_test_LDADD) $(LIBS) +test/random_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/random_test$(EXEEXT): $(test_random_test_OBJECTS) $(test_random_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/random_test$(EXEEXT) + $(CXXLINK) $(test_random_test_OBJECTS) $(test_random_test_LDADD) $(LIBS) +test/suurballe_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/suurballe_test$(EXEEXT): $(test_suurballe_test_OBJECTS) $(test_suurballe_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/suurballe_test$(EXEEXT) + $(CXXLINK) $(test_suurballe_test_OBJECTS) $(test_suurballe_test_LDADD) $(LIBS) +test/test_tools_fail.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/test_tools_fail$(EXEEXT): $(test_test_tools_fail_OBJECTS) $(test_test_tools_fail_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/test_tools_fail$(EXEEXT) + $(CXXLINK) $(test_test_tools_fail_OBJECTS) $(test_test_tools_fail_LDADD) $(LIBS) +test/test_tools_pass.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/test_tools_pass$(EXEEXT): $(test_test_tools_pass_OBJECTS) $(test_test_tools_pass_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/test_tools_pass$(EXEEXT) + $(CXXLINK) $(test_test_tools_pass_OBJECTS) $(test_test_tools_pass_LDADD) $(LIBS) +test/time_measure_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/time_measure_test$(EXEEXT): $(test_time_measure_test_OBJECTS) $(test_time_measure_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/time_measure_test$(EXEEXT) + $(CXXLINK) $(test_time_measure_test_OBJECTS) $(test_time_measure_test_LDADD) $(LIBS) +test/unionfind_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/unionfind_test$(EXEEXT): $(test_unionfind_test_OBJECTS) $(test_unionfind_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/unionfind_test$(EXEEXT) + $(CXXLINK) $(test_unionfind_test_OBJECTS) $(test_unionfind_test_LDADD) $(LIBS) +tools/$(am__dirstamp): + @$(MKDIR_P) tools + @: > tools/$(am__dirstamp) +tools/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tools/$(DEPDIR) + @: > tools/$(DEPDIR)/$(am__dirstamp) +tools/dimacs-solver.$(OBJEXT): tools/$(am__dirstamp) \ + tools/$(DEPDIR)/$(am__dirstamp) +tools/dimacs-solver$(EXEEXT): $(tools_dimacs_solver_OBJECTS) $(tools_dimacs_solver_DEPENDENCIES) tools/$(am__dirstamp) + @rm -f tools/dimacs-solver$(EXEEXT) + $(CXXLINK) $(tools_dimacs_solver_OBJECTS) $(tools_dimacs_solver_LDADD) $(LIBS) +tools/dimacs-to-lgf.$(OBJEXT): tools/$(am__dirstamp) \ + tools/$(DEPDIR)/$(am__dirstamp) +tools/dimacs-to-lgf$(EXEEXT): $(tools_dimacs_to_lgf_OBJECTS) $(tools_dimacs_to_lgf_DEPENDENCIES) tools/$(am__dirstamp) + @rm -f tools/dimacs-to-lgf$(EXEEXT) + $(CXXLINK) $(tools_dimacs_to_lgf_OBJECTS) $(tools_dimacs_to_lgf_LDADD) $(LIBS) +tools/lgf-gen.$(OBJEXT): tools/$(am__dirstamp) \ + tools/$(DEPDIR)/$(am__dirstamp) +tools/lgf-gen$(EXEEXT): $(tools_lgf_gen_OBJECTS) $(tools_lgf_gen_DEPENDENCIES) tools/$(am__dirstamp) + @rm -f tools/lgf-gen$(EXEEXT) + $(CXXLINK) $(tools_lgf_gen_OBJECTS) $(tools_lgf_gen_LDADD) $(LIBS) +install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-dist_binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f lemon/bits/lemon_libemon_la-windows.$(OBJEXT) + -rm -f lemon/bits/lemon_libemon_la-windows.lo + -rm -f lemon/lemon_libemon_la-arg_parser.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-arg_parser.lo + -rm -f lemon/lemon_libemon_la-base.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-base.lo + -rm -f lemon/lemon_libemon_la-cbc.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-cbc.lo + -rm -f lemon/lemon_libemon_la-clp.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-clp.lo + -rm -f lemon/lemon_libemon_la-color.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-color.lo + -rm -f lemon/lemon_libemon_la-cplex.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-cplex.lo + -rm -f lemon/lemon_libemon_la-glpk.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-glpk.lo + -rm -f lemon/lemon_libemon_la-lp_base.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-lp_base.lo + -rm -f lemon/lemon_libemon_la-lp_skeleton.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-lp_skeleton.lo + -rm -f lemon/lemon_libemon_la-random.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-random.lo + -rm -f lemon/lemon_libemon_la-soplex.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-soplex.lo + -rm -f test/adaptors_test.$(OBJEXT) + -rm -f test/bellman_ford_test.$(OBJEXT) + -rm -f test/bfs_test.$(OBJEXT) + -rm -f test/circulation_test.$(OBJEXT) + -rm -f test/connectivity_test.$(OBJEXT) + -rm -f test/counter_test.$(OBJEXT) + -rm -f test/dfs_test.$(OBJEXT) + -rm -f test/digraph_test.$(OBJEXT) + -rm -f test/dijkstra_test.$(OBJEXT) + -rm -f test/dim_test.$(OBJEXT) + -rm -f test/edge_set_test.$(OBJEXT) + -rm -f test/error_test.$(OBJEXT) + -rm -f test/euler_test.$(OBJEXT) + -rm -f test/fractional_matching_test.$(OBJEXT) + -rm -f test/gomory_hu_test.$(OBJEXT) + -rm -f test/graph_copy_test.$(OBJEXT) + -rm -f test/graph_test.$(OBJEXT) + -rm -f test/graph_utils_test.$(OBJEXT) + -rm -f test/hao_orlin_test.$(OBJEXT) + -rm -f test/heap_test.$(OBJEXT) + -rm -f test/kruskal_test.$(OBJEXT) + -rm -f test/lgf_test.$(OBJEXT) + -rm -f test/lp_test.$(OBJEXT) + -rm -f test/maps_test.$(OBJEXT) + -rm -f test/matching_test.$(OBJEXT) + -rm -f test/min_cost_arborescence_test.$(OBJEXT) + -rm -f test/min_cost_flow_test.$(OBJEXT) + -rm -f test/min_mean_cycle_test.$(OBJEXT) + -rm -f test/mip_test.$(OBJEXT) + -rm -f test/path_test.$(OBJEXT) + -rm -f test/planarity_test.$(OBJEXT) + -rm -f test/preflow_test.$(OBJEXT) + -rm -f test/radix_sort_test.$(OBJEXT) + -rm -f test/random_test.$(OBJEXT) + -rm -f test/suurballe_test.$(OBJEXT) + -rm -f test/test_tools_fail.$(OBJEXT) + -rm -f test/test_tools_pass.$(OBJEXT) + -rm -f test/time_measure_test.$(OBJEXT) + -rm -f test/unionfind_test.$(OBJEXT) + -rm -f tools/dimacs-solver.$(OBJEXT) + -rm -f tools/dimacs-to-lgf.$(OBJEXT) + -rm -f tools/lgf-gen.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-base.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-cbc.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-clp.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-color.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-cplex.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-glpk.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-random.Plo +include lemon/$(DEPDIR)/lemon_libemon_la-soplex.Plo +include lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Plo +include test/$(DEPDIR)/adaptors_test.Po +include test/$(DEPDIR)/bellman_ford_test.Po +include test/$(DEPDIR)/bfs_test.Po +include test/$(DEPDIR)/circulation_test.Po +include test/$(DEPDIR)/connectivity_test.Po +include test/$(DEPDIR)/counter_test.Po +include test/$(DEPDIR)/dfs_test.Po +include test/$(DEPDIR)/digraph_test.Po +include test/$(DEPDIR)/dijkstra_test.Po +include test/$(DEPDIR)/dim_test.Po +include test/$(DEPDIR)/edge_set_test.Po +include test/$(DEPDIR)/error_test.Po +include test/$(DEPDIR)/euler_test.Po +include test/$(DEPDIR)/fractional_matching_test.Po +include test/$(DEPDIR)/gomory_hu_test.Po +include test/$(DEPDIR)/graph_copy_test.Po +include test/$(DEPDIR)/graph_test.Po +include test/$(DEPDIR)/graph_utils_test.Po +include test/$(DEPDIR)/hao_orlin_test.Po +include test/$(DEPDIR)/heap_test.Po +include test/$(DEPDIR)/kruskal_test.Po +include test/$(DEPDIR)/lgf_test.Po +include test/$(DEPDIR)/lp_test.Po +include test/$(DEPDIR)/maps_test.Po +include test/$(DEPDIR)/matching_test.Po +include test/$(DEPDIR)/min_cost_arborescence_test.Po +include test/$(DEPDIR)/min_cost_flow_test.Po +include test/$(DEPDIR)/min_mean_cycle_test.Po +include test/$(DEPDIR)/mip_test.Po +include test/$(DEPDIR)/path_test.Po +include test/$(DEPDIR)/planarity_test.Po +include test/$(DEPDIR)/preflow_test.Po +include test/$(DEPDIR)/radix_sort_test.Po +include test/$(DEPDIR)/random_test.Po +include test/$(DEPDIR)/suurballe_test.Po +include test/$(DEPDIR)/test_tools_fail.Po +include test/$(DEPDIR)/test_tools_pass.Po +include test/$(DEPDIR)/time_measure_test.Po +include test/$(DEPDIR)/unionfind_test.Po +include tools/$(DEPDIR)/dimacs-solver.Po +include tools/$(DEPDIR)/dimacs-to-lgf.Po +include tools/$(DEPDIR)/lgf-gen.Po + +.cc.o: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ + $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Plo +# source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LTCXXCOMPILE) -c -o $@ $< + +lemon/lemon_libemon_la-arg_parser.lo: lemon/arg_parser.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-arg_parser.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Tpo -c -o lemon/lemon_libemon_la-arg_parser.lo `test -f 'lemon/arg_parser.cc' || echo '$(srcdir)/'`lemon/arg_parser.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Tpo lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Plo +# source='lemon/arg_parser.cc' object='lemon/lemon_libemon_la-arg_parser.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-arg_parser.lo `test -f 'lemon/arg_parser.cc' || echo '$(srcdir)/'`lemon/arg_parser.cc + +lemon/lemon_libemon_la-base.lo: lemon/base.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-base.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-base.Tpo -c -o lemon/lemon_libemon_la-base.lo `test -f 'lemon/base.cc' || echo '$(srcdir)/'`lemon/base.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-base.Tpo lemon/$(DEPDIR)/lemon_libemon_la-base.Plo +# source='lemon/base.cc' object='lemon/lemon_libemon_la-base.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-base.lo `test -f 'lemon/base.cc' || echo '$(srcdir)/'`lemon/base.cc + +lemon/lemon_libemon_la-color.lo: lemon/color.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-color.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-color.Tpo -c -o lemon/lemon_libemon_la-color.lo `test -f 'lemon/color.cc' || echo '$(srcdir)/'`lemon/color.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-color.Tpo lemon/$(DEPDIR)/lemon_libemon_la-color.Plo +# source='lemon/color.cc' object='lemon/lemon_libemon_la-color.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-color.lo `test -f 'lemon/color.cc' || echo '$(srcdir)/'`lemon/color.cc + +lemon/lemon_libemon_la-lp_base.lo: lemon/lp_base.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-lp_base.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Tpo -c -o lemon/lemon_libemon_la-lp_base.lo `test -f 'lemon/lp_base.cc' || echo '$(srcdir)/'`lemon/lp_base.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Tpo lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Plo +# source='lemon/lp_base.cc' object='lemon/lemon_libemon_la-lp_base.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-lp_base.lo `test -f 'lemon/lp_base.cc' || echo '$(srcdir)/'`lemon/lp_base.cc + +lemon/lemon_libemon_la-lp_skeleton.lo: lemon/lp_skeleton.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-lp_skeleton.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Tpo -c -o lemon/lemon_libemon_la-lp_skeleton.lo `test -f 'lemon/lp_skeleton.cc' || echo '$(srcdir)/'`lemon/lp_skeleton.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Tpo lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Plo +# source='lemon/lp_skeleton.cc' object='lemon/lemon_libemon_la-lp_skeleton.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-lp_skeleton.lo `test -f 'lemon/lp_skeleton.cc' || echo '$(srcdir)/'`lemon/lp_skeleton.cc + +lemon/lemon_libemon_la-random.lo: lemon/random.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-random.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-random.Tpo -c -o lemon/lemon_libemon_la-random.lo `test -f 'lemon/random.cc' || echo '$(srcdir)/'`lemon/random.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-random.Tpo lemon/$(DEPDIR)/lemon_libemon_la-random.Plo +# source='lemon/random.cc' object='lemon/lemon_libemon_la-random.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-random.lo `test -f 'lemon/random.cc' || echo '$(srcdir)/'`lemon/random.cc + +lemon/bits/lemon_libemon_la-windows.lo: lemon/bits/windows.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/bits/lemon_libemon_la-windows.lo -MD -MP -MF lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Tpo -c -o lemon/bits/lemon_libemon_la-windows.lo `test -f 'lemon/bits/windows.cc' || echo '$(srcdir)/'`lemon/bits/windows.cc + $(am__mv) lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Tpo lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Plo +# source='lemon/bits/windows.cc' object='lemon/bits/lemon_libemon_la-windows.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/bits/lemon_libemon_la-windows.lo `test -f 'lemon/bits/windows.cc' || echo '$(srcdir)/'`lemon/bits/windows.cc + +lemon/lemon_libemon_la-glpk.lo: lemon/glpk.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-glpk.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-glpk.Tpo -c -o lemon/lemon_libemon_la-glpk.lo `test -f 'lemon/glpk.cc' || echo '$(srcdir)/'`lemon/glpk.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-glpk.Tpo lemon/$(DEPDIR)/lemon_libemon_la-glpk.Plo +# source='lemon/glpk.cc' object='lemon/lemon_libemon_la-glpk.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-glpk.lo `test -f 'lemon/glpk.cc' || echo '$(srcdir)/'`lemon/glpk.cc + +lemon/lemon_libemon_la-cplex.lo: lemon/cplex.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-cplex.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-cplex.Tpo -c -o lemon/lemon_libemon_la-cplex.lo `test -f 'lemon/cplex.cc' || echo '$(srcdir)/'`lemon/cplex.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-cplex.Tpo lemon/$(DEPDIR)/lemon_libemon_la-cplex.Plo +# source='lemon/cplex.cc' object='lemon/lemon_libemon_la-cplex.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-cplex.lo `test -f 'lemon/cplex.cc' || echo '$(srcdir)/'`lemon/cplex.cc + +lemon/lemon_libemon_la-soplex.lo: lemon/soplex.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-soplex.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-soplex.Tpo -c -o lemon/lemon_libemon_la-soplex.lo `test -f 'lemon/soplex.cc' || echo '$(srcdir)/'`lemon/soplex.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-soplex.Tpo lemon/$(DEPDIR)/lemon_libemon_la-soplex.Plo +# source='lemon/soplex.cc' object='lemon/lemon_libemon_la-soplex.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-soplex.lo `test -f 'lemon/soplex.cc' || echo '$(srcdir)/'`lemon/soplex.cc + +lemon/lemon_libemon_la-clp.lo: lemon/clp.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-clp.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-clp.Tpo -c -o lemon/lemon_libemon_la-clp.lo `test -f 'lemon/clp.cc' || echo '$(srcdir)/'`lemon/clp.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-clp.Tpo lemon/$(DEPDIR)/lemon_libemon_la-clp.Plo +# source='lemon/clp.cc' object='lemon/lemon_libemon_la-clp.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-clp.lo `test -f 'lemon/clp.cc' || echo '$(srcdir)/'`lemon/clp.cc + +lemon/lemon_libemon_la-cbc.lo: lemon/cbc.cc + $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-cbc.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-cbc.Tpo -c -o lemon/lemon_libemon_la-cbc.lo `test -f 'lemon/cbc.cc' || echo '$(srcdir)/'`lemon/cbc.cc + $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-cbc.Tpo lemon/$(DEPDIR)/lemon_libemon_la-cbc.Plo +# source='lemon/cbc.cc' object='lemon/lemon_libemon_la-cbc.lo' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-cbc.lo `test -f 'lemon/cbc.cc' || echo '$(srcdir)/'`lemon/cbc.cc + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf lemon/.libs lemon/_libs + -rm -rf lemon/bits/.libs lemon/bits/_libs + -rm -rf test/.libs test/_libs + -rm -rf tools/.libs tools/_libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files +install-bitsHEADERS: $(bits_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(bitsdir)" || $(MKDIR_P) "$(DESTDIR)$(bitsdir)" + @list='$(bits_HEADERS)'; test -n "$(bitsdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(bitsdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(bitsdir)" || exit $$?; \ + done + +uninstall-bitsHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(bits_HEADERS)'; test -n "$(bitsdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bitsdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bitsdir)" && rm -f $$files +install-conceptHEADERS: $(concept_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(conceptdir)" || $(MKDIR_P) "$(DESTDIR)$(conceptdir)" + @list='$(concept_HEADERS)'; test -n "$(conceptdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(conceptdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(conceptdir)" || exit $$?; \ + done + +uninstall-conceptHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(concept_HEADERS)'; test -n "$(conceptdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(conceptdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(conceptdir)" && rm -f $$files +install-lemonHEADERS: $(lemon_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(lemondir)" || $(MKDIR_P) "$(DESTDIR)$(lemondir)" + @list='$(lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(lemondir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(lemondir)" || exit $$?; \ + done + +uninstall-lemonHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(lemondir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(lemondir)" && rm -f $$files +install-nodist_lemonHEADERS: $(nodist_lemon_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(lemondir)" || $(MKDIR_P) "$(DESTDIR)$(lemondir)" + @list='$(nodist_lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(lemondir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(lemondir)" || exit $$?; \ + done + +uninstall-nodist_lemonHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(lemondir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(lemondir)" && rm -f $$files + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \ + $(HEADERS) config.h +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(bitsdir)" "$(DESTDIR)$(conceptdir)" "$(DESTDIR)$(lemondir)" "$(DESTDIR)$(lemondir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f lemon/$(DEPDIR)/$(am__dirstamp) + -rm -f lemon/$(am__dirstamp) + -rm -f lemon/bits/$(DEPDIR)/$(am__dirstamp) + -rm -f lemon/bits/$(am__dirstamp) + -rm -f test/$(DEPDIR)/$(am__dirstamp) + -rm -f test/$(am__dirstamp) + -rm -f tools/$(DEPDIR)/$(am__dirstamp) + -rm -f tools/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf lemon/$(DEPDIR) lemon/bits/$(DEPDIR) test/$(DEPDIR) tools/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: html-local + +info: info-recursive + +info-am: + +install-data-am: install-bitsHEADERS install-conceptHEADERS \ + install-lemonHEADERS install-nodist_lemonHEADERS \ + install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-dist_binSCRIPTS \ + install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: install-html-local + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf lemon/$(DEPDIR) lemon/bits/$(DEPDIR) test/$(DEPDIR) tools/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-bitsHEADERS \ + uninstall-conceptHEADERS uninstall-dist_binSCRIPTS \ + uninstall-lemonHEADERS uninstall-libLTLIBRARIES \ + uninstall-local uninstall-nodist_lemonHEADERS \ + uninstall-pkgconfigDATA + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-TESTS check-am clean \ + clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-noinstPROGRAMS ctags ctags-recursive dist dist-all \ + dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am html-local info info-am install install-am \ + install-binPROGRAMS install-bitsHEADERS install-conceptHEADERS \ + install-data install-data-am install-dist_binSCRIPTS \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-html-local install-info \ + install-info-am install-lemonHEADERS install-libLTLIBRARIES \ + install-man install-nodist_lemonHEADERS install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-bitsHEADERS uninstall-conceptHEADERS \ + uninstall-dist_binSCRIPTS uninstall-lemonHEADERS \ + uninstall-libLTLIBRARIES uninstall-local \ + uninstall-nodist_lemonHEADERS uninstall-pkgconfigDATA + + +doc/html: + $(MAKE) $(AM_MAKEFLAGS) html + +$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps + -mkdir doc/gen-images + if test ${gs_found} = yes; then \ + $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \ + else \ + echo; \ + echo "Ghostscript not found."; \ + echo; \ + exit 1; \ + fi + +$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps + -mkdir doc/gen-images + if test ${gs_found} = yes; then \ + $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \ + else \ + echo; \ + echo "Ghostscript not found."; \ + echo; \ + exit 1; \ + fi + +references.dox: doc/references.bib + if test ${python_found} = yes; then \ + cd doc; \ + python /home/carlo/honours/lemon/scripts/bib2dox.py /home/carlo/honours/lemon/$< >$@; \ + cd ..; \ + else \ + echo; \ + echo "Python not found."; \ + echo; \ + exit 1; \ + fi + +html-local: $(DOC_PNG_IMAGES) references.dox + if test ${doxygen_found} = yes; then \ + cd doc; \ + doxygen Doxyfile; \ + cd ..; \ + else \ + echo; \ + echo "Doxygen not found."; \ + echo; \ + exit 1; \ + fi + +clean-local: + -rm -rf doc/html + -rm -f doc/doxygen.log + -rm -f $(DOC_PNG_IMAGES) + -rm -rf doc/gen-images + +update-external-tags: + wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \ + mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \ + rm doc/libstdc++.tag.tmp + +install-html-local: doc/html + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(htmldir)/html + for p in doc/html/*.{html,css,png,map,gif,tag} ; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \ + done + +uninstall-local: + @$(NORMAL_UNINSTALL) + for p in doc/html/*.{html,css,png,map,gif,tag} ; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \ + rm -f $(DESTDIR)$(htmldir)/html/$$f; \ + done + +.PHONY: update-external-tags + +demo: + $(MAKE) $(AM_MAKEFLAGS) -C demo + +mrproper: + $(MAKE) $(AM_MAKEFLAGS) maintainer-clean + -rm -f $(MRPROPERFILES) + +dist-bz2: dist + zcat $(PACKAGE)-$(VERSION).tar.gz | \ + bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2 + +distcheck-bz2: distcheck + zcat $(PACKAGE)-$(VERSION).tar.gz | \ + bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2 + +.PHONY: demo mrproper dist-bz2 distcheck-bz2 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lemon/Makefile.am b/lemon/Makefile.am new file mode 100644 index 0000000..9c86f2a --- /dev/null +++ b/lemon/Makefile.am @@ -0,0 +1,80 @@ +ACLOCAL_AMFLAGS = -I m4 + +AM_CXXFLAGS = $(WARNINGCXXFLAGS) + +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) +LDADD = $(top_builddir)/lemon/libemon.la + +EXTRA_DIST = \ + AUTHORS \ + LICENSE \ + m4/lx_check_cplex.m4 \ + m4/lx_check_glpk.m4 \ + m4/lx_check_soplex.m4 \ + m4/lx_check_coin.m4 \ + CMakeLists.txt \ + cmake/FindGhostscript.cmake \ + cmake/FindCPLEX.cmake \ + cmake/FindGLPK.cmake \ + cmake/FindCOIN.cmake \ + cmake/LEMONConfig.cmake.in \ + cmake/version.cmake.in \ + cmake/version.cmake \ + cmake/nsis/lemon.ico \ + cmake/nsis/uninstall.ico + +pkgconfigdir = $(libdir)/pkgconfig +lemondir = $(pkgincludedir) +bitsdir = $(lemondir)/bits +conceptdir = $(lemondir)/concepts +pkgconfig_DATA = +lib_LTLIBRARIES = +lemon_HEADERS = +bits_HEADERS = +concept_HEADERS = +noinst_HEADERS = +noinst_PROGRAMS = +bin_PROGRAMS = +check_PROGRAMS = +dist_bin_SCRIPTS = +TESTS = +XFAIL_TESTS = + +include lemon/Makefile.am +include test/Makefile.am +include doc/Makefile.am +include tools/Makefile.am +include scripts/Makefile.am + +DIST_SUBDIRS = demo + +demo: + $(MAKE) $(AM_MAKEFLAGS) -C demo + +MRPROPERFILES = \ + aclocal.m4 \ + config.h.in \ + config.h.in~ \ + configure \ + Makefile.in \ + build-aux/config.guess \ + build-aux/config.sub \ + build-aux/depcomp \ + build-aux/install-sh \ + build-aux/ltmain.sh \ + build-aux/missing \ + doc/doxygen.log + +mrproper: + $(MAKE) $(AM_MAKEFLAGS) maintainer-clean + -rm -f $(MRPROPERFILES) + +dist-bz2: dist + zcat $(PACKAGE)-$(VERSION).tar.gz | \ + bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2 + +distcheck-bz2: distcheck + zcat $(PACKAGE)-$(VERSION).tar.gz | \ + bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2 + +.PHONY: demo mrproper dist-bz2 distcheck-bz2 diff --git a/lemon/Makefile.in b/lemon/Makefile.in new file mode 100644 index 0000000..d54f863 --- /dev/null +++ b/lemon/Makefile.in @@ -0,0 +1,2241 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = +bin_PROGRAMS = $(am__EXEEXT_1) +check_PROGRAMS = test/adaptors_test$(EXEEXT) \ + test/bellman_ford_test$(EXEEXT) test/bfs_test$(EXEEXT) \ + test/circulation_test$(EXEEXT) test/connectivity_test$(EXEEXT) \ + test/counter_test$(EXEEXT) test/dfs_test$(EXEEXT) \ + test/digraph_test$(EXEEXT) test/dijkstra_test$(EXEEXT) \ + test/dim_test$(EXEEXT) test/edge_set_test$(EXEEXT) \ + test/error_test$(EXEEXT) test/euler_test$(EXEEXT) \ + test/fractional_matching_test$(EXEEXT) \ + test/gomory_hu_test$(EXEEXT) test/graph_copy_test$(EXEEXT) \ + test/graph_test$(EXEEXT) test/graph_utils_test$(EXEEXT) \ + test/hao_orlin_test$(EXEEXT) test/heap_test$(EXEEXT) \ + test/kruskal_test$(EXEEXT) test/lgf_test$(EXEEXT) \ + test/maps_test$(EXEEXT) test/matching_test$(EXEEXT) \ + test/min_cost_arborescence_test$(EXEEXT) \ + test/min_cost_flow_test$(EXEEXT) \ + test/min_mean_cycle_test$(EXEEXT) test/path_test$(EXEEXT) \ + test/planarity_test$(EXEEXT) test/preflow_test$(EXEEXT) \ + test/radix_sort_test$(EXEEXT) test/random_test$(EXEEXT) \ + test/suurballe_test$(EXEEXT) test/test_tools_fail$(EXEEXT) \ + test/test_tools_pass$(EXEEXT) test/time_measure_test$(EXEEXT) \ + test/unionfind_test$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) +DIST_COMMON = README $(am__configure_deps) \ + $(am__dist_bin_SCRIPTS_DIST) $(bits_HEADERS) \ + $(concept_HEADERS) $(lemon_HEADERS) $(noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/config.h.in $(srcdir)/doc/Makefile.am \ + $(srcdir)/lemon/Makefile.am $(srcdir)/scripts/Makefile.am \ + $(srcdir)/test/Makefile.am $(srcdir)/tools/Makefile.am \ + $(top_srcdir)/cmake/version.cmake.in $(top_srcdir)/configure \ + $(top_srcdir)/doc/Doxyfile.in \ + $(top_srcdir)/doc/mainpage.dox.in \ + $(top_srcdir)/lemon/config.h.in \ + $(top_srcdir)/lemon/lemon.pc.in AUTHORS INSTALL NEWS \ + build-aux/config.guess build-aux/config.sub build-aux/depcomp \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing +@HAVE_GLPK_TRUE@am__append_1 = lemon/glpk.cc +@HAVE_CPLEX_TRUE@am__append_2 = lemon/cplex.cc +@HAVE_SOPLEX_TRUE@am__append_3 = lemon/soplex.cc +@HAVE_CLP_TRUE@am__append_4 = lemon/clp.cc +@HAVE_CBC_TRUE@am__append_5 = lemon/cbc.cc +@HAVE_LP_TRUE@am__append_6 = test/lp_test +@HAVE_MIP_TRUE@am__append_7 = test/mip_test +@WANT_TOOLS_TRUE@am__append_8 = \ +@WANT_TOOLS_TRUE@ tools/dimacs-solver \ +@WANT_TOOLS_TRUE@ tools/dimacs-to-lgf \ +@WANT_TOOLS_TRUE@ tools/lgf-gen + +@WANT_TOOLS_TRUE@am__append_9 = tools/lemon-0.x-to-1.x.sh +subdir = . +SUBDIRS = +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/lx_check_coin.m4 \ + $(top_srcdir)/m4/lx_check_cplex.m4 \ + $(top_srcdir)/m4/lx_check_glpk.m4 \ + $(top_srcdir)/m4/lx_check_soplex.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h $(top_builddir)/lemon/config.h +CONFIG_CLEAN_FILES = cmake/version.cmake doc/Doxyfile doc/mainpage.dox \ + lemon/lemon.pc +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(bitsdir)" "$(DESTDIR)$(conceptdir)" \ + "$(DESTDIR)$(lemondir)" "$(DESTDIR)$(lemondir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +lemon_libemon_la_LIBADD = +am__lemon_libemon_la_SOURCES_DIST = lemon/arg_parser.cc lemon/base.cc \ + lemon/color.cc lemon/lp_base.cc lemon/lp_skeleton.cc \ + lemon/random.cc lemon/bits/windows.cc lemon/glpk.cc \ + lemon/cplex.cc lemon/soplex.cc lemon/clp.cc lemon/cbc.cc +am__dirstamp = $(am__leading_dot)dirstamp +@HAVE_GLPK_TRUE@am__objects_1 = lemon/lemon_libemon_la-glpk.lo +@HAVE_CPLEX_TRUE@am__objects_2 = lemon/lemon_libemon_la-cplex.lo +@HAVE_SOPLEX_TRUE@am__objects_3 = lemon/lemon_libemon_la-soplex.lo +@HAVE_CLP_TRUE@am__objects_4 = lemon/lemon_libemon_la-clp.lo +@HAVE_CBC_TRUE@am__objects_5 = lemon/lemon_libemon_la-cbc.lo +am_lemon_libemon_la_OBJECTS = lemon/lemon_libemon_la-arg_parser.lo \ + lemon/lemon_libemon_la-base.lo lemon/lemon_libemon_la-color.lo \ + lemon/lemon_libemon_la-lp_base.lo \ + lemon/lemon_libemon_la-lp_skeleton.lo \ + lemon/lemon_libemon_la-random.lo \ + lemon/bits/lemon_libemon_la-windows.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) \ + $(am__objects_5) +lemon_libemon_la_OBJECTS = $(am_lemon_libemon_la_OBJECTS) +lemon_libemon_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) \ + $(lemon_libemon_la_LDFLAGS) $(LDFLAGS) -o $@ +@WANT_TOOLS_TRUE@am__EXEEXT_1 = tools/dimacs-solver$(EXEEXT) \ +@WANT_TOOLS_TRUE@ tools/dimacs-to-lgf$(EXEEXT) \ +@WANT_TOOLS_TRUE@ tools/lgf-gen$(EXEEXT) +@HAVE_LP_TRUE@am__EXEEXT_2 = test/lp_test$(EXEEXT) +@HAVE_MIP_TRUE@am__EXEEXT_3 = test/mip_test$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am_test_adaptors_test_OBJECTS = test/adaptors_test.$(OBJEXT) +test_adaptors_test_OBJECTS = $(am_test_adaptors_test_OBJECTS) +test_adaptors_test_LDADD = $(LDADD) +test_adaptors_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_bellman_ford_test_OBJECTS = test/bellman_ford_test.$(OBJEXT) +test_bellman_ford_test_OBJECTS = $(am_test_bellman_ford_test_OBJECTS) +test_bellman_ford_test_LDADD = $(LDADD) +test_bellman_ford_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_bfs_test_OBJECTS = test/bfs_test.$(OBJEXT) +test_bfs_test_OBJECTS = $(am_test_bfs_test_OBJECTS) +test_bfs_test_LDADD = $(LDADD) +test_bfs_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_circulation_test_OBJECTS = test/circulation_test.$(OBJEXT) +test_circulation_test_OBJECTS = $(am_test_circulation_test_OBJECTS) +test_circulation_test_LDADD = $(LDADD) +test_circulation_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_connectivity_test_OBJECTS = test/connectivity_test.$(OBJEXT) +test_connectivity_test_OBJECTS = $(am_test_connectivity_test_OBJECTS) +test_connectivity_test_LDADD = $(LDADD) +test_connectivity_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_counter_test_OBJECTS = test/counter_test.$(OBJEXT) +test_counter_test_OBJECTS = $(am_test_counter_test_OBJECTS) +test_counter_test_LDADD = $(LDADD) +test_counter_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_dfs_test_OBJECTS = test/dfs_test.$(OBJEXT) +test_dfs_test_OBJECTS = $(am_test_dfs_test_OBJECTS) +test_dfs_test_LDADD = $(LDADD) +test_dfs_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_digraph_test_OBJECTS = test/digraph_test.$(OBJEXT) +test_digraph_test_OBJECTS = $(am_test_digraph_test_OBJECTS) +test_digraph_test_LDADD = $(LDADD) +test_digraph_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_dijkstra_test_OBJECTS = test/dijkstra_test.$(OBJEXT) +test_dijkstra_test_OBJECTS = $(am_test_dijkstra_test_OBJECTS) +test_dijkstra_test_LDADD = $(LDADD) +test_dijkstra_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_dim_test_OBJECTS = test/dim_test.$(OBJEXT) +test_dim_test_OBJECTS = $(am_test_dim_test_OBJECTS) +test_dim_test_LDADD = $(LDADD) +test_dim_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_edge_set_test_OBJECTS = test/edge_set_test.$(OBJEXT) +test_edge_set_test_OBJECTS = $(am_test_edge_set_test_OBJECTS) +test_edge_set_test_LDADD = $(LDADD) +test_edge_set_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_error_test_OBJECTS = test/error_test.$(OBJEXT) +test_error_test_OBJECTS = $(am_test_error_test_OBJECTS) +test_error_test_LDADD = $(LDADD) +test_error_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_euler_test_OBJECTS = test/euler_test.$(OBJEXT) +test_euler_test_OBJECTS = $(am_test_euler_test_OBJECTS) +test_euler_test_LDADD = $(LDADD) +test_euler_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_fractional_matching_test_OBJECTS = \ + test/fractional_matching_test.$(OBJEXT) +test_fractional_matching_test_OBJECTS = \ + $(am_test_fractional_matching_test_OBJECTS) +test_fractional_matching_test_LDADD = $(LDADD) +test_fractional_matching_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_gomory_hu_test_OBJECTS = test/gomory_hu_test.$(OBJEXT) +test_gomory_hu_test_OBJECTS = $(am_test_gomory_hu_test_OBJECTS) +test_gomory_hu_test_LDADD = $(LDADD) +test_gomory_hu_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_graph_copy_test_OBJECTS = test/graph_copy_test.$(OBJEXT) +test_graph_copy_test_OBJECTS = $(am_test_graph_copy_test_OBJECTS) +test_graph_copy_test_LDADD = $(LDADD) +test_graph_copy_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_graph_test_OBJECTS = test/graph_test.$(OBJEXT) +test_graph_test_OBJECTS = $(am_test_graph_test_OBJECTS) +test_graph_test_LDADD = $(LDADD) +test_graph_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_graph_utils_test_OBJECTS = test/graph_utils_test.$(OBJEXT) +test_graph_utils_test_OBJECTS = $(am_test_graph_utils_test_OBJECTS) +test_graph_utils_test_LDADD = $(LDADD) +test_graph_utils_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_hao_orlin_test_OBJECTS = test/hao_orlin_test.$(OBJEXT) +test_hao_orlin_test_OBJECTS = $(am_test_hao_orlin_test_OBJECTS) +test_hao_orlin_test_LDADD = $(LDADD) +test_hao_orlin_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_heap_test_OBJECTS = test/heap_test.$(OBJEXT) +test_heap_test_OBJECTS = $(am_test_heap_test_OBJECTS) +test_heap_test_LDADD = $(LDADD) +test_heap_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_kruskal_test_OBJECTS = test/kruskal_test.$(OBJEXT) +test_kruskal_test_OBJECTS = $(am_test_kruskal_test_OBJECTS) +test_kruskal_test_LDADD = $(LDADD) +test_kruskal_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_lgf_test_OBJECTS = test/lgf_test.$(OBJEXT) +test_lgf_test_OBJECTS = $(am_test_lgf_test_OBJECTS) +test_lgf_test_LDADD = $(LDADD) +test_lgf_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_lp_test_OBJECTS = test/lp_test.$(OBJEXT) +test_lp_test_OBJECTS = $(am_test_lp_test_OBJECTS) +test_lp_test_LDADD = $(LDADD) +test_lp_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_maps_test_OBJECTS = test/maps_test.$(OBJEXT) +test_maps_test_OBJECTS = $(am_test_maps_test_OBJECTS) +test_maps_test_LDADD = $(LDADD) +test_maps_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_matching_test_OBJECTS = test/matching_test.$(OBJEXT) +test_matching_test_OBJECTS = $(am_test_matching_test_OBJECTS) +test_matching_test_LDADD = $(LDADD) +test_matching_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_min_cost_arborescence_test_OBJECTS = \ + test/min_cost_arborescence_test.$(OBJEXT) +test_min_cost_arborescence_test_OBJECTS = \ + $(am_test_min_cost_arborescence_test_OBJECTS) +test_min_cost_arborescence_test_LDADD = $(LDADD) +test_min_cost_arborescence_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_min_cost_flow_test_OBJECTS = \ + test/min_cost_flow_test.$(OBJEXT) +test_min_cost_flow_test_OBJECTS = \ + $(am_test_min_cost_flow_test_OBJECTS) +test_min_cost_flow_test_LDADD = $(LDADD) +test_min_cost_flow_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_min_mean_cycle_test_OBJECTS = \ + test/min_mean_cycle_test.$(OBJEXT) +test_min_mean_cycle_test_OBJECTS = \ + $(am_test_min_mean_cycle_test_OBJECTS) +test_min_mean_cycle_test_LDADD = $(LDADD) +test_min_mean_cycle_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_mip_test_OBJECTS = test/mip_test.$(OBJEXT) +test_mip_test_OBJECTS = $(am_test_mip_test_OBJECTS) +test_mip_test_LDADD = $(LDADD) +test_mip_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_path_test_OBJECTS = test/path_test.$(OBJEXT) +test_path_test_OBJECTS = $(am_test_path_test_OBJECTS) +test_path_test_LDADD = $(LDADD) +test_path_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_planarity_test_OBJECTS = test/planarity_test.$(OBJEXT) +test_planarity_test_OBJECTS = $(am_test_planarity_test_OBJECTS) +test_planarity_test_LDADD = $(LDADD) +test_planarity_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_preflow_test_OBJECTS = test/preflow_test.$(OBJEXT) +test_preflow_test_OBJECTS = $(am_test_preflow_test_OBJECTS) +test_preflow_test_LDADD = $(LDADD) +test_preflow_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_radix_sort_test_OBJECTS = test/radix_sort_test.$(OBJEXT) +test_radix_sort_test_OBJECTS = $(am_test_radix_sort_test_OBJECTS) +test_radix_sort_test_LDADD = $(LDADD) +test_radix_sort_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_random_test_OBJECTS = test/random_test.$(OBJEXT) +test_random_test_OBJECTS = $(am_test_random_test_OBJECTS) +test_random_test_LDADD = $(LDADD) +test_random_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_suurballe_test_OBJECTS = test/suurballe_test.$(OBJEXT) +test_suurballe_test_OBJECTS = $(am_test_suurballe_test_OBJECTS) +test_suurballe_test_LDADD = $(LDADD) +test_suurballe_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_test_tools_fail_OBJECTS = test/test_tools_fail.$(OBJEXT) +test_test_tools_fail_OBJECTS = $(am_test_test_tools_fail_OBJECTS) +test_test_tools_fail_LDADD = $(LDADD) +test_test_tools_fail_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_test_test_tools_pass_OBJECTS = test/test_tools_pass.$(OBJEXT) +test_test_tools_pass_OBJECTS = $(am_test_test_tools_pass_OBJECTS) +test_test_tools_pass_LDADD = $(LDADD) +am_test_time_measure_test_OBJECTS = test/time_measure_test.$(OBJEXT) +test_time_measure_test_OBJECTS = $(am_test_time_measure_test_OBJECTS) +test_time_measure_test_LDADD = $(LDADD) +test_time_measure_test_DEPENDENCIES = \ + $(top_builddir)/lemon/libemon.la +am_test_unionfind_test_OBJECTS = test/unionfind_test.$(OBJEXT) +test_unionfind_test_OBJECTS = $(am_test_unionfind_test_OBJECTS) +test_unionfind_test_LDADD = $(LDADD) +test_unionfind_test_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_tools_dimacs_solver_OBJECTS = tools/dimacs-solver.$(OBJEXT) +tools_dimacs_solver_OBJECTS = $(am_tools_dimacs_solver_OBJECTS) +tools_dimacs_solver_LDADD = $(LDADD) +tools_dimacs_solver_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_tools_dimacs_to_lgf_OBJECTS = tools/dimacs-to-lgf.$(OBJEXT) +tools_dimacs_to_lgf_OBJECTS = $(am_tools_dimacs_to_lgf_OBJECTS) +tools_dimacs_to_lgf_LDADD = $(LDADD) +tools_dimacs_to_lgf_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_tools_lgf_gen_OBJECTS = tools/lgf-gen.$(OBJEXT) +tools_lgf_gen_OBJECTS = $(am_tools_lgf_gen_OBJECTS) +tools_lgf_gen_LDADD = $(LDADD) +tools_lgf_gen_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am__dist_bin_SCRIPTS_DIST = tools/lemon-0.x-to-1.x.sh +SCRIPTS = $(dist_bin_SCRIPTS) +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(lemon_libemon_la_SOURCES) $(test_adaptors_test_SOURCES) \ + $(test_bellman_ford_test_SOURCES) $(test_bfs_test_SOURCES) \ + $(test_circulation_test_SOURCES) \ + $(test_connectivity_test_SOURCES) $(test_counter_test_SOURCES) \ + $(test_dfs_test_SOURCES) $(test_digraph_test_SOURCES) \ + $(test_dijkstra_test_SOURCES) $(test_dim_test_SOURCES) \ + $(test_edge_set_test_SOURCES) $(test_error_test_SOURCES) \ + $(test_euler_test_SOURCES) \ + $(test_fractional_matching_test_SOURCES) \ + $(test_gomory_hu_test_SOURCES) $(test_graph_copy_test_SOURCES) \ + $(test_graph_test_SOURCES) $(test_graph_utils_test_SOURCES) \ + $(test_hao_orlin_test_SOURCES) $(test_heap_test_SOURCES) \ + $(test_kruskal_test_SOURCES) $(test_lgf_test_SOURCES) \ + $(test_lp_test_SOURCES) $(test_maps_test_SOURCES) \ + $(test_matching_test_SOURCES) \ + $(test_min_cost_arborescence_test_SOURCES) \ + $(test_min_cost_flow_test_SOURCES) \ + $(test_min_mean_cycle_test_SOURCES) $(test_mip_test_SOURCES) \ + $(test_path_test_SOURCES) $(test_planarity_test_SOURCES) \ + $(test_preflow_test_SOURCES) $(test_radix_sort_test_SOURCES) \ + $(test_random_test_SOURCES) $(test_suurballe_test_SOURCES) \ + $(test_test_tools_fail_SOURCES) \ + $(test_test_tools_pass_SOURCES) \ + $(test_time_measure_test_SOURCES) \ + $(test_unionfind_test_SOURCES) $(tools_dimacs_solver_SOURCES) \ + $(tools_dimacs_to_lgf_SOURCES) $(tools_lgf_gen_SOURCES) +DIST_SOURCES = $(am__lemon_libemon_la_SOURCES_DIST) \ + $(test_adaptors_test_SOURCES) \ + $(test_bellman_ford_test_SOURCES) $(test_bfs_test_SOURCES) \ + $(test_circulation_test_SOURCES) \ + $(test_connectivity_test_SOURCES) $(test_counter_test_SOURCES) \ + $(test_dfs_test_SOURCES) $(test_digraph_test_SOURCES) \ + $(test_dijkstra_test_SOURCES) $(test_dim_test_SOURCES) \ + $(test_edge_set_test_SOURCES) $(test_error_test_SOURCES) \ + $(test_euler_test_SOURCES) \ + $(test_fractional_matching_test_SOURCES) \ + $(test_gomory_hu_test_SOURCES) $(test_graph_copy_test_SOURCES) \ + $(test_graph_test_SOURCES) $(test_graph_utils_test_SOURCES) \ + $(test_hao_orlin_test_SOURCES) $(test_heap_test_SOURCES) \ + $(test_kruskal_test_SOURCES) $(test_lgf_test_SOURCES) \ + $(test_lp_test_SOURCES) $(test_maps_test_SOURCES) \ + $(test_matching_test_SOURCES) \ + $(test_min_cost_arborescence_test_SOURCES) \ + $(test_min_cost_flow_test_SOURCES) \ + $(test_min_mean_cycle_test_SOURCES) $(test_mip_test_SOURCES) \ + $(test_path_test_SOURCES) $(test_planarity_test_SOURCES) \ + $(test_preflow_test_SOURCES) $(test_radix_sort_test_SOURCES) \ + $(test_random_test_SOURCES) $(test_suurballe_test_SOURCES) \ + $(test_test_tools_fail_SOURCES) \ + $(test_test_tools_pass_SOURCES) \ + $(test_time_measure_test_SOURCES) \ + $(test_unionfind_test_SOURCES) $(tools_dimacs_solver_SOURCES) \ + $(tools_dimacs_to_lgf_SOURCES) $(tools_lgf_gen_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +DATA = $(pkgconfig_DATA) +HEADERS = $(bits_HEADERS) $(concept_HEADERS) $(lemon_HEADERS) \ + $(nodist_lemon_HEADERS) $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CBC_CXXFLAGS = @CBC_CXXFLAGS@ +CBC_LIBS = @CBC_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLP_CXXFLAGS = @CLP_CXXFLAGS@ +CLP_LIBS = @CLP_LIBS@ +CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ +CPLEX_CFLAGS = @CPLEX_CFLAGS@ +CPLEX_LIBS = @CPLEX_LIBS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GLPK_CFLAGS = @GLPK_CFLAGS@ +GLPK_LIBS = @GLPK_LIBS@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOPLEX_CXXFLAGS = @SOPLEX_CXXFLAGS@ +SOPLEX_LIBS = @SOPLEX_LIBS@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WARNINGCXXFLAGS = @WARNINGCXXFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +doxygen_found = @doxygen_found@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gs_found = @gs_found@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +python_found = @python_found@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I m4 +AM_CXXFLAGS = $(WARNINGCXXFLAGS) +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) +LDADD = $(top_builddir)/lemon/libemon.la +EXTRA_DIST = AUTHORS LICENSE m4/lx_check_cplex.m4 m4/lx_check_glpk.m4 \ + m4/lx_check_soplex.m4 m4/lx_check_coin.m4 CMakeLists.txt \ + cmake/FindGhostscript.cmake cmake/FindCPLEX.cmake \ + cmake/FindGLPK.cmake cmake/FindCOIN.cmake \ + cmake/LEMONConfig.cmake.in cmake/version.cmake.in \ + cmake/version.cmake cmake/nsis/lemon.ico \ + cmake/nsis/uninstall.ico lemon/lemon.pc.in \ + lemon/lemon.pc.cmake lemon/CMakeLists.txt lemon/config.h.cmake \ + test/CMakeLists.txt doc/Doxyfile.in doc/DoxygenLayout.xml \ + doc/coding_style.dox doc/dirs.dox doc/groups.dox doc/lgf.dox \ + doc/license.dox doc/mainpage.dox doc/migration.dox \ + doc/min_cost_flow.dox doc/named-param.dox doc/namespaces.dox \ + doc/html doc/CMakeLists.txt $(DOC_EPS_IMAGES:%=doc/images/%) \ + tools/CMakeLists.txt scripts/bib2dox.py scripts/bootstrap.sh \ + scripts/chg-len.py scripts/mk-release.sh \ + scripts/unify-sources.sh scripts/valgrind-wrapper.sh +pkgconfigdir = $(libdir)/pkgconfig +lemondir = $(pkgincludedir) +bitsdir = $(lemondir)/bits +conceptdir = $(lemondir)/concepts +pkgconfig_DATA = lemon/lemon.pc +lib_LTLIBRARIES = lemon/libemon.la +lemon_HEADERS = lemon/adaptors.h lemon/arg_parser.h lemon/assert.h \ + lemon/bellman_ford.h lemon/bfs.h lemon/bin_heap.h \ + lemon/binomial_heap.h lemon/bucket_heap.h \ + lemon/capacity_scaling.h lemon/cbc.h lemon/circulation.h \ + lemon/clp.h lemon/color.h lemon/concept_check.h \ + lemon/connectivity.h lemon/core.h lemon/cost_scaling.h \ + lemon/counter.h lemon/cplex.h lemon/cycle_canceling.h \ + lemon/dfs.h lemon/dheap.h lemon/dijkstra.h lemon/dim2.h \ + lemon/dimacs.h lemon/edge_set.h lemon/elevator.h lemon/error.h \ + lemon/euler.h lemon/fib_heap.h lemon/fractional_matching.h \ + lemon/full_graph.h lemon/glpk.h lemon/gomory_hu.h \ + lemon/graph_to_eps.h lemon/grid_graph.h \ + lemon/hartmann_orlin_mmc.h lemon/howard_mmc.h \ + lemon/hypercube_graph.h lemon/karp_mmc.h lemon/kruskal.h \ + lemon/hao_orlin.h lemon/lgf_reader.h lemon/lgf_writer.h \ + lemon/list_graph.h lemon/lp.h lemon/lp_base.h \ + lemon/lp_skeleton.h lemon/maps.h lemon/matching.h lemon/math.h \ + lemon/min_cost_arborescence.h lemon/nauty_reader.h \ + lemon/network_simplex.h lemon/pairing_heap.h lemon/path.h \ + lemon/planarity.h lemon/preflow.h lemon/quad_heap.h \ + lemon/radix_heap.h lemon/radix_sort.h lemon/random.h \ + lemon/smart_graph.h lemon/soplex.h lemon/static_graph.h \ + lemon/suurballe.h lemon/time_measure.h lemon/tolerance.h \ + lemon/unionfind.h lemon/bits/windows.h +bits_HEADERS = lemon/bits/alteration_notifier.h lemon/bits/array_map.h \ + lemon/bits/bezier.h lemon/bits/default_map.h \ + lemon/bits/edge_set_extender.h lemon/bits/enable_if.h \ + lemon/bits/graph_adaptor_extender.h \ + lemon/bits/graph_extender.h lemon/bits/map_extender.h \ + lemon/bits/path_dump.h lemon/bits/solver_bits.h \ + lemon/bits/traits.h lemon/bits/variant.h \ + lemon/bits/vector_map.h +concept_HEADERS = lemon/concepts/digraph.h lemon/concepts/graph.h \ + lemon/concepts/graph_components.h lemon/concepts/heap.h \ + lemon/concepts/maps.h lemon/concepts/path.h +noinst_HEADERS = test/graph_test.h test/test_tools.h +dist_bin_SCRIPTS = $(am__append_9) +TESTS = $(check_PROGRAMS) +XFAIL_TESTS = test/test_tools_fail$(EXEEXT) +lemon_libemon_la_SOURCES = lemon/arg_parser.cc lemon/base.cc \ + lemon/color.cc lemon/lp_base.cc lemon/lp_skeleton.cc \ + lemon/random.cc lemon/bits/windows.cc $(am__append_1) \ + $(am__append_2) $(am__append_3) $(am__append_4) \ + $(am__append_5) +nodist_lemon_HEADERS = lemon/config.h +lemon_libemon_la_CXXFLAGS = \ + $(AM_CXXFLAGS) \ + $(GLPK_CFLAGS) \ + $(CPLEX_CFLAGS) \ + $(SOPLEX_CXXFLAGS) \ + $(CLP_CXXFLAGS) \ + $(CBC_CXXFLAGS) + +lemon_libemon_la_LDFLAGS = \ + $(GLPK_LIBS) \ + $(CPLEX_LIBS) \ + $(SOPLEX_LIBS) \ + $(CLP_LIBS) \ + $(CBC_LIBS) + +@USE_VALGRIND_TRUE@TESTS_ENVIRONMENT = $(top_srcdir)/scripts/valgrind-wrapper.sh +test_test_tools_pass_DEPENDENCIES = demo +test_adaptors_test_SOURCES = test/adaptors_test.cc +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc +test_bfs_test_SOURCES = test/bfs_test.cc +test_circulation_test_SOURCES = test/circulation_test.cc +test_counter_test_SOURCES = test/counter_test.cc +test_connectivity_test_SOURCES = test/connectivity_test.cc +test_dfs_test_SOURCES = test/dfs_test.cc +test_digraph_test_SOURCES = test/digraph_test.cc +test_dijkstra_test_SOURCES = test/dijkstra_test.cc +test_dim_test_SOURCES = test/dim_test.cc +test_edge_set_test_SOURCES = test/edge_set_test.cc +test_error_test_SOURCES = test/error_test.cc +test_euler_test_SOURCES = test/euler_test.cc +test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc +test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc +test_graph_copy_test_SOURCES = test/graph_copy_test.cc +test_graph_test_SOURCES = test/graph_test.cc +test_graph_utils_test_SOURCES = test/graph_utils_test.cc +test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc +test_heap_test_SOURCES = test/heap_test.cc +test_kruskal_test_SOURCES = test/kruskal_test.cc +test_lgf_test_SOURCES = test/lgf_test.cc +test_lp_test_SOURCES = test/lp_test.cc +test_maps_test_SOURCES = test/maps_test.cc +test_mip_test_SOURCES = test/mip_test.cc +test_matching_test_SOURCES = test/matching_test.cc +test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc +test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc +test_path_test_SOURCES = test/path_test.cc +test_planarity_test_SOURCES = test/planarity_test.cc +test_preflow_test_SOURCES = test/preflow_test.cc +test_radix_sort_test_SOURCES = test/radix_sort_test.cc +test_suurballe_test_SOURCES = test/suurballe_test.cc +test_random_test_SOURCES = test/random_test.cc +test_test_tools_fail_SOURCES = test/test_tools_fail.cc +test_test_tools_pass_SOURCES = test/test_tools_pass.cc +test_time_measure_test_SOURCES = test/time_measure_test.cc +test_unionfind_test_SOURCES = test/unionfind_test.cc +DOC_EPS_IMAGES18 = \ + grid_graph.eps \ + nodeshape_0.eps \ + nodeshape_1.eps \ + nodeshape_2.eps \ + nodeshape_3.eps \ + nodeshape_4.eps + +DOC_EPS_IMAGES27 = \ + bipartite_matching.eps \ + bipartite_partitions.eps \ + connected_components.eps \ + edge_biconnected_components.eps \ + matching.eps \ + node_biconnected_components.eps \ + planar.eps \ + strongly_connected_components.eps + +DOC_EPS_IMAGES = \ + $(DOC_EPS_IMAGES18) \ + $(DOC_EPS_IMAGES27) + +DOC_PNG_IMAGES = \ + $(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png) + +GS_COMMAND = gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 +tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc +tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc +tools_lgf_gen_SOURCES = tools/lgf-gen.cc +DIST_SUBDIRS = demo +MRPROPERFILES = \ + aclocal.m4 \ + config.h.in \ + config.h.in~ \ + configure \ + Makefile.in \ + build-aux/config.guess \ + build-aux/config.sub \ + build-aux/depcomp \ + build-aux/install-sh \ + build-aux/ltmain.sh \ + build-aux/missing \ + doc/doxygen.log + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/lemon/Makefile.am $(srcdir)/test/Makefile.am $(srcdir)/doc/Makefile.am $(srcdir)/tools/Makefile.am $(srcdir)/scripts/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +lemon/config.h: lemon/stamp-h2 + @if test ! -f $@; then \ + rm -f lemon/stamp-h2; \ + $(MAKE) $(AM_MAKEFLAGS) lemon/stamp-h2; \ + else :; fi + +lemon/stamp-h2: $(top_srcdir)/lemon/config.h.in $(top_builddir)/config.status + @rm -f lemon/stamp-h2 + cd $(top_builddir) && $(SHELL) ./config.status lemon/config.h + +distclean-hdr: + -rm -f config.h stamp-h1 lemon/config.h lemon/stamp-h2 +cmake/version.cmake: $(top_builddir)/config.status $(top_srcdir)/cmake/version.cmake.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +doc/Doxyfile: $(top_builddir)/config.status $(top_srcdir)/doc/Doxyfile.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +doc/mainpage.dox: $(top_builddir)/config.status $(top_srcdir)/doc/mainpage.dox.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +lemon/lemon.pc: $(top_builddir)/config.status $(top_srcdir)/lemon/lemon.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +lemon/$(am__dirstamp): + @$(MKDIR_P) lemon + @: > lemon/$(am__dirstamp) +lemon/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) lemon/$(DEPDIR) + @: > lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-arg_parser.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-base.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-color.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-lp_base.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-lp_skeleton.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-random.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/bits/$(am__dirstamp): + @$(MKDIR_P) lemon/bits + @: > lemon/bits/$(am__dirstamp) +lemon/bits/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) lemon/bits/$(DEPDIR) + @: > lemon/bits/$(DEPDIR)/$(am__dirstamp) +lemon/bits/lemon_libemon_la-windows.lo: lemon/bits/$(am__dirstamp) \ + lemon/bits/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-glpk.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-cplex.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-soplex.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-clp.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/lemon_libemon_la-cbc.lo: lemon/$(am__dirstamp) \ + lemon/$(DEPDIR)/$(am__dirstamp) +lemon/libemon.la: $(lemon_libemon_la_OBJECTS) $(lemon_libemon_la_DEPENDENCIES) lemon/$(am__dirstamp) + $(lemon_libemon_la_LINK) -rpath $(libdir) $(lemon_libemon_la_OBJECTS) $(lemon_libemon_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +test/$(am__dirstamp): + @$(MKDIR_P) test + @: > test/$(am__dirstamp) +test/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) test/$(DEPDIR) + @: > test/$(DEPDIR)/$(am__dirstamp) +test/adaptors_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/adaptors_test$(EXEEXT): $(test_adaptors_test_OBJECTS) $(test_adaptors_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/adaptors_test$(EXEEXT) + $(CXXLINK) $(test_adaptors_test_OBJECTS) $(test_adaptors_test_LDADD) $(LIBS) +test/bellman_ford_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/bellman_ford_test$(EXEEXT): $(test_bellman_ford_test_OBJECTS) $(test_bellman_ford_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/bellman_ford_test$(EXEEXT) + $(CXXLINK) $(test_bellman_ford_test_OBJECTS) $(test_bellman_ford_test_LDADD) $(LIBS) +test/bfs_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/bfs_test$(EXEEXT): $(test_bfs_test_OBJECTS) $(test_bfs_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/bfs_test$(EXEEXT) + $(CXXLINK) $(test_bfs_test_OBJECTS) $(test_bfs_test_LDADD) $(LIBS) +test/circulation_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/circulation_test$(EXEEXT): $(test_circulation_test_OBJECTS) $(test_circulation_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/circulation_test$(EXEEXT) + $(CXXLINK) $(test_circulation_test_OBJECTS) $(test_circulation_test_LDADD) $(LIBS) +test/connectivity_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/connectivity_test$(EXEEXT): $(test_connectivity_test_OBJECTS) $(test_connectivity_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/connectivity_test$(EXEEXT) + $(CXXLINK) $(test_connectivity_test_OBJECTS) $(test_connectivity_test_LDADD) $(LIBS) +test/counter_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/counter_test$(EXEEXT): $(test_counter_test_OBJECTS) $(test_counter_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/counter_test$(EXEEXT) + $(CXXLINK) $(test_counter_test_OBJECTS) $(test_counter_test_LDADD) $(LIBS) +test/dfs_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/dfs_test$(EXEEXT): $(test_dfs_test_OBJECTS) $(test_dfs_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/dfs_test$(EXEEXT) + $(CXXLINK) $(test_dfs_test_OBJECTS) $(test_dfs_test_LDADD) $(LIBS) +test/digraph_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/digraph_test$(EXEEXT): $(test_digraph_test_OBJECTS) $(test_digraph_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/digraph_test$(EXEEXT) + $(CXXLINK) $(test_digraph_test_OBJECTS) $(test_digraph_test_LDADD) $(LIBS) +test/dijkstra_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/dijkstra_test$(EXEEXT): $(test_dijkstra_test_OBJECTS) $(test_dijkstra_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/dijkstra_test$(EXEEXT) + $(CXXLINK) $(test_dijkstra_test_OBJECTS) $(test_dijkstra_test_LDADD) $(LIBS) +test/dim_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/dim_test$(EXEEXT): $(test_dim_test_OBJECTS) $(test_dim_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/dim_test$(EXEEXT) + $(CXXLINK) $(test_dim_test_OBJECTS) $(test_dim_test_LDADD) $(LIBS) +test/edge_set_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/edge_set_test$(EXEEXT): $(test_edge_set_test_OBJECTS) $(test_edge_set_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/edge_set_test$(EXEEXT) + $(CXXLINK) $(test_edge_set_test_OBJECTS) $(test_edge_set_test_LDADD) $(LIBS) +test/error_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/error_test$(EXEEXT): $(test_error_test_OBJECTS) $(test_error_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/error_test$(EXEEXT) + $(CXXLINK) $(test_error_test_OBJECTS) $(test_error_test_LDADD) $(LIBS) +test/euler_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/euler_test$(EXEEXT): $(test_euler_test_OBJECTS) $(test_euler_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/euler_test$(EXEEXT) + $(CXXLINK) $(test_euler_test_OBJECTS) $(test_euler_test_LDADD) $(LIBS) +test/fractional_matching_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/fractional_matching_test$(EXEEXT): $(test_fractional_matching_test_OBJECTS) $(test_fractional_matching_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/fractional_matching_test$(EXEEXT) + $(CXXLINK) $(test_fractional_matching_test_OBJECTS) $(test_fractional_matching_test_LDADD) $(LIBS) +test/gomory_hu_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/gomory_hu_test$(EXEEXT): $(test_gomory_hu_test_OBJECTS) $(test_gomory_hu_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/gomory_hu_test$(EXEEXT) + $(CXXLINK) $(test_gomory_hu_test_OBJECTS) $(test_gomory_hu_test_LDADD) $(LIBS) +test/graph_copy_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/graph_copy_test$(EXEEXT): $(test_graph_copy_test_OBJECTS) $(test_graph_copy_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/graph_copy_test$(EXEEXT) + $(CXXLINK) $(test_graph_copy_test_OBJECTS) $(test_graph_copy_test_LDADD) $(LIBS) +test/graph_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/graph_test$(EXEEXT): $(test_graph_test_OBJECTS) $(test_graph_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/graph_test$(EXEEXT) + $(CXXLINK) $(test_graph_test_OBJECTS) $(test_graph_test_LDADD) $(LIBS) +test/graph_utils_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/graph_utils_test$(EXEEXT): $(test_graph_utils_test_OBJECTS) $(test_graph_utils_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/graph_utils_test$(EXEEXT) + $(CXXLINK) $(test_graph_utils_test_OBJECTS) $(test_graph_utils_test_LDADD) $(LIBS) +test/hao_orlin_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/hao_orlin_test$(EXEEXT): $(test_hao_orlin_test_OBJECTS) $(test_hao_orlin_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/hao_orlin_test$(EXEEXT) + $(CXXLINK) $(test_hao_orlin_test_OBJECTS) $(test_hao_orlin_test_LDADD) $(LIBS) +test/heap_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/heap_test$(EXEEXT): $(test_heap_test_OBJECTS) $(test_heap_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/heap_test$(EXEEXT) + $(CXXLINK) $(test_heap_test_OBJECTS) $(test_heap_test_LDADD) $(LIBS) +test/kruskal_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/kruskal_test$(EXEEXT): $(test_kruskal_test_OBJECTS) $(test_kruskal_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/kruskal_test$(EXEEXT) + $(CXXLINK) $(test_kruskal_test_OBJECTS) $(test_kruskal_test_LDADD) $(LIBS) +test/lgf_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/lgf_test$(EXEEXT): $(test_lgf_test_OBJECTS) $(test_lgf_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/lgf_test$(EXEEXT) + $(CXXLINK) $(test_lgf_test_OBJECTS) $(test_lgf_test_LDADD) $(LIBS) +test/lp_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/lp_test$(EXEEXT): $(test_lp_test_OBJECTS) $(test_lp_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/lp_test$(EXEEXT) + $(CXXLINK) $(test_lp_test_OBJECTS) $(test_lp_test_LDADD) $(LIBS) +test/maps_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/maps_test$(EXEEXT): $(test_maps_test_OBJECTS) $(test_maps_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/maps_test$(EXEEXT) + $(CXXLINK) $(test_maps_test_OBJECTS) $(test_maps_test_LDADD) $(LIBS) +test/matching_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/matching_test$(EXEEXT): $(test_matching_test_OBJECTS) $(test_matching_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/matching_test$(EXEEXT) + $(CXXLINK) $(test_matching_test_OBJECTS) $(test_matching_test_LDADD) $(LIBS) +test/min_cost_arborescence_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/min_cost_arborescence_test$(EXEEXT): $(test_min_cost_arborescence_test_OBJECTS) $(test_min_cost_arborescence_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/min_cost_arborescence_test$(EXEEXT) + $(CXXLINK) $(test_min_cost_arborescence_test_OBJECTS) $(test_min_cost_arborescence_test_LDADD) $(LIBS) +test/min_cost_flow_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/min_cost_flow_test$(EXEEXT): $(test_min_cost_flow_test_OBJECTS) $(test_min_cost_flow_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/min_cost_flow_test$(EXEEXT) + $(CXXLINK) $(test_min_cost_flow_test_OBJECTS) $(test_min_cost_flow_test_LDADD) $(LIBS) +test/min_mean_cycle_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/min_mean_cycle_test$(EXEEXT): $(test_min_mean_cycle_test_OBJECTS) $(test_min_mean_cycle_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/min_mean_cycle_test$(EXEEXT) + $(CXXLINK) $(test_min_mean_cycle_test_OBJECTS) $(test_min_mean_cycle_test_LDADD) $(LIBS) +test/mip_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/mip_test$(EXEEXT): $(test_mip_test_OBJECTS) $(test_mip_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/mip_test$(EXEEXT) + $(CXXLINK) $(test_mip_test_OBJECTS) $(test_mip_test_LDADD) $(LIBS) +test/path_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/path_test$(EXEEXT): $(test_path_test_OBJECTS) $(test_path_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/path_test$(EXEEXT) + $(CXXLINK) $(test_path_test_OBJECTS) $(test_path_test_LDADD) $(LIBS) +test/planarity_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/planarity_test$(EXEEXT): $(test_planarity_test_OBJECTS) $(test_planarity_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/planarity_test$(EXEEXT) + $(CXXLINK) $(test_planarity_test_OBJECTS) $(test_planarity_test_LDADD) $(LIBS) +test/preflow_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/preflow_test$(EXEEXT): $(test_preflow_test_OBJECTS) $(test_preflow_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/preflow_test$(EXEEXT) + $(CXXLINK) $(test_preflow_test_OBJECTS) $(test_preflow_test_LDADD) $(LIBS) +test/radix_sort_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/radix_sort_test$(EXEEXT): $(test_radix_sort_test_OBJECTS) $(test_radix_sort_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/radix_sort_test$(EXEEXT) + $(CXXLINK) $(test_radix_sort_test_OBJECTS) $(test_radix_sort_test_LDADD) $(LIBS) +test/random_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/random_test$(EXEEXT): $(test_random_test_OBJECTS) $(test_random_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/random_test$(EXEEXT) + $(CXXLINK) $(test_random_test_OBJECTS) $(test_random_test_LDADD) $(LIBS) +test/suurballe_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/suurballe_test$(EXEEXT): $(test_suurballe_test_OBJECTS) $(test_suurballe_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/suurballe_test$(EXEEXT) + $(CXXLINK) $(test_suurballe_test_OBJECTS) $(test_suurballe_test_LDADD) $(LIBS) +test/test_tools_fail.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/test_tools_fail$(EXEEXT): $(test_test_tools_fail_OBJECTS) $(test_test_tools_fail_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/test_tools_fail$(EXEEXT) + $(CXXLINK) $(test_test_tools_fail_OBJECTS) $(test_test_tools_fail_LDADD) $(LIBS) +test/test_tools_pass.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/test_tools_pass$(EXEEXT): $(test_test_tools_pass_OBJECTS) $(test_test_tools_pass_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/test_tools_pass$(EXEEXT) + $(CXXLINK) $(test_test_tools_pass_OBJECTS) $(test_test_tools_pass_LDADD) $(LIBS) +test/time_measure_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/time_measure_test$(EXEEXT): $(test_time_measure_test_OBJECTS) $(test_time_measure_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/time_measure_test$(EXEEXT) + $(CXXLINK) $(test_time_measure_test_OBJECTS) $(test_time_measure_test_LDADD) $(LIBS) +test/unionfind_test.$(OBJEXT): test/$(am__dirstamp) \ + test/$(DEPDIR)/$(am__dirstamp) +test/unionfind_test$(EXEEXT): $(test_unionfind_test_OBJECTS) $(test_unionfind_test_DEPENDENCIES) test/$(am__dirstamp) + @rm -f test/unionfind_test$(EXEEXT) + $(CXXLINK) $(test_unionfind_test_OBJECTS) $(test_unionfind_test_LDADD) $(LIBS) +tools/$(am__dirstamp): + @$(MKDIR_P) tools + @: > tools/$(am__dirstamp) +tools/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tools/$(DEPDIR) + @: > tools/$(DEPDIR)/$(am__dirstamp) +tools/dimacs-solver.$(OBJEXT): tools/$(am__dirstamp) \ + tools/$(DEPDIR)/$(am__dirstamp) +tools/dimacs-solver$(EXEEXT): $(tools_dimacs_solver_OBJECTS) $(tools_dimacs_solver_DEPENDENCIES) tools/$(am__dirstamp) + @rm -f tools/dimacs-solver$(EXEEXT) + $(CXXLINK) $(tools_dimacs_solver_OBJECTS) $(tools_dimacs_solver_LDADD) $(LIBS) +tools/dimacs-to-lgf.$(OBJEXT): tools/$(am__dirstamp) \ + tools/$(DEPDIR)/$(am__dirstamp) +tools/dimacs-to-lgf$(EXEEXT): $(tools_dimacs_to_lgf_OBJECTS) $(tools_dimacs_to_lgf_DEPENDENCIES) tools/$(am__dirstamp) + @rm -f tools/dimacs-to-lgf$(EXEEXT) + $(CXXLINK) $(tools_dimacs_to_lgf_OBJECTS) $(tools_dimacs_to_lgf_LDADD) $(LIBS) +tools/lgf-gen.$(OBJEXT): tools/$(am__dirstamp) \ + tools/$(DEPDIR)/$(am__dirstamp) +tools/lgf-gen$(EXEEXT): $(tools_lgf_gen_OBJECTS) $(tools_lgf_gen_DEPENDENCIES) tools/$(am__dirstamp) + @rm -f tools/lgf-gen$(EXEEXT) + $(CXXLINK) $(tools_lgf_gen_OBJECTS) $(tools_lgf_gen_LDADD) $(LIBS) +install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-dist_binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f lemon/bits/lemon_libemon_la-windows.$(OBJEXT) + -rm -f lemon/bits/lemon_libemon_la-windows.lo + -rm -f lemon/lemon_libemon_la-arg_parser.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-arg_parser.lo + -rm -f lemon/lemon_libemon_la-base.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-base.lo + -rm -f lemon/lemon_libemon_la-cbc.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-cbc.lo + -rm -f lemon/lemon_libemon_la-clp.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-clp.lo + -rm -f lemon/lemon_libemon_la-color.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-color.lo + -rm -f lemon/lemon_libemon_la-cplex.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-cplex.lo + -rm -f lemon/lemon_libemon_la-glpk.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-glpk.lo + -rm -f lemon/lemon_libemon_la-lp_base.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-lp_base.lo + -rm -f lemon/lemon_libemon_la-lp_skeleton.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-lp_skeleton.lo + -rm -f lemon/lemon_libemon_la-random.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-random.lo + -rm -f lemon/lemon_libemon_la-soplex.$(OBJEXT) + -rm -f lemon/lemon_libemon_la-soplex.lo + -rm -f test/adaptors_test.$(OBJEXT) + -rm -f test/bellman_ford_test.$(OBJEXT) + -rm -f test/bfs_test.$(OBJEXT) + -rm -f test/circulation_test.$(OBJEXT) + -rm -f test/connectivity_test.$(OBJEXT) + -rm -f test/counter_test.$(OBJEXT) + -rm -f test/dfs_test.$(OBJEXT) + -rm -f test/digraph_test.$(OBJEXT) + -rm -f test/dijkstra_test.$(OBJEXT) + -rm -f test/dim_test.$(OBJEXT) + -rm -f test/edge_set_test.$(OBJEXT) + -rm -f test/error_test.$(OBJEXT) + -rm -f test/euler_test.$(OBJEXT) + -rm -f test/fractional_matching_test.$(OBJEXT) + -rm -f test/gomory_hu_test.$(OBJEXT) + -rm -f test/graph_copy_test.$(OBJEXT) + -rm -f test/graph_test.$(OBJEXT) + -rm -f test/graph_utils_test.$(OBJEXT) + -rm -f test/hao_orlin_test.$(OBJEXT) + -rm -f test/heap_test.$(OBJEXT) + -rm -f test/kruskal_test.$(OBJEXT) + -rm -f test/lgf_test.$(OBJEXT) + -rm -f test/lp_test.$(OBJEXT) + -rm -f test/maps_test.$(OBJEXT) + -rm -f test/matching_test.$(OBJEXT) + -rm -f test/min_cost_arborescence_test.$(OBJEXT) + -rm -f test/min_cost_flow_test.$(OBJEXT) + -rm -f test/min_mean_cycle_test.$(OBJEXT) + -rm -f test/mip_test.$(OBJEXT) + -rm -f test/path_test.$(OBJEXT) + -rm -f test/planarity_test.$(OBJEXT) + -rm -f test/preflow_test.$(OBJEXT) + -rm -f test/radix_sort_test.$(OBJEXT) + -rm -f test/random_test.$(OBJEXT) + -rm -f test/suurballe_test.$(OBJEXT) + -rm -f test/test_tools_fail.$(OBJEXT) + -rm -f test/test_tools_pass.$(OBJEXT) + -rm -f test/time_measure_test.$(OBJEXT) + -rm -f test/unionfind_test.$(OBJEXT) + -rm -f tools/dimacs-solver.$(OBJEXT) + -rm -f tools/dimacs-to-lgf.$(OBJEXT) + -rm -f tools/lgf-gen.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-base.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-cbc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-clp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-color.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-cplex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-glpk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-random.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/$(DEPDIR)/lemon_libemon_la-soplex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/adaptors_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/bellman_ford_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/bfs_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/circulation_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/connectivity_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/counter_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/dfs_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/digraph_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/dijkstra_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/dim_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/edge_set_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/error_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/euler_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/fractional_matching_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gomory_hu_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/graph_copy_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/graph_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/graph_utils_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/hao_orlin_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/heap_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/kruskal_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/lgf_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/lp_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/maps_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/matching_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/min_cost_arborescence_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/min_cost_flow_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/min_mean_cycle_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/mip_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/path_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/planarity_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/preflow_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/radix_sort_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/random_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/suurballe_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_tools_fail.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_tools_pass.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/time_measure_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/unionfind_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/dimacs-solver.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/dimacs-to-lgf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/lgf-gen.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +lemon/lemon_libemon_la-arg_parser.lo: lemon/arg_parser.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-arg_parser.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Tpo -c -o lemon/lemon_libemon_la-arg_parser.lo `test -f 'lemon/arg_parser.cc' || echo '$(srcdir)/'`lemon/arg_parser.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Tpo lemon/$(DEPDIR)/lemon_libemon_la-arg_parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/arg_parser.cc' object='lemon/lemon_libemon_la-arg_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-arg_parser.lo `test -f 'lemon/arg_parser.cc' || echo '$(srcdir)/'`lemon/arg_parser.cc + +lemon/lemon_libemon_la-base.lo: lemon/base.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-base.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-base.Tpo -c -o lemon/lemon_libemon_la-base.lo `test -f 'lemon/base.cc' || echo '$(srcdir)/'`lemon/base.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-base.Tpo lemon/$(DEPDIR)/lemon_libemon_la-base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/base.cc' object='lemon/lemon_libemon_la-base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-base.lo `test -f 'lemon/base.cc' || echo '$(srcdir)/'`lemon/base.cc + +lemon/lemon_libemon_la-color.lo: lemon/color.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-color.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-color.Tpo -c -o lemon/lemon_libemon_la-color.lo `test -f 'lemon/color.cc' || echo '$(srcdir)/'`lemon/color.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-color.Tpo lemon/$(DEPDIR)/lemon_libemon_la-color.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/color.cc' object='lemon/lemon_libemon_la-color.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-color.lo `test -f 'lemon/color.cc' || echo '$(srcdir)/'`lemon/color.cc + +lemon/lemon_libemon_la-lp_base.lo: lemon/lp_base.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-lp_base.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Tpo -c -o lemon/lemon_libemon_la-lp_base.lo `test -f 'lemon/lp_base.cc' || echo '$(srcdir)/'`lemon/lp_base.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Tpo lemon/$(DEPDIR)/lemon_libemon_la-lp_base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/lp_base.cc' object='lemon/lemon_libemon_la-lp_base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-lp_base.lo `test -f 'lemon/lp_base.cc' || echo '$(srcdir)/'`lemon/lp_base.cc + +lemon/lemon_libemon_la-lp_skeleton.lo: lemon/lp_skeleton.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-lp_skeleton.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Tpo -c -o lemon/lemon_libemon_la-lp_skeleton.lo `test -f 'lemon/lp_skeleton.cc' || echo '$(srcdir)/'`lemon/lp_skeleton.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Tpo lemon/$(DEPDIR)/lemon_libemon_la-lp_skeleton.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/lp_skeleton.cc' object='lemon/lemon_libemon_la-lp_skeleton.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-lp_skeleton.lo `test -f 'lemon/lp_skeleton.cc' || echo '$(srcdir)/'`lemon/lp_skeleton.cc + +lemon/lemon_libemon_la-random.lo: lemon/random.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-random.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-random.Tpo -c -o lemon/lemon_libemon_la-random.lo `test -f 'lemon/random.cc' || echo '$(srcdir)/'`lemon/random.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-random.Tpo lemon/$(DEPDIR)/lemon_libemon_la-random.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/random.cc' object='lemon/lemon_libemon_la-random.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-random.lo `test -f 'lemon/random.cc' || echo '$(srcdir)/'`lemon/random.cc + +lemon/bits/lemon_libemon_la-windows.lo: lemon/bits/windows.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/bits/lemon_libemon_la-windows.lo -MD -MP -MF lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Tpo -c -o lemon/bits/lemon_libemon_la-windows.lo `test -f 'lemon/bits/windows.cc' || echo '$(srcdir)/'`lemon/bits/windows.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Tpo lemon/bits/$(DEPDIR)/lemon_libemon_la-windows.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/bits/windows.cc' object='lemon/bits/lemon_libemon_la-windows.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/bits/lemon_libemon_la-windows.lo `test -f 'lemon/bits/windows.cc' || echo '$(srcdir)/'`lemon/bits/windows.cc + +lemon/lemon_libemon_la-glpk.lo: lemon/glpk.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-glpk.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-glpk.Tpo -c -o lemon/lemon_libemon_la-glpk.lo `test -f 'lemon/glpk.cc' || echo '$(srcdir)/'`lemon/glpk.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-glpk.Tpo lemon/$(DEPDIR)/lemon_libemon_la-glpk.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/glpk.cc' object='lemon/lemon_libemon_la-glpk.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-glpk.lo `test -f 'lemon/glpk.cc' || echo '$(srcdir)/'`lemon/glpk.cc + +lemon/lemon_libemon_la-cplex.lo: lemon/cplex.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-cplex.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-cplex.Tpo -c -o lemon/lemon_libemon_la-cplex.lo `test -f 'lemon/cplex.cc' || echo '$(srcdir)/'`lemon/cplex.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-cplex.Tpo lemon/$(DEPDIR)/lemon_libemon_la-cplex.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/cplex.cc' object='lemon/lemon_libemon_la-cplex.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-cplex.lo `test -f 'lemon/cplex.cc' || echo '$(srcdir)/'`lemon/cplex.cc + +lemon/lemon_libemon_la-soplex.lo: lemon/soplex.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-soplex.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-soplex.Tpo -c -o lemon/lemon_libemon_la-soplex.lo `test -f 'lemon/soplex.cc' || echo '$(srcdir)/'`lemon/soplex.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-soplex.Tpo lemon/$(DEPDIR)/lemon_libemon_la-soplex.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/soplex.cc' object='lemon/lemon_libemon_la-soplex.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-soplex.lo `test -f 'lemon/soplex.cc' || echo '$(srcdir)/'`lemon/soplex.cc + +lemon/lemon_libemon_la-clp.lo: lemon/clp.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-clp.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-clp.Tpo -c -o lemon/lemon_libemon_la-clp.lo `test -f 'lemon/clp.cc' || echo '$(srcdir)/'`lemon/clp.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-clp.Tpo lemon/$(DEPDIR)/lemon_libemon_la-clp.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/clp.cc' object='lemon/lemon_libemon_la-clp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-clp.lo `test -f 'lemon/clp.cc' || echo '$(srcdir)/'`lemon/clp.cc + +lemon/lemon_libemon_la-cbc.lo: lemon/cbc.cc +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -MT lemon/lemon_libemon_la-cbc.lo -MD -MP -MF lemon/$(DEPDIR)/lemon_libemon_la-cbc.Tpo -c -o lemon/lemon_libemon_la-cbc.lo `test -f 'lemon/cbc.cc' || echo '$(srcdir)/'`lemon/cbc.cc +@am__fastdepCXX_TRUE@ $(am__mv) lemon/$(DEPDIR)/lemon_libemon_la-cbc.Tpo lemon/$(DEPDIR)/lemon_libemon_la-cbc.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='lemon/cbc.cc' object='lemon/lemon_libemon_la-cbc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lemon_libemon_la_CXXFLAGS) $(CXXFLAGS) -c -o lemon/lemon_libemon_la-cbc.lo `test -f 'lemon/cbc.cc' || echo '$(srcdir)/'`lemon/cbc.cc + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf lemon/.libs lemon/_libs + -rm -rf lemon/bits/.libs lemon/bits/_libs + -rm -rf test/.libs test/_libs + -rm -rf tools/.libs tools/_libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files +install-bitsHEADERS: $(bits_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(bitsdir)" || $(MKDIR_P) "$(DESTDIR)$(bitsdir)" + @list='$(bits_HEADERS)'; test -n "$(bitsdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(bitsdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(bitsdir)" || exit $$?; \ + done + +uninstall-bitsHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(bits_HEADERS)'; test -n "$(bitsdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bitsdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bitsdir)" && rm -f $$files +install-conceptHEADERS: $(concept_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(conceptdir)" || $(MKDIR_P) "$(DESTDIR)$(conceptdir)" + @list='$(concept_HEADERS)'; test -n "$(conceptdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(conceptdir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(conceptdir)" || exit $$?; \ + done + +uninstall-conceptHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(concept_HEADERS)'; test -n "$(conceptdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(conceptdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(conceptdir)" && rm -f $$files +install-lemonHEADERS: $(lemon_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(lemondir)" || $(MKDIR_P) "$(DESTDIR)$(lemondir)" + @list='$(lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(lemondir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(lemondir)" || exit $$?; \ + done + +uninstall-lemonHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(lemondir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(lemondir)" && rm -f $$files +install-nodist_lemonHEADERS: $(nodist_lemon_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(lemondir)" || $(MKDIR_P) "$(DESTDIR)$(lemondir)" + @list='$(nodist_lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(lemondir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(lemondir)" || exit $$?; \ + done + +uninstall-nodist_lemonHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_lemon_HEADERS)'; test -n "$(lemondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(lemondir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(lemondir)" && rm -f $$files + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \ + $(HEADERS) config.h +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(bitsdir)" "$(DESTDIR)$(conceptdir)" "$(DESTDIR)$(lemondir)" "$(DESTDIR)$(lemondir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f lemon/$(DEPDIR)/$(am__dirstamp) + -rm -f lemon/$(am__dirstamp) + -rm -f lemon/bits/$(DEPDIR)/$(am__dirstamp) + -rm -f lemon/bits/$(am__dirstamp) + -rm -f test/$(DEPDIR)/$(am__dirstamp) + -rm -f test/$(am__dirstamp) + -rm -f tools/$(DEPDIR)/$(am__dirstamp) + -rm -f tools/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf lemon/$(DEPDIR) lemon/bits/$(DEPDIR) test/$(DEPDIR) tools/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: html-local + +info: info-recursive + +info-am: + +install-data-am: install-bitsHEADERS install-conceptHEADERS \ + install-lemonHEADERS install-nodist_lemonHEADERS \ + install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-dist_binSCRIPTS \ + install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: install-html-local + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf lemon/$(DEPDIR) lemon/bits/$(DEPDIR) test/$(DEPDIR) tools/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-bitsHEADERS \ + uninstall-conceptHEADERS uninstall-dist_binSCRIPTS \ + uninstall-lemonHEADERS uninstall-libLTLIBRARIES \ + uninstall-local uninstall-nodist_lemonHEADERS \ + uninstall-pkgconfigDATA + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check-am \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-TESTS check-am clean \ + clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-local \ + clean-noinstPROGRAMS ctags ctags-recursive dist dist-all \ + dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am html-local info info-am install install-am \ + install-binPROGRAMS install-bitsHEADERS install-conceptHEADERS \ + install-data install-data-am install-dist_binSCRIPTS \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-html-local install-info \ + install-info-am install-lemonHEADERS install-libLTLIBRARIES \ + install-man install-nodist_lemonHEADERS install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-bitsHEADERS uninstall-conceptHEADERS \ + uninstall-dist_binSCRIPTS uninstall-lemonHEADERS \ + uninstall-libLTLIBRARIES uninstall-local \ + uninstall-nodist_lemonHEADERS uninstall-pkgconfigDATA + + +doc/html: + $(MAKE) $(AM_MAKEFLAGS) html + +$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps + -mkdir doc/gen-images + if test ${gs_found} = yes; then \ + $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \ + else \ + echo; \ + echo "Ghostscript not found."; \ + echo; \ + exit 1; \ + fi + +$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps + -mkdir doc/gen-images + if test ${gs_found} = yes; then \ + $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \ + else \ + echo; \ + echo "Ghostscript not found."; \ + echo; \ + exit 1; \ + fi + +references.dox: doc/references.bib + if test ${python_found} = yes; then \ + cd doc; \ + python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \ + cd ..; \ + else \ + echo; \ + echo "Python not found."; \ + echo; \ + exit 1; \ + fi + +html-local: $(DOC_PNG_IMAGES) references.dox + if test ${doxygen_found} = yes; then \ + cd doc; \ + doxygen Doxyfile; \ + cd ..; \ + else \ + echo; \ + echo "Doxygen not found."; \ + echo; \ + exit 1; \ + fi + +clean-local: + -rm -rf doc/html + -rm -f doc/doxygen.log + -rm -f $(DOC_PNG_IMAGES) + -rm -rf doc/gen-images + +update-external-tags: + wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \ + mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \ + rm doc/libstdc++.tag.tmp + +install-html-local: doc/html + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(htmldir)/html + for p in doc/html/*.{html,css,png,map,gif,tag} ; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \ + done + +uninstall-local: + @$(NORMAL_UNINSTALL) + for p in doc/html/*.{html,css,png,map,gif,tag} ; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \ + rm -f $(DESTDIR)$(htmldir)/html/$$f; \ + done + +.PHONY: update-external-tags + +demo: + $(MAKE) $(AM_MAKEFLAGS) -C demo + +mrproper: + $(MAKE) $(AM_MAKEFLAGS) maintainer-clean + -rm -f $(MRPROPERFILES) + +dist-bz2: dist + zcat $(PACKAGE)-$(VERSION).tar.gz | \ + bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2 + +distcheck-bz2: distcheck + zcat $(PACKAGE)-$(VERSION).tar.gz | \ + bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2 + +.PHONY: demo mrproper dist-bz2 distcheck-bz2 + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lemon/NEWS b/lemon/NEWS new file mode 100644 index 0000000..aaf2474 --- /dev/null +++ b/lemon/NEWS @@ -0,0 +1,260 @@ +2011-11-09 Version 1.2.3 released + + Bugfix release. + + #428: Add missing lemon/lemon.pc.cmake to the release tarball + #429: Fix VS warnings + #430: Fix LpBase::Constr two-side limit bug + +2011-08-08 Version 1.2.2 released + + Bugfix release. + + #392: Bug fix in Dfs::start(s,t) + #414: Fix wrong initialization in Preflow + #404: Update Doxygen configuration + #416: Support tests with valgrind + #418: Better Win CodeBlock/MinGW support + #419: Backport build environment improvements from the main branch + - Build of mip_test and lp_test precede the running of the tests + - Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin + - Do not look for COIN_VOL libraries + #382: Allow lgf file without Arc maps + #417: Bug fix in CostScaling + +2010-10-21 Version 1.2.1 released + + Bugfix release. + + #366: Fix Pred[Matrix]MapPath::empty() + #371: Bug fix in (di)graphCopy() + The target graph is cleared before adding nodes and arcs/edges. + + #364: Add missing UndirectedTags + #368: Fix the usage of std::numeric_limits<>::min() in Network Simplex + #372: Fix a critical bug in preflow + +2010-03-19 Version 1.2 released + + This is major feature release + + * New algorithms + * Bellman-Ford algorithm (#51) + * Minimum mean cycle algorithms (#179) + * Karp, Hartman-Orlin and Howard algorithms + * New minimum cost flow algorithms (#180) + * Cost Scaling algorithms + * Capacity Scaling algorithm + * Cycle-Canceling algorithms + * Planarity related algorithms (#62) + * Planarity checking algorithm + * Planar embedding algorithm + * Schnyder's planar drawing algorithm + * Coloring planar graphs with five or six colors + * Fractional matching algorithms (#314) + * New data structures + * StaticDigraph structure (#68) + * Several new priority queue structures (#50, #301) + * Fibonacci, Radix, Bucket, Pairing, Binomial + D-ary and fourary heaps (#301) + * Iterable map structures (#73) + * Other new tools and functionality + * Map utility functions (#320) + * Reserve functions are added to ListGraph and SmartGraph (#311) + * A resize() function is added to HypercubeGraph (#311) + * A count() function is added to CrossRefMap (#302) + * Support for multiple targets in Suurballe using fullInit() (#181) + * Traits class and named parameters for Suurballe (#323) + * Separate reset() and resetParams() functions in NetworkSimplex + to handle graph changes (#327) + * tolerance() functions are added to HaoOrlin (#306) + * Implementation improvements + * Improvements in weighted matching algorithms (#314) + * Jumpstart initialization + * ArcIt iteration is based on out-arc lists instead of in-arc lists + in ListDigraph (#311) + * Faster add row operation in CbcMip (#203) + * Better implementation for split() in ListDigraph (#311) + * ArgParser can also throw exception instead of exit(1) (#332) + * Miscellaneous + * A simple interactive bootstrap script + * Doc improvements (#62,#180,#299,#302,#303,#304,#307,#311,#331,#315, + #316,#319) + * BibTeX references in the doc (#184) + * Optionally use valgrind when running tests + * Also check ReferenceMapTag in concept checks (#312) + * dimacs-solver uses long long type by default. + * Several bugfixes (compared to release 1.1): + #295: Suppress MSVC warnings using pragmas + ----: Various CMAKE related improvements + * Remove duplications from doc/CMakeLists.txt + * Rename documentation install folder from 'docs' to 'html' + * Add tools/CMakeLists.txt to the tarball + * Generate and install LEMONConfig.cmake + * Change the label of the html project in Visual Studio + * Fix the check for the 'long long' type + * Put the version string into config.h + * Minor CMake improvements + * Set the version to 'hg-tip' if everything fails + #311: Add missing 'explicit' keywords + #302: Fix the implementation and doc of CrossRefMap + #308: Remove duplicate list_graph.h entry from source list + #307: Bugfix in Preflow and Circulation + #305: Bugfix and extension in the rename script + #312: Also check ReferenceMapTag in concept checks + #250: Bugfix in pathSource() and pathTarget() + #321: Use pathCopy(from,to) instead of copyPath(to,from) + #322: Distribure LEMONConfig.cmake.in + #330: Bug fix in map_extender.h + #336: Fix the date field comment of graphToEps() output + #323: Bug fix in Suurballe + #335: Fix clear() function in ExtendFindEnum + #337: Use void* as the LPX object pointer + #317: Fix (and improve) error message in mip_test.cc + Remove unnecessary OsiCbc dependency + #356: Allow multiple executions of weighted matching algorithms (#356) + +2009-05-13 Version 1.1 released + + This is the second stable release of the 1.x series. It + features a better coverage of the tools available in the 0.x + series, a thoroughly reworked LP/MIP interface plus various + improvements in the existing tools. + + * Much improved M$ Windows support + * Various improvements in the CMAKE build system + * Compilation warnings are fixed/suppressed + * Support IBM xlC compiler + * New algorithms + * Connectivity related algorithms (#61) + * Euler walks (#65) + * Preflow push-relabel max. flow algorithm (#176) + * Circulation algorithm (push-relabel based) (#175) + * Suurballe algorithm (#47) + * Gomory-Hu algorithm (#66) + * Hao-Orlin algorithm (#58) + * Edmond's maximum cardinality and weighted matching algorithms + in general graphs (#48,#265) + * Minimum cost arborescence/branching (#60) + * Network Simplex min. cost flow algorithm (#234) + * New data structures + * Full graph structure (#57) + * Grid graph structure (#57) + * Hypercube graph structure (#57) + * Graph adaptors (#67) + * ArcSet and EdgeSet classes (#67) + * Elevator class (#174) + * Other new tools + * LP/MIP interface (#44) + * Support for GLPK, CPLEX, Soplex, COIN-OR CLP and CBC + * Reader for the Nauty file format (#55) + * DIMACS readers (#167) + * Radix sort algorithms (#72) + * RangeIdMap and CrossRefMap (#160) + * New command line tools + * DIMACS to LGF converter (#182) + * lgf-gen - a graph generator (#45) + * DIMACS solver utility (#226) + * Other code improvements + * Lognormal distribution added to Random (#102) + * Better (i.e. O(1) time) item counting in SmartGraph (#3) + * The standard maps of graphs are guaranteed to be + reference maps (#190) + * Miscellaneous + * Various doc improvements + * Improved 0.x -> 1.x converter script + + * Several bugfixes (compared to release 1.0): + #170: Bugfix SmartDigraph::split() + #171: Bugfix in SmartGraph::restoreSnapshot() + #172: Extended test cases for graphs and digraphs + #173: Bugfix in Random + * operator()s always return a double now + * the faulty real(Num) and real(Num,Num) + have been removed + #187: Remove DijkstraWidestPathOperationTraits + #61: Bugfix in DfsVisit + #193: Bugfix in GraphReader::skipSection() + #195: Bugfix in ConEdgeIt() + #197: Bugfix in heap unionfind + * This bug affects Edmond's general matching algorithms + #207: Fix 'make install' without 'make html' using CMAKE + #208: Suppress or fix VS2008 compilation warnings + ----: Update the LEMON icon + ----: Enable the component-based installer + (in installers made by CPACK) + ----: Set the proper version for CMAKE in the tarballs + (made by autotools) + ----: Minor clarification in the LICENSE file + ----: Add missing unistd.h include to time_measure.h + #204: Compilation bug fixed in graph_to_eps.h with VS2005 + #214,#215: windows.h should never be included by LEMON headers + #230: Build systems check the availability of 'long long' type + #229: Default implementation of Tolerance<> is used for integer types + #211,#212: Various fixes for compiling on AIX + ----: Improvements in CMAKE config + - docs is installed in share/doc/ + - detects newer versions of Ghostscript + #239: Fix missing 'inline' specifier in time_measure.h + #274,#280: Install lemon/config.h + #275: Prefix macro names with LEMON_ in lemon/config.h + ----: Small script for making the release tarballs added + ----: Minor improvement in unify-sources.sh (a76f55d7d397) + +2009-03-27 LEMON joins to the COIN-OR initiative + + COIN-OR (Computational Infrastructure for Operations Research, + http://www.coin-or.org) project is an initiative to spur the + development of open-source software for the operations research + community. + +2008-10-13 Version 1.0 released + + This is the first stable release of LEMON. Compared to the 0.x + release series, it features a considerably smaller but more + matured set of tools. The API has also completely revised and + changed in several places. + + * The major name changes compared to the 0.x series (see the + Migration Guide in the doc for more details) + * Graph -> Digraph, UGraph -> Graph + * Edge -> Arc, UEdge -> Edge + * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge) + * Other improvements + * Better documentation + * Reviewed and cleaned up codebase + * CMake based build system (along with the autotools based one) + * Contents of the library (ported from 0.x) + * Algorithms + * breadth-first search (bfs.h) + * depth-first search (dfs.h) + * Dijkstra's algorithm (dijkstra.h) + * Kruskal's algorithm (kruskal.h) + * Data structures + * graph data structures (list_graph.h, smart_graph.h) + * path data structures (path.h) + * binary heap data structure (bin_heap.h) + * union-find data structures (unionfind.h) + * miscellaneous property maps (maps.h) + * two dimensional vector and bounding box (dim2.h) + * Concepts + * graph structure concepts (concepts/digraph.h, concepts/graph.h, + concepts/graph_components.h) + * concepts for other structures (concepts/heap.h, concepts/maps.h, + concepts/path.h) + * Tools + * Mersenne twister random number generator (random.h) + * tools for measuring cpu and wall clock time (time_measure.h) + * tools for counting steps and events (counter.h) + * tool for parsing command line arguments (arg_parser.h) + * tool for visualizing graphs (graph_to_eps.h) + * tools for reading and writing data in LEMON Graph Format + (lgf_reader.h, lgf_writer.h) + * tools to handle the anomalies of calculations with + floating point numbers (tolerance.h) + * tools to manage RGB colors (color.h) + * Infrastructure + * extended assertion handling (assert.h) + * exception classes and error handling (error.h) + * concept checking (concept_check.h) + * commonly used mathematical constants (math.h) diff --git a/lemon/README b/lemon/README new file mode 100644 index 0000000..52a768c --- /dev/null +++ b/lemon/README @@ -0,0 +1,50 @@ +===================================================================== +LEMON - a Library for Efficient Modeling and Optimization in Networks +===================================================================== + +LEMON is an open source library written in C++. It provides +easy-to-use implementations of common data structures and algorithms +in the area of optimization and helps implementing new ones. The main +focus is on graphs and graph algorithms, thus it is especially +suitable for solving design and optimization problems of +telecommunication networks. To achieve wide usability its data +structures and algorithms provide generic interfaces. + +Contents +======== + +LICENSE + + Copying, distribution and modification conditions and terms. + +NEWS + + News and version history. + +INSTALL + + General building and installation instructions. + +lemon/ + + Source code of LEMON library. + +doc/ + + Documentation of LEMON. The starting page is doc/html/index.html. + +demo/ + + Some example programs to make you easier to get familiar with LEMON. + +scripts/ + + Scripts that make it easier to develop LEMON. + +test/ + + Programs to check the integrity and correctness of LEMON. + +tools/ + + Various utilities related to LEMON. diff --git a/lemon/aclocal.m4 b/lemon/aclocal.m4 new file mode 100644 index 0000000..e31779e --- /dev/null +++ b/lemon/aclocal.m4 @@ -0,0 +1,960 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/lx_check_coin.m4]) +m4_include([m4/lx_check_cplex.m4]) +m4_include([m4/lx_check_glpk.m4]) +m4_include([m4/lx_check_soplex.m4]) diff --git a/lemon/build-aux/config.guess b/lemon/build-aux/config.guess new file mode 100755 index 0000000..666c5ad --- /dev/null +++ b/lemon/build-aux/config.guess @@ -0,0 +1,1511 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_MACHINE}" in + i?86) + test -z "$VENDOR" && VENDOR=pc + ;; + *) + test -z "$VENDOR" && VENDOR=unknown + ;; +esac +test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-${VENDOR}-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-${VENDOR}-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-${VENDOR}-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-${VENDOR}-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-${VENDOR}-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-${VENDOR}-osf1mk + else + echo ${UNAME_MACHINE}-${VENDOR}-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-${VENDOR}-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-${VENDOR}-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-${VENDOR}-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-${VENDOR}-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-${VENDOR}-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-${VENDOR}-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-${VENDOR}-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-${VENDOR}-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + else + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-${VENDOR}-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-${VENDOR}-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-${VENDOR}-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-${VENDOR}-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-${VENDOR}-linux-gnu ;; + PA8*) echo hppa2.0-${VENDOR}-linux-gnu ;; + *) echo hppa-${VENDOR}-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-${VENDOR}-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-${VENDOR}-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-${VENDOR}-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-${VENDOR}-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-${VENDOR}-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-${VENDOR}-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-${VENDOR}-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-${VENDOR}-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-${VENDOR}-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-${VENDOR}-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-${VENDOR}-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-${VENDOR}-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-${VENDOR}-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-${VENDOR}-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-${VENDOR}-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-${VENDOR}-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-${VENDOR}-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-${VENDOR}-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lemon/build-aux/config.sub b/lemon/build-aux/config.sub new file mode 100755 index 0000000..2a55a50 --- /dev/null +++ b/lemon/build-aux/config.sub @@ -0,0 +1,1705 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lemon/build-aux/depcomp b/lemon/build-aux/depcomp new file mode 100755 index 0000000..df8eea7 --- /dev/null +++ b/lemon/build-aux/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/lemon/build-aux/install-sh b/lemon/build-aux/install-sh new file mode 100755 index 0000000..6781b98 --- /dev/null +++ b/lemon/build-aux/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/lemon/build-aux/ltmain.sh b/lemon/build-aux/ltmain.sh new file mode 100755 index 0000000..950feee --- /dev/null +++ b/lemon/build-aux/ltmain.sh @@ -0,0 +1,8406 @@ +# Generated from ltmain.m4sh. + +# ltmain.sh (GNU libtool) 2.2.6b +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print informational messages (default) +# --version print version information +# -h, --help print short or long help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.2.6b +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=2.2.6b +TIMESTAMP="" +package_revision=1.3018 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# NLS nuisances: We save the old values to restore during execute mode. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done + +$lt_unset CDPATH + + + + + +: ${CP="cp -f"} +: ${ECHO="echo"} +: ${EGREP="/usr/bin/grep -E"} +: ${FGREP="/usr/bin/grep -F"} +: ${GREP="/usr/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/usr/bin/sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +# Generated shell functions inserted here. + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +# In the unlikely event $progname began with a '-', it would play havoc with +# func_echo (imagine progname=-n), so we prepend ./ in that case: +func_dirname_and_basename "$progpath" +progname=$func_basename_result +case $progname in + -*) progname=./$progname ;; +esac + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname${mode+: }$mode: $*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` + done + my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "X$my_tmpdir" | $Xsed +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "X$1" | $Xsed \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + + + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $SED -n '/^# Usage:/,/# -h/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + $ECHO + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help +# Echo long help message to standard output and exit. +func_help () +{ + $SED -n '/^# Usage:/,/# Report bugs to/ { + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + }' < "$progpath" + exit $? +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1" + exit_cmd=exit +} + +exit_cmd=: + + + + + +# Check that we have a working $ECHO. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell, and then maybe $ECHO will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `libtool --version' happen quickly. +{ + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Parse non-mode specific arguments: + while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --config) func_config ;; + + --debug) preserve_args="$preserve_args $opt" + func_echo "enabling shell trace mode" + opt_debug='set -x' + $opt_debug + ;; + + -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break + execute_dlfiles="$execute_dlfiles $1" + shift + ;; + + --dry-run | -n) opt_dry_run=: ;; + --features) func_features ;; + --finish) mode="finish" ;; + + --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break + case $1 in + # Valid mode arguments: + clean) ;; + compile) ;; + execute) ;; + finish) ;; + install) ;; + link) ;; + relink) ;; + uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; + esac + + mode="$1" + shift + ;; + + --preserve-dup-deps) + opt_duplicate_deps=: ;; + + --quiet|--silent) preserve_args="$preserve_args $opt" + opt_silent=: + ;; + + --verbose| -v) preserve_args="$preserve_args $opt" + opt_silent=false + ;; + + --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break + preserve_args="$preserve_args $opt $1" + func_enable_tag "$1" # tagname is set here + shift + ;; + + # Separate optargs to long options: + -dlopen=*|--mode=*|--tag=*) + func_opt_split "$opt" + set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + shift + ;; + + -\?|-h) func_usage ;; + --help) opt_help=: ;; + --version) func_version ;; + + -*) func_fatal_help "unrecognized option \`$opt'" ;; + + *) nonopt="$opt" + break + ;; + esac + done + + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_duplicate_deps + ;; + esac + + # Having warned about all mis-specified options, bail out if + # anything was wrong. + $exit_cmd $EXIT_FAILURE +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +## ----------- ## +## Main. ## +## ----------- ## + +$opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + test -z "$mode" && func_fatal_error "error: you must specify a MODE." + + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$mode' for more information." +} + + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_ltwrapper_scriptname_result="" + if func_ltwrapper_executable_p "$1"; then + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + fi +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case "$@ " in + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + removelist="$removelist $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + removelist="$removelist $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { +test "$mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$mode'" + ;; + esac + + $ECHO + $ECHO "Try \`$progname --help' for more information about other modes." + + exit $? +} + + # Now that we've collected a possible --mode arg, show help if necessary + $opt_help && func_mode_help + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_quote_for_eval "$file" + args="$args $func_quote_for_eval_result" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + $ECHO "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + $ECHO "X----------------------------------------------------------------------" | $Xsed + $ECHO "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + $ECHO + $ECHO "If you ever happen to want to link against installed libraries" + $ECHO "in a given directory, LIBDIR, you must either use libtool, and" + $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" + $ECHO "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" + $ECHO " during execution" + fi + if test -n "$runpath_var"; then + $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" + $ECHO " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $ECHO + + $ECHO "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" + $ECHO "pages." + ;; + *) + $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + $ECHO "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS +} + +test "$mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $ECHO "X$nonopt" | $GREP shtool >/dev/null; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + install_prog="$install_prog$func_quote_for_eval_result" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + install_prog="$install_prog $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_verbose "extracting global C symbols from \`$progfile'" + $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + $ECHO >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +" + case $host in + *cygwin* | *mingw* | *cegcc* ) + $ECHO >> "$output_objdir/$my_dlsyms" "\ +/* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs. */" + lt_dlsym_const= ;; + *osf5*) + echo >> "$output_objdir/$my_dlsyms" "\ +/* This system does not cope well with relocations in const data */" + lt_dlsym_const= ;; + *) + lt_dlsym_const=const ;; + esac + + $ECHO >> "$output_objdir/$my_dlsyms" "\ +extern $lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +$lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + $ECHO >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) symtab_cflags="$symtab_cflags $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + + +# func_emit_wrapper_part1 [arg=no] +# +# Emit the first part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part1 () +{ + func_emit_wrapper_part1_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part1_arg1=$1 + fi + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + ECHO=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$ECHO works! + : + else + # Restart under the correct shell, and then maybe \$ECHO will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $ECHO "\ + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done +" +} +# end: func_emit_wrapper_part1 + +# func_emit_wrapper_part2 [arg=no] +# +# Emit the second part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part2 () +{ + func_emit_wrapper_part2_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part2_arg1=$1 + fi + + $ECHO "\ + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} +# end: func_emit_wrapper_part2 + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=no + if test -n "$1" ; then + func_emit_wrapper_arg1=$1 + fi + + # split this up so that func_emit_cwrapperexe_src + # can call each part independently. + func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" + func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" +} + + +# func_to_host_path arg +# +# Convert paths to host format when used with build tools. +# Intended for use with "native" mingw (where libtool itself +# is running under the msys shell), or in the following cross- +# build environments: +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# where wine is equipped with the `winepath' executable. +# In the native mingw case, the (msys) shell automatically +# converts paths for any non-msys applications it launches, +# but that facility isn't available from inside the cwrapper. +# Similar accommodations are necessary for $host mingw and +# $build cygwin. Calling this function does no harm for other +# $host/$build combinations not listed above. +# +# ARG is the path (on $build) that should be converted to +# the proper representation for $host. The result is stored +# in $func_to_host_path_result. +func_to_host_path () +{ + func_to_host_path_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + case $build in + *mingw* ) # actually, msys + # awkward: cmd appends spaces to result + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_path_tmp1=`( cmd //c echo "$1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_path_tmp1=`cygpath -w "$1"` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # Unfortunately, winepath does not exit with a non-zero + # error code, so we are forced to check the contents of + # stdout. On the other hand, if the command is not + # found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both + # error code of zero AND non-empty stdout, which explains + # the odd construction: + func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + else + # Allow warning below. + func_to_host_path_result="" + fi + ;; + esac + if test -z "$func_to_host_path_result" ; then + func_error "Could not determine host path corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_path_result="$1" + fi + ;; + esac + fi +} +# end: func_to_host_path + +# func_to_host_pathlist arg +# +# Convert pathlists to host format when used with build tools. +# See func_to_host_path(), above. This function supports the +# following $build/$host combinations (but does no harm for +# combinations not listed here): +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# +# Path separators are also converted from $build format to +# $host format. If ARG begins or ends with a path separator +# character, it is preserved (but converted to $host format) +# on output. +# +# ARG is a pathlist (on $build) that should be converted to +# the proper representation on $host. The result is stored +# in $func_to_host_pathlist_result. +func_to_host_pathlist () +{ + func_to_host_pathlist_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_to_host_pathlist_tmp2="$1" + # Once set for this call, this variable should not be + # reassigned. It is used in tha fallback case. + func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e 's|^:*||' -e 's|:*$||'` + case $build in + *mingw* ) # Actually, msys. + # Awkward: cmd appends spaces to result. + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # unfortunately, winepath doesn't convert pathlists + func_to_host_pathlist_result="" + func_to_host_pathlist_oldIFS=$IFS + IFS=: + for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do + IFS=$func_to_host_pathlist_oldIFS + if test -n "$func_to_host_pathlist_f" ; then + func_to_host_path "$func_to_host_pathlist_f" + if test -n "$func_to_host_path_result" ; then + if test -z "$func_to_host_pathlist_result" ; then + func_to_host_pathlist_result="$func_to_host_path_result" + else + func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" + fi + fi + fi + IFS=: + done + IFS=$func_to_host_pathlist_oldIFS + ;; + esac + if test -z "$func_to_host_pathlist_result" ; then + func_error "Could not determine the host path(s) corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This may break if $1 contains DOS-style drive + # specifications. The fix is not to complicate the expression + # below, but for the user to provide a working wine installation + # with winepath so that path translation in the cross-to-mingw + # case works properly. + lt_replace_pathsep_nix_to_dos="s|:|;|g" + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_replace_pathsep_nix_to_dos"` + fi + # Now, add the leading and trailing path separators back + case "$1" in + :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" + ;; + esac + case "$1" in + *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" + ;; + esac + ;; + esac + fi +} +# end: func_to_host_pathlist + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +# define setmode _setmode +#else +# include +# include +# ifdef __CYGWIN__ +# include +# define HAVE_SETENV +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +#ifdef _MSC_VER +# define S_IXUSR _S_IEXEC +# define stat _stat +# ifndef _INTPTR_T_DEFINED +# define intptr_t int +# endif +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifdef __CYGWIN__ +# define FOPEN_WB "wb" +#endif + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#undef LTWRAPPER_DEBUGPRINTF +#if defined DEBUGWRAPPER +# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args +static void +ltwrapper_debugprintf (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); +} +#else +# define LTWRAPPER_DEBUGPRINTF(args) +#endif + +const char *program_name = NULL; + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_fatal (const char *message, ...); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_opt_process_env_set (const char *arg); +void lt_opt_process_env_prepend (const char *arg); +void lt_opt_process_env_append (const char *arg); +int lt_split_name_value (const char *arg, char** name, char** value); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); + +static const char *script_text_part1 = +EOF + + func_emit_wrapper_part1 yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ "/' -e 's/$/\\n"/' + echo ";" + cat <"))); + for (i = 0; i < newargc; i++) + { + LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", + wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", + tmp_pathspec)); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + char *errstr = strerror (errno); + lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal ("Could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} + +void +lt_setenv (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", + (name ? name : ""), + (value ? value : ""))); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +int +lt_split_name_value (const char *arg, char** name, char** value) +{ + const char *p; + int len; + if (!arg || !*arg) + return 1; + + p = strchr (arg, (int)'='); + + if (!p) + return 1; + + *value = xstrdup (++p); + + len = strlen (arg) - strlen (*value); + *name = XMALLOC (char, len); + strncpy (*name, arg, len-1); + (*name)[len - 1] = '\0'; + + return 0; +} + +void +lt_opt_process_env_set (const char *arg) +{ + char *name = NULL; + char *value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); + } + + lt_setenv (name, value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_prepend (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_append (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 1); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + + +EOF +} +# end: func_emit_cwrapperexe_src + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + weak_libs="$weak_libs $arg" + prev= + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname '-L' '' "$arg" + dir=$func_stripname_result + if test -z "$dir"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" + linker_flags="$linker_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_duplicate_deps ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + case $lib in + *.la) func_source "$lib" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` + case " $weak_libs " in + *" $deplib_base "*) ;; + *) deplibs="$deplibs $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + dir=$func_stripname_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $ECHO + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because the file extensions .$libext of this argument makes me believe" + $ECHO "*** that it is just a static archive that I should not use here." + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) temp_rpath="$temp_rpath$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + $ECHO + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $ECHO + $ECHO "*** And there doesn't seem to be a static archive available" + $ECHO "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $ECHO + $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $ECHO "*** But as you try to build a module library, libtool will still create " + $ECHO "*** a static module, that should work as long as the dlopening application" + $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_dirname "$deplib" "" "." + dir="$func_dirname_result" + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + libobjs="$libobjs $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` + # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` + # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ + -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` + done + fi + if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | + $GREP . >/dev/null; then + $ECHO + if test "X$deplibs_check_method" = "Xnone"; then + $ECHO "*** Warning: inter-library dependencies are not supported in this platform." + else + $ECHO "*** Warning: inter-library dependencies are not known to be supported." + fi + $ECHO "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $ECHO + $ECHO "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + $ECHO "*** a static module, that should work as long as the dlopening" + $ECHO "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $ECHO "*** The inter-library dependencies that have been dropped here will be" + $ECHO "*** automatically added whenever a program is linked with this library" + $ECHO "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $ECHO + $ECHO "*** Since this library must not contain undefined symbols," + $ECHO "*** because either the platform does not support them or" + $ECHO "*** it was explicitly requested with -no-undefined," + $ECHO "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + delfiles="$delfiles $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$ECHO "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + $ECHO 'INPUT (' > $output + for obj in $save_libobjs + do + $ECHO "$obj" >> $output + done + $ECHO ')' >> $output + delfiles="$delfiles $output" + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + $ECHO "$obj" >> $output + done + delfiles="$delfiles $output" + output=$firstobj\"$file_list_spec$output\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + delfiles="$delfiles $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *cegcc) + # Disable wrappers for cegcc, we are cross compiling anyway. + wrappers_required=no + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $ECHO for shipping. + if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + oldobjs="$oldobjs $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $ECHO "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlfiles="$newdlfiles $libdir/$name" + ;; + *) newdlfiles="$newdlfiles $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlprefiles="$newdlprefiles $libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$mode" = link || test "$mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) RM="$RM $arg"; rmforce=yes ;; + -*) RM="$RM $arg" ;; + *) files="$files $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$mode" = uninstall || test "$mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/lemon/build-aux/missing b/lemon/build-aux/missing new file mode 100755 index 0000000..28055d2 --- /dev/null +++ b/lemon/build-aux/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/lemon/cmake/FindCOIN.cmake b/lemon/cmake/FindCOIN.cmake new file mode 100644 index 0000000..74d37c0 --- /dev/null +++ b/lemon/cmake/FindCOIN.cmake @@ -0,0 +1,98 @@ +SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory") + +FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h + HINTS ${COIN_ROOT_DIR}/include +) +FIND_LIBRARY(COIN_CBC_LIBRARY + NAMES Cbc libCbc + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY + NAMES CbcSolver libCbcSolver + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_CGL_LIBRARY + NAMES Cgl libCgl + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_CLP_LIBRARY + NAMES Clp libClp + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY + NAMES CoinUtils libCoinUtils + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_OSI_LIBRARY + NAMES Osi libOsi + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_OSI_CBC_LIBRARY + NAMES OsiCbc libOsiCbc + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_OSI_CLP_LIBRARY + NAMES OsiClp libOsiClp + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_OSI_VOL_LIBRARY + NAMES OsiVol libOsiVol + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) +FIND_LIBRARY(COIN_VOL_LIBRARY + NAMES Vol libVol + HINTS ${COIN_ROOT_DIR}/lib/coin + HINTS ${COIN_ROOT_DIR}/lib +) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG + COIN_INCLUDE_DIR + COIN_CBC_LIBRARY + COIN_CBC_SOLVER_LIBRARY + COIN_CGL_LIBRARY + COIN_CLP_LIBRARY + COIN_COIN_UTILS_LIBRARY + COIN_OSI_LIBRARY + COIN_OSI_CBC_LIBRARY + COIN_OSI_CLP_LIBRARY + # COIN_OSI_VOL_LIBRARY + # COIN_VOL_LIBRARY +) + +IF(COIN_FOUND) + SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR}) + SET(COIN_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY}") + SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}") + SET(COIN_CBC_LIBRARIES ${COIN_LIBRARIES}) +ENDIF(COIN_FOUND) + +MARK_AS_ADVANCED( + COIN_INCLUDE_DIR + COIN_CBC_LIBRARY + COIN_CBC_SOLVER_LIBRARY + COIN_CGL_LIBRARY + COIN_CLP_LIBRARY + COIN_COIN_UTILS_LIBRARY + COIN_OSI_LIBRARY + COIN_OSI_CBC_LIBRARY + COIN_OSI_CLP_LIBRARY + COIN_OSI_VOL_LIBRARY + COIN_VOL_LIBRARY +) + +IF(COIN_FOUND) + SET(LEMON_HAVE_LP TRUE) + SET(LEMON_HAVE_MIP TRUE) + SET(LEMON_HAVE_CLP TRUE) + SET(LEMON_HAVE_CBC TRUE) +ENDIF(COIN_FOUND) diff --git a/lemon/cmake/FindCPLEX.cmake b/lemon/cmake/FindCPLEX.cmake new file mode 100644 index 0000000..71dca09 --- /dev/null +++ b/lemon/cmake/FindCPLEX.cmake @@ -0,0 +1,38 @@ +SET(CPLEX_ROOT_DIR "" CACHE PATH "CPLEX root directory") + +FIND_PATH(CPLEX_INCLUDE_DIR + ilcplex/cplex.h + PATHS "C:/ILOG/CPLEX91/include" + PATHS "/opt/ilog/cplex91/include" + HINTS ${CPLEX_ROOT_DIR}/include +) +FIND_LIBRARY(CPLEX_LIBRARY + cplex91 + PATHS "C:/ILOG/CPLEX91/lib/msvc7/stat_mda" + PATHS "/opt/ilog/cplex91/bin" + HINTS ${CPLEX_ROOT_DIR}/bin +) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR) + +FIND_PATH(CPLEX_BIN_DIR + cplex91.dll + PATHS "C:/ILOG/CPLEX91/bin/x86_win32" +) + +IF(CPLEX_FOUND) + SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR}) + SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY}) + IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") + SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread") + ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux") +ENDIF(CPLEX_FOUND) + +MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR) + +IF(CPLEX_FOUND) + SET(LEMON_HAVE_LP TRUE) + SET(LEMON_HAVE_MIP TRUE) + SET(LEMON_HAVE_CPLEX TRUE) +ENDIF(CPLEX_FOUND) diff --git a/lemon/cmake/FindGLPK.cmake b/lemon/cmake/FindGLPK.cmake new file mode 100644 index 0000000..4e576af --- /dev/null +++ b/lemon/cmake/FindGLPK.cmake @@ -0,0 +1,61 @@ +SET(GLPK_ROOT_DIR "" CACHE PATH "GLPK root directory") + +SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]") +GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE) + +FIND_PATH(GLPK_INCLUDE_DIR + glpk.h + PATHS ${GLPK_REGKEY}/include + HINTS ${GLPK_ROOT_DIR}/include +) +FIND_LIBRARY(GLPK_LIBRARY + glpk + PATHS ${GLPK_REGKEY}/lib + HINTS ${GLPK_ROOT_DIR}/lib +) + +IF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY) + FILE(READ ${GLPK_INCLUDE_DIR}/glpk.h GLPK_GLPK_H) + + STRING(REGEX MATCH "define[ ]+GLP_MAJOR_VERSION[ ]+[0-9]+" GLPK_MAJOR_VERSION_LINE "${GLPK_GLPK_H}") + STRING(REGEX REPLACE "define[ ]+GLP_MAJOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MAJOR "${GLPK_MAJOR_VERSION_LINE}") + + STRING(REGEX MATCH "define[ ]+GLP_MINOR_VERSION[ ]+[0-9]+" GLPK_MINOR_VERSION_LINE "${GLPK_GLPK_H}") + STRING(REGEX REPLACE "define[ ]+GLP_MINOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MINOR "${GLPK_MINOR_VERSION_LINE}") + + SET(GLPK_VERSION_STRING "${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}") + + IF(GLPK_FIND_VERSION) + IF(GLPK_FIND_VERSION_COUNT GREATER 2) + MESSAGE(SEND_ERROR "unexpected version string") + ENDIF(GLPK_FIND_VERSION_COUNT GREATER 2) + + MATH(EXPR GLPK_REQUESTED_VERSION "${GLPK_FIND_VERSION_MAJOR}*100 + ${GLPK_FIND_VERSION_MINOR}") + MATH(EXPR GLPK_FOUND_VERSION "${GLPK_VERSION_MAJOR}*100 + ${GLPK_VERSION_MINOR}") + + IF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION) + SET(GLPK_PROPER_VERSION_FOUND FALSE) + ELSE(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION) + SET(GLPK_PROPER_VERSION_FOUND TRUE) + ENDIF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION) + ELSE(GLPK_FIND_VERSION) + SET(GLPK_PROPER_VERSION_FOUND TRUE) + ENDIF(GLPK_FIND_VERSION) +ENDIF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_PROPER_VERSION_FOUND) + +IF(GLPK_FOUND) + SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR}) + SET(GLPK_LIBRARIES ${GLPK_LIBRARY}) + SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin) +ENDIF(GLPK_FOUND) + +MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR) + +IF(GLPK_FOUND) + SET(LEMON_HAVE_LP TRUE) + SET(LEMON_HAVE_MIP TRUE) + SET(LEMON_HAVE_GLPK TRUE) +ENDIF(GLPK_FOUND) diff --git a/lemon/cmake/FindGhostscript.cmake b/lemon/cmake/FindGhostscript.cmake new file mode 100644 index 0000000..3366a00 --- /dev/null +++ b/lemon/cmake/FindGhostscript.cmake @@ -0,0 +1,10 @@ +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PROGRAM(GHOSTSCRIPT_EXECUTABLE + NAMES gs gswin32c + PATHS "$ENV{ProgramFiles}/gs" + PATH_SUFFIXES gs8.61/bin gs8.62/bin gs8.63/bin gs8.64/bin gs8.65/bin + DOC "Ghostscript: PostScript and PDF language interpreter and previewer." +) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ghostscript DEFAULT_MSG GHOSTSCRIPT_EXECUTABLE) diff --git a/lemon/cmake/LEMONConfig.cmake.in b/lemon/cmake/LEMONConfig.cmake.in new file mode 100644 index 0000000..b0d2d8b --- /dev/null +++ b/lemon/cmake/LEMONConfig.cmake.in @@ -0,0 +1,13 @@ +SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory") +SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}") + +IF(UNIX) + SET(LEMON_LIB_NAME "libemon.a") +ELSEIF(WIN32) + SET(LEMON_LIB_NAME "lemon.lib") +ENDIF(UNIX) + +SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library") +SET(LEMON_LIBRARIES "${LEMON_LIBRARY}") + +MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR) diff --git a/lemon/cmake/nsis/lemon.ico b/lemon/cmake/nsis/lemon.ico new file mode 100644 index 0000000..bbfd8c1 Binary files /dev/null and b/lemon/cmake/nsis/lemon.ico differ diff --git a/lemon/cmake/nsis/uninstall.ico b/lemon/cmake/nsis/uninstall.ico new file mode 100644 index 0000000..7495f7c Binary files /dev/null and b/lemon/cmake/nsis/uninstall.ico differ diff --git a/lemon/cmake/version.cmake b/lemon/cmake/version.cmake new file mode 100644 index 0000000..9c106b6 --- /dev/null +++ b/lemon/cmake/version.cmake @@ -0,0 +1 @@ +SET(LEMON_VERSION "1.2.3" CACHE STRING "LEMON version string.") diff --git a/lemon/cmake/version.cmake.in b/lemon/cmake/version.cmake.in new file mode 100644 index 0000000..4a2680b --- /dev/null +++ b/lemon/cmake/version.cmake.in @@ -0,0 +1 @@ +SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.") diff --git a/lemon/config.h b/lemon/config.h new file mode 100644 index 0000000..d388177 --- /dev/null +++ b/lemon/config.h @@ -0,0 +1,126 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `ctime_r' function. */ +#define HAVE_CTIME_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIMES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the `times' function. */ +#define HAVE_TIMES 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have CBC. */ +/* #undef LEMON_HAVE_CBC */ + +/* Define to 1 if you have CLP. */ +/* #undef LEMON_HAVE_CLP */ + +/* Define to 1 if you have CPLEX. */ +/* #undef LEMON_HAVE_CPLEX */ + +/* Define to 1 if you have GLPK. */ +/* #undef LEMON_HAVE_GLPK */ + +/* Define to 1 if you have long long. */ +#define LEMON_HAVE_LONG_LONG 1 + +/* Define to 1 if you have any LP solver. */ +/* #undef LEMON_HAVE_LP */ + +/* Define to 1 if you have any MIP solver. */ +/* #undef LEMON_HAVE_MIP */ + +/* Define to 1 if you have SOPLEX. */ +/* #undef LEMON_HAVE_SOPLEX */ + +/* The version string */ +#define LEMON_VERSION 1.2.3 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "lemon" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "LEMON" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "LEMON 1.2.3" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "lemon" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.2.3" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Version number of package */ +#define VERSION "1.2.3" + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/lemon/config.h.in b/lemon/config.h.in new file mode 100644 index 0000000..5025de2 --- /dev/null +++ b/lemon/config.h.in @@ -0,0 +1,125 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `ctime_r' function. */ +#undef HAVE_CTIME_R + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIMES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the `times' function. */ +#undef HAVE_TIMES + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have CBC. */ +#undef LEMON_HAVE_CBC + +/* Define to 1 if you have CLP. */ +#undef LEMON_HAVE_CLP + +/* Define to 1 if you have CPLEX. */ +#undef LEMON_HAVE_CPLEX + +/* Define to 1 if you have GLPK. */ +#undef LEMON_HAVE_GLPK + +/* Define to 1 if you have long long. */ +#undef LEMON_HAVE_LONG_LONG + +/* Define to 1 if you have any LP solver. */ +#undef LEMON_HAVE_LP + +/* Define to 1 if you have any MIP solver. */ +#undef LEMON_HAVE_MIP + +/* Define to 1 if you have SOPLEX. */ +#undef LEMON_HAVE_SOPLEX + +/* The version string */ +#undef LEMON_VERSION + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/lemon/config.log b/lemon/config.log new file mode 100644 index 0000000..faf42ef --- /dev/null +++ b/lemon/config.log @@ -0,0 +1,1252 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by LEMON configure 1.2.3, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ ./configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = pc-4w14-0 +uname -m = x86_64 +uname -r = 3.2.0-2-amd64 +uname -s = Linux +uname -v = #1 SMP Mon Jun 11 17:24:18 UTC 2012 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /home/carlo/bin +PATH: /home/carlo/bin +PATH: /usr/local/bin +PATH: /usr/bin +PATH: /bin +PATH: /usr/local/games +PATH: /usr/games + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2680: checking for a BSD-compatible install +configure:2748: result: /usr/bin/install -c +configure:2759: checking whether build environment is sane +configure:2809: result: yes +configure:2950: checking for a thread-safe mkdir -p +configure:2989: result: /bin/mkdir -p +configure:3002: checking for gawk +configure:3032: result: no +configure:3002: checking for mawk +configure:3018: found /usr/bin/mawk +configure:3029: result: mawk +configure:3040: checking whether make sets $(MAKE) +configure:3062: result: yes +configure:3169: checking for style of include used by make +configure:3197: result: GNU +configure:3277: checking for g++ +configure:3293: found /usr/bin/g++ +configure:3304: result: g++ +configure:3331: checking for C++ compiler version +configure:3340: g++ --version >&5 +g++ (Debian 4.7.1-2) 4.7.1 +Copyright (C) 2012 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:3351: $? = 0 +configure:3340: g++ -v >&5 +Using built-in specs. +COLLECT_GCC=g++ +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.1-2' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.7.1 (Debian 4.7.1-2) +configure:3351: $? = 0 +configure:3340: g++ -V >&5 +g++: error: unrecognized command line option '-V' +g++: fatal error: no input files +compilation terminated. +configure:3351: $? = 4 +configure:3340: g++ -qversion >&5 +g++: error: unrecognized command line option '-qversion' +g++: fatal error: no input files +compilation terminated. +configure:3351: $? = 4 +configure:3371: checking whether the C++ compiler works +configure:3393: g++ conftest.cpp >&5 +configure:3397: $? = 0 +configure:3445: result: yes +configure:3448: checking for C++ compiler default output file name +configure:3450: result: a.out +configure:3456: checking for suffix of executables +configure:3463: g++ -o conftest conftest.cpp >&5 +configure:3467: $? = 0 +configure:3489: result: +configure:3511: checking whether we are cross compiling +configure:3519: g++ -o conftest conftest.cpp >&5 +configure:3523: $? = 0 +configure:3530: ./conftest +configure:3534: $? = 0 +configure:3549: result: no +configure:3554: checking for suffix of object files +configure:3576: g++ -c conftest.cpp >&5 +configure:3580: $? = 0 +configure:3601: result: o +configure:3605: checking whether we are using the GNU C++ compiler +configure:3624: g++ -c conftest.cpp >&5 +configure:3624: $? = 0 +configure:3633: result: yes +configure:3642: checking whether g++ accepts -g +configure:3662: g++ -c -g conftest.cpp >&5 +configure:3662: $? = 0 +configure:3703: result: yes +configure:3728: checking dependency style of g++ +configure:3838: result: gcc3 +configure:3859: checking how to run the C++ preprocessor +configure:3886: g++ -E conftest.cpp +configure:3886: $? = 0 +configure:3900: g++ -E conftest.cpp +conftest.cpp:12:28: fatal error: ac_nonexistent.h: No such file or directory +compilation terminated. +configure:3900: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| /* end confdefs.h. */ +| #include +configure:3925: result: g++ -E +configure:3945: g++ -E conftest.cpp +configure:3945: $? = 0 +configure:3959: g++ -E conftest.cpp +conftest.cpp:12:28: fatal error: ac_nonexistent.h: No such file or directory +compilation terminated. +configure:3959: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| /* end confdefs.h. */ +| #include +configure:3988: checking for grep that handles long lines and -e +configure:4046: result: /bin/grep +configure:4051: checking for egrep +configure:4113: result: /bin/grep -E +configure:4118: checking for ANSI C header files +configure:4138: g++ -c -g -O2 conftest.cpp >&5 +configure:4138: $? = 0 +configure:4211: g++ -o conftest -g -O2 conftest.cpp >&5 +configure:4211: $? = 0 +configure:4211: ./conftest +configure:4211: $? = 0 +configure:4222: result: yes +configure:4235: checking for sys/types.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for sys/stat.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for stdlib.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for string.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for memory.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for strings.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for inttypes.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for stdint.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4235: checking for unistd.h +configure:4235: g++ -c -g -O2 conftest.cpp >&5 +configure:4235: $? = 0 +configure:4235: result: yes +configure:4247: checking for long long +configure:4247: g++ -c -g -O2 conftest.cpp >&5 +configure:4247: $? = 0 +configure:4247: g++ -c -g -O2 conftest.cpp >&5 +conftest.cpp: In function 'int main()': +conftest.cpp:58:14: error: expected primary-expression before 'long' +conftest.cpp:58:14: error: expected ')' before 'long' +conftest.cpp:59:14: error: expected ')' before ';' token +conftest.cpp:59:14: error: expected ')' before ';' token +configure:4247: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((long long))) +| return 0; +| ; +| return 0; +| } +configure:4247: result: yes +configure:4372: checking for C++ compiler version +configure:4381: g++ --version >&5 +g++ (Debian 4.7.1-2) 4.7.1 +Copyright (C) 2012 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:4392: $? = 0 +configure:4381: g++ -v >&5 +Using built-in specs. +COLLECT_GCC=g++ +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.1-2' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.7.1 (Debian 4.7.1-2) +configure:4392: $? = 0 +configure:4381: g++ -V >&5 +g++: error: unrecognized command line option '-V' +g++: fatal error: no input files +compilation terminated. +configure:4392: $? = 4 +configure:4381: g++ -qversion >&5 +g++: error: unrecognized command line option '-qversion' +g++: fatal error: no input files +compilation terminated. +configure:4392: $? = 4 +configure:4396: checking whether we are using the GNU C++ compiler +configure:4424: result: yes +configure:4433: checking whether g++ accepts -g +configure:4494: result: yes +configure:4519: checking dependency style of g++ +configure:4629: result: gcc3 +configure:4649: checking how to run the C++ preprocessor +configure:4715: result: g++ -E +configure:4735: g++ -E conftest.cpp +configure:4735: $? = 0 +configure:4749: g++ -E conftest.cpp +conftest.cpp:23:28: fatal error: ac_nonexistent.h: No such file or directory +compilation terminated. +configure:4749: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| /* end confdefs.h. */ +| #include +configure:4838: checking build system type +configure:4852: result: x86_64-unknown-linux-gnu +configure:4872: checking host system type +configure:4885: result: x86_64-unknown-linux-gnu +configure:4953: checking for gcc +configure:4969: found /usr/bin/gcc +configure:4980: result: gcc +configure:5209: checking for C compiler version +configure:5218: gcc --version >&5 +gcc (Debian 4.7.1-2) 4.7.1 +Copyright (C) 2012 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:5229: $? = 0 +configure:5218: gcc -v >&5 +Using built-in specs. +COLLECT_GCC=gcc +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.1-2' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.7.1 (Debian 4.7.1-2) +configure:5229: $? = 0 +configure:5218: gcc -V >&5 +gcc: error: unrecognized command line option '-V' +gcc: fatal error: no input files +compilation terminated. +configure:5229: $? = 4 +configure:5218: gcc -qversion >&5 +gcc: error: unrecognized command line option '-qversion' +gcc: fatal error: no input files +compilation terminated. +configure:5229: $? = 4 +configure:5233: checking whether we are using the GNU C compiler +configure:5252: gcc -c conftest.c >&5 +configure:5252: $? = 0 +configure:5261: result: yes +configure:5270: checking whether gcc accepts -g +configure:5290: gcc -c -g conftest.c >&5 +configure:5290: $? = 0 +configure:5331: result: yes +configure:5348: checking for gcc option to accept ISO C89 +configure:5412: gcc -c -g -O2 conftest.c >&5 +configure:5412: $? = 0 +configure:5425: result: none needed +configure:5447: checking dependency style of gcc +configure:5557: result: gcc3 +configure:5572: checking for a sed that does not truncate output +configure:5636: result: /bin/sed +configure:5654: checking for fgrep +configure:5716: result: /bin/grep -F +configure:5751: checking for ld used by gcc +configure:5818: result: /usr/bin/ld +configure:5825: checking if the linker (/usr/bin/ld) is GNU ld +configure:5840: result: yes +configure:5852: checking for BSD- or MS-compatible name lister (nm) +configure:5901: result: /usr/bin/nm -B +configure:6019: checking the name lister (/usr/bin/nm -B) interface +configure:6026: g++ -c -g -O2 conftest.cpp >&5 +configure:6029: /usr/bin/nm -B "conftest.o" +configure:6032: output +0000000000000000 B some_variable +configure:6039: result: BSD nm +configure:6042: checking whether ln -s works +configure:6046: result: yes +configure:6054: checking the maximum length of command line arguments +configure:6174: result: 1572864 +configure:6191: checking whether the shell understands some XSI constructs +configure:6201: result: yes +configure:6205: checking whether the shell understands "+=" +configure:6211: result: yes +configure:6246: checking for /usr/bin/ld option to reload object files +configure:6253: result: -r +configure:6322: checking for objdump +configure:6338: found /usr/bin/objdump +configure:6349: result: objdump +configure:6381: checking how to recognize dependent libraries +configure:6577: result: pass_all +configure:6637: checking for ar +configure:6653: found /usr/bin/ar +configure:6664: result: ar +configure:6742: checking for strip +configure:6758: found /usr/bin/strip +configure:6769: result: strip +configure:6841: checking for ranlib +configure:6857: found /usr/bin/ranlib +configure:6868: result: ranlib +configure:6958: checking command to parse /usr/bin/nm -B output from gcc object +configure:7076: g++ -c -g -O2 conftest.cpp >&5 +configure:7079: $? = 0 +configure:7083: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' \> conftest.nm +configure:7086: $? = 0 +configure:7140: g++ -o conftest -g -O2 conftest.cpp conftstm.o >&5 +configure:7143: $? = 0 +configure:7181: result: ok +configure:7277: g++ -c -g -O2 conftest.cpp >&5 +configure:7280: $? = 0 +configure:7987: checking for dlfcn.h +configure:7987: g++ -c -g -O2 conftest.cpp >&5 +configure:7987: $? = 0 +configure:7987: result: yes +configure:8112: checking for C++ compiler version +configure:8121: g++ --version >&5 +g++ (Debian 4.7.1-2) 4.7.1 +Copyright (C) 2012 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:8132: $? = 0 +configure:8121: g++ -v >&5 +Using built-in specs. +COLLECT_GCC=g++ +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.1-2' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 4.7.1 (Debian 4.7.1-2) +configure:8132: $? = 0 +configure:8121: g++ -V >&5 +g++: error: unrecognized command line option '-V' +g++: fatal error: no input files +compilation terminated. +configure:8132: $? = 4 +configure:8121: g++ -qversion >&5 +g++: error: unrecognized command line option '-qversion' +g++: fatal error: no input files +compilation terminated. +configure:8132: $? = 4 +configure:8136: checking whether we are using the GNU C++ compiler +configure:8164: result: yes +configure:8173: checking whether g++ accepts -g +configure:8234: result: yes +configure:8259: checking dependency style of g++ +configure:8369: result: gcc3 +configure:8392: checking how to run the C++ preprocessor +configure:8458: result: g++ -E +configure:8478: g++ -E conftest.cpp +configure:8478: $? = 0 +configure:8492: g++ -E conftest.cpp +conftest.cpp:24:28: fatal error: ac_nonexistent.h: No such file or directory +compilation terminated. +configure:8492: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| #define HAVE_DLFCN_H 1 +| /* end confdefs.h. */ +| #include +configure:8667: checking for objdir +configure:8682: result: .libs +configure:8978: checking if gcc supports -fno-rtti -fno-exceptions +configure:8996: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 +cc1: warning: command line option '-fno-rtti' is valid for C++/ObjC++ but not for C [enabled by default] +configure:9000: $? = 0 +configure:9013: result: no +configure:9033: checking for gcc option to produce PIC +configure:9305: result: -fPIC -DPIC +configure:9317: checking if gcc PIC flag -fPIC -DPIC works +configure:9335: gcc -c -g -O2 -fPIC -DPIC -DPIC conftest.c >&5 +configure:9339: $? = 0 +configure:9352: result: yes +configure:9376: checking if gcc static flag -static works +configure:9404: result: yes +configure:9419: checking if gcc supports -c -o file.o +configure:9440: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 +configure:9444: $? = 0 +configure:9466: result: yes +configure:9474: checking if gcc supports -c -o file.o +configure:9521: result: yes +configure:9554: checking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries +configure:10541: result: yes +configure:10780: checking dynamic linker characteristics +configure:11213: gcc -o conftest -g -O2 -Wl,-rpath -Wl,/foo conftest.c >&5 +configure:11213: $? = 0 +configure:11431: result: GNU/Linux ld.so +configure:11533: checking how to hardcode library paths into programs +configure:11558: result: immediate +configure:12078: checking whether stripping libraries is possible +configure:12083: result: yes +configure:12118: checking if libtool supports shared libraries +configure:12120: result: yes +configure:12123: checking whether to build shared libraries +configure:12144: result: no +configure:12147: checking whether to build static libraries +configure:12151: result: yes +configure:12301: checking for ld used by g++ +configure:12368: result: /usr/bin/ld -m elf_x86_64 +configure:12375: checking if the linker (/usr/bin/ld -m elf_x86_64) is GNU ld +configure:12390: result: yes +configure:12445: checking whether the g++ linker (/usr/bin/ld -m elf_x86_64) supports shared libraries +configure:13358: result: yes +configure:13386: g++ -c -g -O2 conftest.cpp >&5 +configure:13389: $? = 0 +configure:13571: checking for g++ option to produce PIC +configure:13888: result: -fPIC -DPIC +configure:13897: checking if g++ PIC flag -fPIC -DPIC works +configure:13915: g++ -c -g -O2 -fPIC -DPIC -DPIC conftest.cpp >&5 +configure:13919: $? = 0 +configure:13932: result: yes +configure:13953: checking if g++ static flag -static works +configure:13981: result: yes +configure:13993: checking if g++ supports -c -o file.o +configure:14014: g++ -c -g -O2 -o out/conftest2.o conftest.cpp >&5 +configure:14018: $? = 0 +configure:14040: result: yes +configure:14045: checking if g++ supports -c -o file.o +configure:14092: result: yes +configure:14122: checking whether the g++ linker (/usr/bin/ld -m elf_x86_64) supports shared libraries +configure:14148: result: yes +configure:14285: checking dynamic linker characteristics +configure:14666: g++ -o conftest -g -O2 -Wl,-rpath -Wl,/foo conftest.cpp >&5 +configure:14666: $? = 0 +configure:14884: result: GNU/Linux ld.so +configure:14935: checking how to hardcode library paths into programs +configure:14960: result: immediate +configure:15021: checking for doxygen +configure:15049: result: no +configure:15059: checking for python +configure:15075: found /usr/bin/python +configure:15087: result: yes +configure:15097: checking for gs +configure:15113: found /usr/bin/gs +configure:15125: result: yes +configure:15134: checking whether we are using the Intel C++ compiler +configure:15142: g++ -c -g -O2 conftest.cpp >&5 +conftest.cpp:26:1: error: 'choke' does not name a type +configure:15142: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| #define HAVE_DLFCN_H 1 +| #define LT_OBJDIR ".libs/" +| /* end confdefs.h. */ +| #ifndef __INTEL_COMPILER +| choke me +| #endif +configure:15152: result: no +configure:15191: checking for GLPK +configure:15242: g++ -o conftest conftest.cpp -lglpk >&5 +conftest.cpp:27:24: fatal error: glpk.h: No such file or directory +compilation terminated. +configure:15242: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| #define HAVE_DLFCN_H 1 +| #define LT_OBJDIR ".libs/" +| /* end confdefs.h. */ +| +| extern "C" { +| #include +| } +| +| #if (GLP_MAJOR_VERSION < 4) \ +| || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33) +| #error Supported GLPK versions: 4.33 or above +| #endif +| +| int main(int argc, char** argv) +| { +| LPX *lp; +| lp = lpx_create_prob(); +| lpx_delete_prob(lp); +| return 0; +| } +configure:15278: result: no +configure:15324: checking for CPLEX +configure:15372: g++ -o conftest conftest.cpp -lcplex -lm -lpthread >&5 +conftest.cpp:27:33: fatal error: ilcplex/cplex.h: No such file or directory +compilation terminated. +configure:15372: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| #define HAVE_DLFCN_H 1 +| #define LT_OBJDIR ".libs/" +| /* end confdefs.h. */ +| +| extern "C" { +| #include +| } +| +| int main(int argc, char** argv) +| { +| CPXENVptr env = NULL; +| return 0; +| } +configure:15408: result: no +configure:15454: checking for SOPLEX +configure:15496: g++ -o conftest conftest.cpp -lsoplex -lz >&5 +conftest.cpp:26:26: fatal error: soplex.h: No such file or directory +compilation terminated. +configure:15496: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| #define HAVE_DLFCN_H 1 +| #define LT_OBJDIR ".libs/" +| /* end confdefs.h. */ +| +| #include +| +| int main(int argc, char** argv) +| { +| soplex::SoPlex soplex; +| return 0; +| } +configure:15528: result: no +configure:15574: checking for CLP +configure:15616: g++ -o conftest conftest.cpp -lClp -lCoinUtils -lm >&5 +conftest.cpp:26:35: fatal error: coin/ClpModel.hpp: No such file or directory +compilation terminated. +configure:15616: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| #define HAVE_DLFCN_H 1 +| #define LT_OBJDIR ".libs/" +| /* end confdefs.h. */ +| +| #include +| +| int main(int argc, char** argv) +| { +| ClpModel clp; +| return 0; +| } +configure:15648: result: no +configure:15788: checking whether to build the additional tools +configure:15791: result: yes +configure:15869: checking limits.h usability +configure:15869: g++ -c -g -O2 conftest.cpp >&5 +configure:15869: $? = 0 +configure:15869: result: yes +configure:15869: checking limits.h presence +configure:15869: g++ -E conftest.cpp +configure:15869: $? = 0 +configure:15869: result: yes +configure:15869: checking for limits.h +configure:15869: result: yes +configure:15869: checking sys/time.h usability +configure:15869: g++ -c -g -O2 conftest.cpp >&5 +configure:15869: $? = 0 +configure:15869: result: yes +configure:15869: checking sys/time.h presence +configure:15869: g++ -E conftest.cpp +configure:15869: $? = 0 +configure:15869: result: yes +configure:15869: checking for sys/time.h +configure:15869: result: yes +configure:15869: checking sys/times.h usability +configure:15869: g++ -c -g -O2 conftest.cpp >&5 +configure:15869: $? = 0 +configure:15869: result: yes +configure:15869: checking sys/times.h presence +configure:15869: g++ -E conftest.cpp +configure:15869: $? = 0 +configure:15869: result: yes +configure:15869: checking for sys/times.h +configure:15869: result: yes +configure:15869: checking for unistd.h +configure:15869: result: yes +configure:15880: checking for an ANSI C-conforming const +configure:15945: g++ -c -g -O2 conftest.cpp >&5 +configure:15945: $? = 0 +configure:15952: result: yes +configure:15960: checking for inline +configure:15976: g++ -c -g -O2 conftest.cpp >&5 +configure:15976: $? = 0 +configure:15984: result: inline +configure:16002: checking for size_t +configure:16002: g++ -c -g -O2 conftest.cpp >&5 +configure:16002: $? = 0 +configure:16002: g++ -c -g -O2 conftest.cpp >&5 +conftest.cpp: In function 'int main()': +conftest.cpp:65:20: error: expected primary-expression before ')' token +configure:16002: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "LEMON" +| #define PACKAGE_TARNAME "lemon" +| #define PACKAGE_VERSION "1.2.3" +| #define PACKAGE_STRING "LEMON 1.2.3" +| #define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +| #define PACKAGE_URL "" +| #define PACKAGE "lemon" +| #define VERSION "1.2.3" +| #define LEMON_VERSION 1.2.3 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define LEMON_HAVE_LONG_LONG 1 +| #define HAVE_DLFCN_H 1 +| #define LT_OBJDIR ".libs/" +| #define HAVE_LIMITS_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_SYS_TIMES_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((size_t))) +| return 0; +| ; +| return 0; +| } +configure:16002: result: yes +configure:16013: checking whether time.h and sys/time.h may both be included +configure:16033: g++ -c -g -O2 conftest.cpp >&5 +configure:16033: $? = 0 +configure:16040: result: yes +configure:16048: checking whether struct tm is in sys/time.h or time.h +configure:16068: g++ -c -g -O2 conftest.cpp >&5 +configure:16068: $? = 0 +configure:16075: result: time.h +configure:16084: checking for ANSI C header files +configure:16188: result: yes +configure:16199: checking for gettimeofday +configure:16199: g++ -o conftest -g -O2 conftest.cpp >&5 +configure:16199: $? = 0 +configure:16199: result: yes +configure:16199: checking for times +configure:16199: g++ -o conftest -g -O2 conftest.cpp >&5 +configure:16199: $? = 0 +configure:16199: result: yes +configure:16199: checking for ctime_r +configure:16199: g++ -o conftest -g -O2 conftest.cpp >&5 +configure:16199: $? = 0 +configure:16199: result: yes +configure:16393: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by LEMON config.status 1.2.3, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on pc-4w14-0 + +config.status:1184: creating Makefile +config.status:1184: creating demo/Makefile +config.status:1184: creating cmake/version.cmake +config.status:1184: creating doc/Doxyfile +config.status:1184: creating doc/mainpage.dox +config.status:1184: creating lemon/lemon.pc +config.status:1184: creating config.h +config.status:1184: creating lemon/config.h +config.status:1413: executing depfiles commands +config.status:1413: executing libtool commands + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_build=x86_64-unknown-linux-gnu +ac_cv_c_compiler_gnu=yes +ac_cv_c_const=yes +ac_cv_c_inline=inline +ac_cv_cxx_compiler_gnu=yes +ac_cv_env_CCC_set= +ac_cv_env_CCC_value= +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CXXCPP_set= +ac_cv_env_CXXCPP_value= +ac_cv_env_CXXFLAGS_set= +ac_cv_env_CXXFLAGS_value= +ac_cv_env_CXX_set= +ac_cv_env_CXX_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_func_ctime_r=yes +ac_cv_func_gettimeofday=yes +ac_cv_func_times=yes +ac_cv_header_dlfcn_h=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_limits_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_stdc=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_time_h=yes +ac_cv_header_sys_times_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_time=yes +ac_cv_header_unistd_h=yes +ac_cv_host=x86_64-unknown-linux-gnu +ac_cv_objext=o +ac_cv_path_EGREP='/bin/grep -E' +ac_cv_path_FGREP='/bin/grep -F' +ac_cv_path_GREP=/bin/grep +ac_cv_path_SED=/bin/sed +ac_cv_path_install='/usr/bin/install -c' +ac_cv_path_mkdir=/bin/mkdir +ac_cv_prog_AWK=mawk +ac_cv_prog_CXXCPP='g++ -E' +ac_cv_prog_ac_ct_AR=ar +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_ac_ct_CXX=g++ +ac_cv_prog_ac_ct_OBJDUMP=objdump +ac_cv_prog_ac_ct_RANLIB=ranlib +ac_cv_prog_ac_ct_STRIP=strip +ac_cv_prog_cc_c89= +ac_cv_prog_cc_g=yes +ac_cv_prog_cxx_g=yes +ac_cv_prog_doxygen_found=no +ac_cv_prog_gs_found=yes +ac_cv_prog_make_make_set=yes +ac_cv_prog_python_found=yes +ac_cv_struct_tm=time.h +ac_cv_type_long_long=yes +ac_cv_type_size_t=yes +am_cv_CC_dependencies_compiler_type=gcc3 +am_cv_CXX_dependencies_compiler_type=gcc3 +lt_cv_deplibs_check_method=pass_all +lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_ld_reload_flag=-r +lt_cv_nm_interface='BSD nm' +lt_cv_objdir=.libs +lt_cv_path_LD=/usr/bin/ld +lt_cv_path_LDCXX='/usr/bin/ld -m elf_x86_64' +lt_cv_path_NM='/usr/bin/nm -B' +lt_cv_prog_compiler_c_o=yes +lt_cv_prog_compiler_c_o_CXX=yes +lt_cv_prog_compiler_pic_works=yes +lt_cv_prog_compiler_pic_works_CXX=yes +lt_cv_prog_compiler_rtti_exceptions=no +lt_cv_prog_compiler_static_works=yes +lt_cv_prog_compiler_static_works_CXX=yes +lt_cv_prog_gnu_ld=yes +lt_cv_prog_gnu_ldcxx=yes +lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\''' +lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"\2", (void *) \&\2},/p'\''' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \(lib[^ ]*\)$/ {"\2", (void *) \&\2},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"lib\2", (void *) \&\2},/p'\''' +lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^T .* \(.*\)$/extern int \1();/p'\'' -e '\''s/^[ABCDGIRSTW]* .* \(.*\)$/extern char \1;/p'\''' +lt_cv_sys_max_cmd_len=1572864 + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +ACLOCAL='${SHELL} /home/carlo/honours/lemon/build-aux/missing --run aclocal-1.11' +AMDEPBACKSLASH='\' +AMDEP_FALSE='#' +AMDEP_TRUE='' +AMTAR='${SHELL} /home/carlo/honours/lemon/build-aux/missing --run tar' +AR='ar' +AUTOCONF='${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoconf' +AUTOHEADER='${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoheader' +AUTOMAKE='${SHELL} /home/carlo/honours/lemon/build-aux/missing --run automake-1.11' +AWK='mawk' +CBC_CXXFLAGS='' +CBC_LIBS=' ' +CC='gcc' +CCDEPMODE='depmode=gcc3' +CFLAGS='-g -O2' +CLP_CXXFLAGS='' +CLP_LIBS=' ' +CONFIG_STATUS_DEPENDENCIES='$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in' +CPLEX_CFLAGS='' +CPLEX_LIBS=' ' +CPPFLAGS='' +CXX='g++' +CXXCPP='g++ -E' +CXXDEPMODE='depmode=gcc3' +CXXFLAGS='-g -O2' +CYGPATH_W='echo' +DEFS='-DHAVE_CONFIG_H' +DEPDIR='.deps' +DSYMUTIL='' +DUMPBIN='' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='/bin/grep -E' +EXEEXT='' +FGREP='/bin/grep -F' +GLPK_CFLAGS='' +GLPK_LIBS=' ' +GREP='/bin/grep' +HAVE_CBC_FALSE='' +HAVE_CBC_TRUE='#' +HAVE_CLP_FALSE='' +HAVE_CLP_TRUE='#' +HAVE_CPLEX_FALSE='' +HAVE_CPLEX_TRUE='#' +HAVE_GLPK_FALSE='' +HAVE_GLPK_TRUE='#' +HAVE_LP_FALSE='' +HAVE_LP_TRUE='#' +HAVE_MIP_FALSE='' +HAVE_MIP_TRUE='#' +HAVE_SOPLEX_FALSE='' +HAVE_SOPLEX_TRUE='#' +HAVE_VALGRIND='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +INSTALL_STRIP_PROGRAM='$(install_sh) -c -s' +LD='/usr/bin/ld -m elf_x86_64' +LDFLAGS='' +LIBOBJS='' +LIBS='' +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +LIPO='' +LN_S='ln -s' +LTLIBOBJS='' +MAKEINFO='${SHELL} /home/carlo/honours/lemon/build-aux/missing --run makeinfo' +MKDIR_P='/bin/mkdir -p' +NM='/usr/bin/nm -B' +NMEDIT='' +OBJDUMP='objdump' +OBJEXT='o' +OTOOL64='' +OTOOL='' +PACKAGE='lemon' +PACKAGE_BUGREPORT='lemon-user@lemon.cs.elte.hu' +PACKAGE_NAME='LEMON' +PACKAGE_STRING='LEMON 1.2.3' +PACKAGE_TARNAME='lemon' +PACKAGE_URL='' +PACKAGE_VERSION='1.2.3' +PATH_SEPARATOR=':' +RANLIB='ranlib' +SED='/bin/sed' +SET_MAKE='' +SHELL='/bin/bash' +SOPLEX_CXXFLAGS='' +SOPLEX_LIBS=' ' +STRIP='strip' +USE_VALGRIND_FALSE='' +USE_VALGRIND_TRUE='#' +VERSION='1.2.3' +WANT_TOOLS_FALSE='#' +WANT_TOOLS_TRUE='' +WARNINGCXXFLAGS='-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas' +ac_ct_CC='gcc' +ac_ct_CXX='g++' +ac_ct_DUMPBIN='' +am__EXEEXT_FALSE='' +am__EXEEXT_TRUE='#' +am__fastdepCC_FALSE='#' +am__fastdepCC_TRUE='' +am__fastdepCXX_FALSE='#' +am__fastdepCXX_TRUE='' +am__include='include' +am__isrc='' +am__leading_dot='.' +am__quote='' +am__tar='${AMTAR} chof - "$$tardir"' +am__untar='${AMTAR} xf -' +bindir='${exec_prefix}/bin' +build='x86_64-unknown-linux-gnu' +build_alias='' +build_cpu='x86_64' +build_os='linux-gnu' +build_vendor='unknown' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +doxygen_found='no' +dvidir='${docdir}' +exec_prefix='${prefix}' +gs_found='yes' +host='x86_64-unknown-linux-gnu' +host_alias='' +host_cpu='x86_64' +host_os='linux-gnu' +host_vendor='unknown' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +install_sh='${SHELL} /home/carlo/honours/lemon/build-aux/install-sh' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +lt_ECHO='echo' +mandir='${datarootdir}/man' +mkdir_p='/bin/mkdir -p' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +python_found='yes' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +/* confdefs.h */ +#define PACKAGE_NAME "LEMON" +#define PACKAGE_TARNAME "lemon" +#define PACKAGE_VERSION "1.2.3" +#define PACKAGE_STRING "LEMON 1.2.3" +#define PACKAGE_BUGREPORT "lemon-user@lemon.cs.elte.hu" +#define PACKAGE_URL "" +#define PACKAGE "lemon" +#define VERSION "1.2.3" +#define LEMON_VERSION 1.2.3 +#define STDC_HEADERS 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define LEMON_HAVE_LONG_LONG 1 +#define HAVE_DLFCN_H 1 +#define LT_OBJDIR ".libs/" +#define HAVE_LIMITS_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TIMES_H 1 +#define HAVE_UNISTD_H 1 +#define TIME_WITH_SYS_TIME 1 +#define STDC_HEADERS 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_TIMES 1 +#define HAVE_CTIME_R 1 + +configure: exit 0 diff --git a/lemon/config.status b/lemon/config.status new file mode 100755 index 0000000..54a23a3 --- /dev/null +++ b/lemon/config.status @@ -0,0 +1,2321 @@ +#! /bin/bash +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=${CONFIG_SHELL-/bin/bash} +export SHELL +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by LEMON $as_me 1.2.3, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +# Files that config.status was made for. +config_files=" Makefile demo/Makefile cmake/version.cmake doc/Doxyfile doc/mainpage.dox lemon/lemon.pc" +config_headers=" config.h lemon/config.h" +config_commands=" depfiles libtool" + +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +ac_cs_config="" +ac_cs_version="\ +LEMON config.status 1.2.3 +configured by ./configure, generated by GNU Autoconf 2.68, + with options \"$ac_cs_config\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='/home/carlo/honours/lemon' +srcdir='.' +INSTALL='/usr/bin/install -c' +MKDIR_P='/bin/mkdir -p' +AWK='mawk' +test -n "$AWK" || AWK=awk +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + set X '/bin/bash' './configure' $ac_configure_extra_args --no-create --no-recursion + shift + $as_echo "running CONFIG_SHELL=/bin/bash $*" >&6 + CONFIG_SHELL='/bin/bash' + export CONFIG_SHELL + exec "$@" +fi + +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +# +# INIT-COMMANDS +# +AMDEP_TRUE="" ac_aux_dir="build-aux" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +double_quote_subst='s/\(["`\\]\)/\\\1/g' +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' +enable_shared='no' +macro_version='2.2.6b' +macro_revision='1.3018' +enable_static='yes' +pic_mode='default' +enable_fast_install='needless' +host_alias='' +host='x86_64-unknown-linux-gnu' +host_os='linux-gnu' +build_alias='' +build='x86_64-unknown-linux-gnu' +build_os='linux-gnu' +SED='/bin/sed' +Xsed='/bin/sed -e 1s/^X//' +GREP='/bin/grep' +EGREP='/bin/grep -E' +FGREP='/bin/grep -F' +LD='/usr/bin/ld -m elf_x86_64' +NM='/usr/bin/nm -B' +LN_S='ln -s' +max_cmd_len='1572864' +ac_objext='o' +exeext='' +lt_unset='unset' +lt_SP2NL='tr \040 \012' +lt_NL2SP='tr \015\012 \040\040' +reload_flag=' -r' +reload_cmds='$LD$reload_flag -o $output$reload_objs' +OBJDUMP='objdump' +deplibs_check_method='pass_all' +file_magic_cmd='$MAGIC_CMD' +AR='ar' +AR_FLAGS='cru' +STRIP='strip' +RANLIB='ranlib' +old_postinstall_cmds='chmod 644 $oldlib~$RANLIB $oldlib' +old_postuninstall_cmds='' +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs~$RANLIB $oldlib' +CC='gcc' +CFLAGS='-g -O2' +compiler='g++' +GCC='yes' +lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\''' +lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^T .* \(.*\)$/extern int \1();/p'\'' -e '\''s/^[ABCDGIRSTW]* .* \(.*\)$/extern char \1;/p'\''' +lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"\2", (void *) \&\2},/p'\''' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (void *) 0},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \(lib[^ ]*\)$/ {"\2", (void *) \&\2},/p'\'' -e '\''s/^[ABCDGIRSTW]* \([^ ]*\) \([^ ]*\)$/ {"lib\2", (void *) \&\2},/p'\''' +objdir='.libs' +SHELL='/bin/bash' +ECHO='echo' +MAGIC_CMD='file' +lt_prog_compiler_no_builtin_flag=' -fno-builtin' +lt_prog_compiler_wl='-Wl,' +lt_prog_compiler_pic=' -fPIC -DPIC' +lt_prog_compiler_static='-static' +lt_cv_prog_compiler_c_o='yes' +need_locks='no' +DSYMUTIL='' +NMEDIT='' +LIPO='' +OTOOL='' +OTOOL64='' +libext='a' +shrext_cmds='.so' +extract_expsyms_cmds='' +archive_cmds_need_lc='yes' +enable_shared_with_static_runtimes='no' +export_dynamic_flag_spec='${wl}--export-dynamic' +whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +compiler_needs_object='no' +old_archive_from_new_cmds='' +old_archive_from_expsyms_cmds='' +archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' +archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' +module_cmds='' +module_expsym_cmds='' +with_gnu_ld='yes' +allow_undefined_flag='' +no_undefined_flag='' +hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +hardcode_libdir_flag_spec_ld='' +hardcode_libdir_separator='' +hardcode_direct='no' +hardcode_direct_absolute='no' +hardcode_minus_L='no' +hardcode_shlibpath_var='unsupported' +hardcode_automatic='no' +inherit_rpath='no' +link_all_deplibs='unknown' +fix_srcfile_path='' +always_export_symbols='no' +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' +exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' +include_expsyms='' +prelink_cmds='' +file_list_spec='' +variables_saved_for_relink='PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH' +need_lib_prefix='no' +need_version='no' +version_type='linux' +runpath_var='LD_RUN_PATH' +shlibpath_var='LD_LIBRARY_PATH' +shlibpath_overrides_runpath='no' +libname_spec='lib$name' +library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' +soname_spec='${libname}${release}${shared_ext}$major' +postinstall_cmds='' +postuninstall_cmds='' +finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' +finish_eval='' +hardcode_into_libs='yes' +sys_lib_search_path_spec='/usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib' +sys_lib_dlsearch_path_spec='/lib /usr/lib /usr/local/lib /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu /lib32 /usr/lib32 ' +hardcode_action='immediate' +enable_dlopen='unknown' +enable_dlopen_self='unknown' +enable_dlopen_self_static='unknown' +old_striplib='strip --strip-debug' +striplib='strip --strip-unneeded' +compiler_lib_search_dirs='' +predep_objects='' +postdep_objects='' +predeps='' +postdeps='' +compiler_lib_search_path='' +LD_CXX='/usr/bin/ld -m elf_x86_64' +old_archive_cmds_CXX='$AR $AR_FLAGS $oldlib$oldobjs~$RANLIB $oldlib' +compiler_CXX='g++' +GCC_CXX='yes' +lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' +lt_prog_compiler_wl_CXX='-Wl,' +lt_prog_compiler_pic_CXX=' -fPIC -DPIC' +lt_prog_compiler_static_CXX='-static' +lt_cv_prog_compiler_c_o_CXX='yes' +archive_cmds_need_lc_CXX='no' +enable_shared_with_static_runtimes_CXX='no' +export_dynamic_flag_spec_CXX='${wl}--export-dynamic' +whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' +compiler_needs_object_CXX='no' +old_archive_from_new_cmds_CXX='' +old_archive_from_expsyms_cmds_CXX='' +archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' +archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' +module_cmds_CXX='' +module_expsym_cmds_CXX='' +with_gnu_ld_CXX='yes' +allow_undefined_flag_CXX='' +no_undefined_flag_CXX='' +hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' +hardcode_libdir_flag_spec_ld_CXX='' +hardcode_libdir_separator_CXX='' +hardcode_direct_CXX='no' +hardcode_direct_absolute_CXX='no' +hardcode_minus_L_CXX='no' +hardcode_shlibpath_var_CXX='unsupported' +hardcode_automatic_CXX='no' +inherit_rpath_CXX='no' +link_all_deplibs_CXX='unknown' +fix_srcfile_path_CXX='' +always_export_symbols_CXX='no' +export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' +exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' +include_expsyms_CXX='' +prelink_cmds_CXX='' +file_list_spec_CXX='' +hardcode_action_CXX='immediate' +compiler_lib_search_dirs_CXX='/usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /usr/lib/gcc/x86_64-linux-gnu/4.7/../../..' +predep_objects_CXX='/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o' +postdep_objects_CXX='/usr/lib/gcc/x86_64-linux-gnu/4.7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o' +predeps_CXX='' +postdeps_CXX='-lstdc++ -lm -lgcc_s -lc -lgcc_s' +compiler_lib_search_path_CXX='-L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../..' + +LTCC='gcc' +LTCFLAGS='-g -O2' +compiler='gcc' + +# Quote evaled strings. +for var in SED GREP EGREP FGREP LD NM LN_S lt_SP2NL lt_NL2SP reload_flag OBJDUMP deplibs_check_method file_magic_cmd AR AR_FLAGS STRIP RANLIB CC CFLAGS compiler lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl lt_cv_sys_global_symbol_to_c_name_address lt_cv_sys_global_symbol_to_c_name_address_lib_prefix SHELL ECHO lt_prog_compiler_no_builtin_flag lt_prog_compiler_wl lt_prog_compiler_pic lt_prog_compiler_static lt_cv_prog_compiler_c_o need_locks DSYMUTIL NMEDIT LIPO OTOOL OTOOL64 shrext_cmds export_dynamic_flag_spec whole_archive_flag_spec compiler_needs_object with_gnu_ld allow_undefined_flag no_undefined_flag hardcode_libdir_flag_spec hardcode_libdir_flag_spec_ld hardcode_libdir_separator fix_srcfile_path exclude_expsyms include_expsyms file_list_spec variables_saved_for_relink libname_spec library_names_spec soname_spec finish_eval old_striplib striplib compiler_lib_search_dirs predep_objects postdep_objects predeps postdeps compiler_lib_search_path LD_CXX compiler_CXX lt_prog_compiler_no_builtin_flag_CXX lt_prog_compiler_wl_CXX lt_prog_compiler_pic_CXX lt_prog_compiler_static_CXX lt_cv_prog_compiler_c_o_CXX export_dynamic_flag_spec_CXX whole_archive_flag_spec_CXX compiler_needs_object_CXX with_gnu_ld_CXX allow_undefined_flag_CXX no_undefined_flag_CXX hardcode_libdir_flag_spec_CXX hardcode_libdir_flag_spec_ld_CXX hardcode_libdir_separator_CXX fix_srcfile_path_CXX exclude_expsyms_CXX include_expsyms_CXX file_list_spec_CXX compiler_lib_search_dirs_CXX predep_objects_CXX postdep_objects_CXX predeps_CXX postdeps_CXX compiler_lib_search_path_CXX; do + case `eval \\$ECHO "X\\$$var"` in + *[\\\`\"\$]*) + eval "lt_$var=\\\"\`\$ECHO \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\$$var\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds old_postinstall_cmds old_postuninstall_cmds old_archive_cmds extract_expsyms_cmds old_archive_from_new_cmds old_archive_from_expsyms_cmds archive_cmds archive_expsym_cmds module_cmds module_expsym_cmds export_symbols_cmds prelink_cmds postinstall_cmds postuninstall_cmds finish_cmds sys_lib_search_path_spec sys_lib_dlsearch_path_spec old_archive_cmds_CXX old_archive_from_new_cmds_CXX old_archive_from_expsyms_cmds_CXX archive_cmds_CXX archive_expsym_cmds_CXX module_cmds_CXX module_expsym_cmds_CXX export_symbols_cmds_CXX prelink_cmds_CXX; do + case `eval \\$ECHO "X\\$$var"` in + *[\\\`\"\$]*) + eval "lt_$var=\\\"\`\$ECHO \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\$$var\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case $lt_ECHO in +*'\$0 --fallback-echo"') lt_ECHO=`$ECHO "X$lt_ECHO" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; +esac + +ac_aux_dir='build-aux' +xsi_shell='yes' +lt_shell_append='yes' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='lemon' + VERSION='1.2.3' + TIMESTAMP='' + RM='rm -f' + ofile='libtool' + + + + + + + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "lemon/config.h") CONFIG_HEADERS="$CONFIG_HEADERS lemon/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "demo/Makefile") CONFIG_FILES="$CONFIG_FILES demo/Makefile" ;; + "cmake/version.cmake") CONFIG_FILES="$CONFIG_FILES cmake/version.cmake" ;; + "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; + "doc/mainpage.dox") CONFIG_FILES="$CONFIG_FILES doc/mainpage.dox" ;; + "lemon/lemon.pc") CONFIG_FILES="$CONFIG_FILES lemon/lemon.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +cat >>"$ac_tmp/subs1.awk" <<\_ACAWK && +S["am__EXEEXT_FALSE"]="" +S["am__EXEEXT_TRUE"]="#" +S["LTLIBOBJS"]="" +S["LIBOBJS"]="" +S["CONFIG_STATUS_DEPENDENCIES"]="$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in" +S["USE_VALGRIND_FALSE"]="" +S["USE_VALGRIND_TRUE"]="#" +S["HAVE_VALGRIND"]="" +S["WANT_TOOLS_FALSE"]="#" +S["WANT_TOOLS_TRUE"]="" +S["HAVE_MIP_FALSE"]="" +S["HAVE_MIP_TRUE"]="#" +S["HAVE_LP_FALSE"]="" +S["HAVE_LP_TRUE"]="#" +S["HAVE_CBC_FALSE"]="" +S["HAVE_CBC_TRUE"]="#" +S["CBC_LIBS"]=" " +S["CBC_CXXFLAGS"]="" +S["HAVE_CLP_FALSE"]="" +S["HAVE_CLP_TRUE"]="#" +S["CLP_LIBS"]=" " +S["CLP_CXXFLAGS"]="" +S["HAVE_SOPLEX_FALSE"]="" +S["HAVE_SOPLEX_TRUE"]="#" +S["SOPLEX_LIBS"]=" " +S["SOPLEX_CXXFLAGS"]="" +S["HAVE_CPLEX_FALSE"]="" +S["HAVE_CPLEX_TRUE"]="#" +S["CPLEX_LIBS"]=" " +S["CPLEX_CFLAGS"]="" +S["HAVE_GLPK_FALSE"]="" +S["HAVE_GLPK_TRUE"]="#" +S["GLPK_LIBS"]=" " +S["GLPK_CFLAGS"]="" +S["WARNINGCXXFLAGS"]="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type"\ +" -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas" +S["gs_found"]="yes" +S["python_found"]="yes" +S["doxygen_found"]="no" +S["OTOOL64"]="" +S["OTOOL"]="" +S["LIPO"]="" +S["NMEDIT"]="" +S["DSYMUTIL"]="" +S["lt_ECHO"]="echo" +S["RANLIB"]="ranlib" +S["AR"]="ar" +S["OBJDUMP"]="objdump" +S["LN_S"]="ln -s" +S["NM"]="/usr/bin/nm -B" +S["ac_ct_DUMPBIN"]="" +S["DUMPBIN"]="" +S["LD"]="/usr/bin/ld -m elf_x86_64" +S["FGREP"]="/bin/grep -F" +S["SED"]="/bin/sed" +S["am__fastdepCC_FALSE"]="#" +S["am__fastdepCC_TRUE"]="" +S["CCDEPMODE"]="depmode=gcc3" +S["ac_ct_CC"]="gcc" +S["CFLAGS"]="-g -O2" +S["CC"]="gcc" +S["host_os"]="linux-gnu" +S["host_vendor"]="unknown" +S["host_cpu"]="x86_64" +S["host"]="x86_64-unknown-linux-gnu" +S["build_os"]="linux-gnu" +S["build_vendor"]="unknown" +S["build_cpu"]="x86_64" +S["build"]="x86_64-unknown-linux-gnu" +S["LIBTOOL"]="$(SHELL) $(top_builddir)/libtool" +S["EGREP"]="/bin/grep -E" +S["GREP"]="/bin/grep" +S["CXXCPP"]="g++ -E" +S["am__fastdepCXX_FALSE"]="#" +S["am__fastdepCXX_TRUE"]="" +S["CXXDEPMODE"]="depmode=gcc3" +S["AMDEPBACKSLASH"]="\\" +S["AMDEP_FALSE"]="#" +S["AMDEP_TRUE"]="" +S["am__quote"]="" +S["am__include"]="include" +S["DEPDIR"]=".deps" +S["OBJEXT"]="o" +S["EXEEXT"]="" +S["ac_ct_CXX"]="g++" +S["CPPFLAGS"]="" +S["LDFLAGS"]="" +S["CXXFLAGS"]="-g -O2" +S["CXX"]="g++" +S["am__untar"]="${AMTAR} xf -" +S["am__tar"]="${AMTAR} chof - \"$$tardir\"" +S["AMTAR"]="${SHELL} /home/carlo/honours/lemon/build-aux/missing --run tar" +S["am__leading_dot"]="." +S["SET_MAKE"]="" +S["AWK"]="mawk" +S["mkdir_p"]="/bin/mkdir -p" +S["MKDIR_P"]="/bin/mkdir -p" +S["INSTALL_STRIP_PROGRAM"]="$(install_sh) -c -s" +S["STRIP"]="strip" +S["install_sh"]="${SHELL} /home/carlo/honours/lemon/build-aux/install-sh" +S["MAKEINFO"]="${SHELL} /home/carlo/honours/lemon/build-aux/missing --run makeinfo" +S["AUTOHEADER"]="${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoheader" +S["AUTOMAKE"]="${SHELL} /home/carlo/honours/lemon/build-aux/missing --run automake-1.11" +S["AUTOCONF"]="${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoconf" +S["ACLOCAL"]="${SHELL} /home/carlo/honours/lemon/build-aux/missing --run aclocal-1.11" +S["VERSION"]="1.2.3" +S["PACKAGE"]="lemon" +S["CYGPATH_W"]="echo" +S["am__isrc"]="" +S["INSTALL_DATA"]="${INSTALL} -m 644" +S["INSTALL_SCRIPT"]="${INSTALL}" +S["INSTALL_PROGRAM"]="${INSTALL}" +S["target_alias"]="" +S["host_alias"]="" +S["build_alias"]="" +S["LIBS"]="" +S["ECHO_T"]="" +S["ECHO_N"]="-n" +S["ECHO_C"]="" +S["DEFS"]="-DHAVE_CONFIG_H" +S["mandir"]="${datarootdir}/man" +S["localedir"]="${datarootdir}/locale" +S["libdir"]="${exec_prefix}/lib" +S["psdir"]="${docdir}" +S["pdfdir"]="${docdir}" +S["dvidir"]="${docdir}" +S["htmldir"]="${docdir}" +S["infodir"]="${datarootdir}/info" +S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}" +S["oldincludedir"]="/usr/include" +S["includedir"]="${prefix}/include" +S["localstatedir"]="${prefix}/var" +S["sharedstatedir"]="${prefix}/com" +S["sysconfdir"]="${prefix}/etc" +S["datadir"]="${datarootdir}" +S["datarootdir"]="${prefix}/share" +S["libexecdir"]="${exec_prefix}/libexec" +S["sbindir"]="${exec_prefix}/sbin" +S["bindir"]="${exec_prefix}/bin" +S["program_transform_name"]="s,x,x," +S["prefix"]="/usr/local" +S["exec_prefix"]="${prefix}" +S["PACKAGE_URL"]="" +S["PACKAGE_BUGREPORT"]="lemon-user@lemon.cs.elte.hu" +S["PACKAGE_STRING"]="LEMON 1.2.3" +S["PACKAGE_VERSION"]="1.2.3" +S["PACKAGE_TARNAME"]="lemon" +S["PACKAGE_NAME"]="LEMON" +S["PATH_SEPARATOR"]=":" +S["SHELL"]="/bin/bash" +_ACAWK +cat >>"$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +D["PACKAGE_NAME"]=" \"LEMON\"" +D["PACKAGE_TARNAME"]=" \"lemon\"" +D["PACKAGE_VERSION"]=" \"1.2.3\"" +D["PACKAGE_STRING"]=" \"LEMON 1.2.3\"" +D["PACKAGE_BUGREPORT"]=" \"lemon-user@lemon.cs.elte.hu\"" +D["PACKAGE_URL"]=" \"\"" +D["PACKAGE"]=" \"lemon\"" +D["VERSION"]=" \"1.2.3\"" +D["LEMON_VERSION"]=" 1.2.3" +D["STDC_HEADERS"]=" 1" +D["HAVE_SYS_TYPES_H"]=" 1" +D["HAVE_SYS_STAT_H"]=" 1" +D["HAVE_STDLIB_H"]=" 1" +D["HAVE_STRING_H"]=" 1" +D["HAVE_MEMORY_H"]=" 1" +D["HAVE_STRINGS_H"]=" 1" +D["HAVE_INTTYPES_H"]=" 1" +D["HAVE_STDINT_H"]=" 1" +D["HAVE_UNISTD_H"]=" 1" +D["LEMON_HAVE_LONG_LONG"]=" 1" +D["HAVE_DLFCN_H"]=" 1" +D["LT_OBJDIR"]=" \".libs/\"" +D["HAVE_LIMITS_H"]=" 1" +D["HAVE_SYS_TIME_H"]=" 1" +D["HAVE_SYS_TIMES_H"]=" 1" +D["HAVE_UNISTD_H"]=" 1" +D["TIME_WITH_SYS_TIME"]=" 1" +D["STDC_HEADERS"]=" 1" +D["HAVE_GETTIMEOFDAY"]=" 1" +D["HAVE_TIMES"]=" 1" +D["HAVE_CTIME_R"]=" 1" + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ { + line = $ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + ac_datarootdir_hack=' + s&@datadir@&${datarootdir}&g + s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g + s&@infodir@&${datarootdir}/info&g + s&@localedir@&${datarootdir}/locale&g + s&@mandir@&${datarootdir}/man&g + s&\${datarootdir}&${prefix}/share&g' ;; +esac +ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that does not interpret backslashes. +ECHO=$lt_ECHO + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 diff --git a/lemon/configure b/lemon/configure new file mode 100755 index 0000000..d339153 --- /dev/null +++ b/lemon/configure @@ -0,0 +1,18910 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for LEMON 1.2.3. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: lemon-user@lemon.cs.elte.hu about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +$* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='LEMON' +PACKAGE_TARNAME='lemon' +PACKAGE_VERSION='1.2.3' +PACKAGE_STRING='LEMON 1.2.3' +PACKAGE_BUGREPORT='lemon-user@lemon.cs.elte.hu' +PACKAGE_URL='' + +ac_unique_file="lemon/list_graph.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +CONFIG_STATUS_DEPENDENCIES +USE_VALGRIND_FALSE +USE_VALGRIND_TRUE +HAVE_VALGRIND +WANT_TOOLS_FALSE +WANT_TOOLS_TRUE +HAVE_MIP_FALSE +HAVE_MIP_TRUE +HAVE_LP_FALSE +HAVE_LP_TRUE +HAVE_CBC_FALSE +HAVE_CBC_TRUE +CBC_LIBS +CBC_CXXFLAGS +HAVE_CLP_FALSE +HAVE_CLP_TRUE +CLP_LIBS +CLP_CXXFLAGS +HAVE_SOPLEX_FALSE +HAVE_SOPLEX_TRUE +SOPLEX_LIBS +SOPLEX_CXXFLAGS +HAVE_CPLEX_FALSE +HAVE_CPLEX_TRUE +CPLEX_LIBS +CPLEX_CFLAGS +HAVE_GLPK_FALSE +HAVE_GLPK_TRUE +GLPK_LIBS +GLPK_CFLAGS +WARNINGCXXFLAGS +gs_found +python_found +doxygen_found +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +lt_ECHO +RANLIB +AR +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +EGREP +GREP +CXXCPP +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock +with_glpk +with_glpk_includedir +with_glpk_libdir +with_cplex +with_cplex_includedir +with_cplex_libdir +with_soplex +with_soplex_includedir +with_soplex_libdir +with_coin +with_coin_includedir +with_coin_libdir +enable_tools +enable_valgrind +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CXXCPP +CC +CFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures LEMON 1.2.3 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/lemon] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of LEMON 1.2.3:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=no] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-tools build additional tools [default] + --disable-tools do not build additional tools + --enable-valgrind use valgrind when running tests + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-glpk[=PREFIX] search for GLPK under PREFIX or under the default + search paths if PREFIX is not given [default] + --without-glpk disable checking for GLPK + --with-glpk-includedir=DIR + search for GLPK headers in DIR + --with-glpk-libdir=DIR search for GLPK libraries in DIR + --with-cplex[=PREFIX] search for CPLEX under PREFIX or under the default + search paths if PREFIX is not given [default] + --without-cplex disable checking for CPLEX + --with-cplex-includedir=DIR + search for CPLEX headers in DIR + --with-cplex-libdir=DIR search for CPLEX libraries in DIR + --with-soplex[=PREFIX] search for SOPLEX under PREFIX or under the default + search paths if PREFIX is not given [default] + --without-soplex disable checking for SOPLEX + --with-soplex-includedir=DIR + search for SOPLEX headers in DIR + --with-soplex-libdir=DIR + search for SOPLEX libraries in DIR + --with-coin[=PREFIX] search for CLP under PREFIX or under the default + search paths if PREFIX is not given [default] + --without-coin disable checking for CLP + --with-coin-includedir=DIR + search for CLP headers in DIR + --with-coin-libdir=DIR search for CLP libraries in DIR + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXXCPP C++ preprocessor + CC C compiler command + CFLAGS C compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +LEMON configure 1.2.3 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES +# --------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_cxx_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_type + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_run LINENO +# ------------------------ +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_cxx_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_run + +# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_cxx_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_compile + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------------ ## +## Report this to lemon-user@lemon.cs.elte.hu ## +## ------------------------------------------ ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel + +# ac_fn_cxx_check_func LINENO FUNC VAR +# ------------------------------------ +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_cxx_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by LEMON $as_me 1.2.3, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_aux_dir= +for ac_dir in build-aux "$srcdir"/build-aux; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='lemon' + VERSION='1.2.3' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + + +ac_config_headers="$ac_config_headers config.h lemon/config.h" + + + +$as_echo "#define LEMON_VERSION 1.2.3" >>confdefs.h + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_cxx_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" +if test "x$ac_cv_type_long_long" = xyes; then : + long_long_found=yes +else + long_long_found=no +fi + +if test x"$long_long_found" = x"yes"; then + +$as_echo "#define LEMON_HAVE_LONG_LONG 1" >>confdefs.h + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=no +fi + + + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.6b' +macro_revision='1.3018' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$ac_tool_prefix"; then + for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in "dumpbin -symbols" "link -dump -symbols" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:6026: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:6029: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:6032: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 7238 "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +_lt_caught_CXX_error=yes; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + + + + + + + + + + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8996: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:9000: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:9335: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:9339: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:9440: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:9444: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:9495: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:9499: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 +$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 11863 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 11959 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC="$lt_save_CC" + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5]* | *pgcpp\ [1-5]*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_prog_compiler_pic_CXX" >&6; } + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:13915: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:13919: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14014: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14018: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14066: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14070: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_CXX" >&5 +$as_echo "$archive_cmds_need_lc_CXX" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +# Extract the first word of "doxygen", so it can be a program name with args. +set dummy doxygen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_doxygen_found+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$doxygen_found"; then + ac_cv_prog_doxygen_found="$doxygen_found" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_doxygen_found="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_doxygen_found" && ac_cv_prog_doxygen_found="no" +fi +fi +doxygen_found=$ac_cv_prog_doxygen_found +if test -n "$doxygen_found"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doxygen_found" >&5 +$as_echo "$doxygen_found" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "python", so it can be a program name with args. +set dummy python; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_python_found+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$python_found"; then + ac_cv_prog_python_found="$python_found" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_python_found="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_python_found" && ac_cv_prog_python_found="no" +fi +fi +python_found=$ac_cv_prog_python_found +if test -n "$python_found"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $python_found" >&5 +$as_echo "$python_found" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "gs", so it can be a program name with args. +set dummy gs; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_gs_found+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$gs_found"; then + ac_cv_prog_gs_found="$gs_found" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_gs_found="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_gs_found" && ac_cv_prog_gs_found="no" +fi +fi +gs_found=$ac_cv_prog_gs_found +if test -n "$gs_found"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gs_found" >&5 +$as_echo "$gs_found" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the Intel C++ compiler" >&5 +$as_echo_n "checking whether we are using the Intel C++ compiler... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __INTEL_COMPILER +choke me +#endif +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ICC=yes +else + ICC=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if test x"$ICC" = x"yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +if test "$GXX" = yes -a "$ICC" = no; then + WARNINGCXXFLAGS="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas" +fi + + + + +# Check whether --with-glpk was given. +if test "${with_glpk+set}" = set; then : + withval=$with_glpk; +else + with_glpk=yes +fi + + + +# Check whether --with-glpk-includedir was given. +if test "${with_glpk_includedir+set}" = set; then : + withval=$with_glpk_includedir; +else + with_glpk_includedir=no +fi + + + +# Check whether --with-glpk-libdir was given. +if test "${with_glpk_libdir+set}" = set; then : + withval=$with_glpk_libdir; +else + with_glpk_libdir=no +fi + + + lx_glpk_found=no + if test x"$with_glpk" != x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLPK" >&5 +$as_echo_n "checking for GLPK... " >&6; } + + if test x"$with_glpk_includedir" != x"no"; then + GLPK_CFLAGS="-I$with_glpk_includedir" + elif test x"$with_glpk" != x"yes"; then + GLPK_CFLAGS="-I$with_glpk/include" + fi + + if test x"$with_glpk_libdir" != x"no"; then + GLPK_LDFLAGS="-L$with_glpk_libdir" + elif test x"$with_glpk" != x"yes"; then + GLPK_LDFLAGS="-L$with_glpk/lib" + fi + GLPK_LIBS="-lglpk" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$GLPK_CFLAGS" + LDFLAGS="$GLPK_LDFLAGS" + LIBS="$GLPK_LIBS" + + lx_glpk_test_prog=' + extern "C" { + #include + } + + #if (GLP_MAJOR_VERSION < 4) \ + || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33) + #error Supported GLPK versions: 4.33 or above + #endif + + int main(int argc, char** argv) + { + LPX *lp; + lp = lpx_create_prob(); + lpx_delete_prob(lp); + return 0; + }' + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$lx_glpk_test_prog +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + lx_glpk_found=yes +else + lx_glpk_found=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_glpk_found" = x"yes"; then + +$as_echo "#define LEMON_HAVE_GLPK 1" >>confdefs.h + + lx_lp_found=yes + +$as_echo "#define LEMON_HAVE_LP 1" >>confdefs.h + + lx_mip_found=yes + +$as_echo "#define LEMON_HAVE_MIP 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + GLPK_CFLAGS="" + GLPK_LDFLAGS="" + GLPK_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + GLPK_LIBS="$GLPK_LDFLAGS $GLPK_LIBS" + + + if test x"$lx_glpk_found" = x"yes"; then + HAVE_GLPK_TRUE= + HAVE_GLPK_FALSE='#' +else + HAVE_GLPK_TRUE='#' + HAVE_GLPK_FALSE= +fi + + + + +# Check whether --with-cplex was given. +if test "${with_cplex+set}" = set; then : + withval=$with_cplex; +else + with_cplex=yes +fi + + + +# Check whether --with-cplex-includedir was given. +if test "${with_cplex_includedir+set}" = set; then : + withval=$with_cplex_includedir; +else + with_cplex_includedir=no +fi + + + +# Check whether --with-cplex-libdir was given. +if test "${with_cplex_libdir+set}" = set; then : + withval=$with_cplex_libdir; +else + with_cplex_libdir=no +fi + + + lx_cplex_found=no + if test x"$with_cplex" != x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CPLEX" >&5 +$as_echo_n "checking for CPLEX... " >&6; } + + if test x"$with_cplex_includedir" != x"no"; then + CPLEX_CFLAGS="-I$with_cplex_includedir" + elif test x"$with_cplex" != x"yes"; then + CPLEX_CFLAGS="-I$with_cplex/include" + elif test x"$CPLEX_INCLUDEDIR" != x; then + CPLEX_CFLAGS="-I$CPLEX_INCLUDEDIR" + fi + + if test x"$with_cplex_libdir" != x"no"; then + CPLEX_LDFLAGS="-L$with_cplex_libdir" + elif test x"$with_cplex" != x"yes"; then + CPLEX_LDFLAGS="-L$with_cplex/lib" + elif test x"$CPLEX_LIBDIR" != x; then + CPLEX_LDFLAGS="-L$CPLEX_LIBDIR" + fi + CPLEX_LIBS="-lcplex -lm -lpthread" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$CPLEX_CFLAGS" + LDFLAGS="$CPLEX_LDFLAGS" + LIBS="$CPLEX_LIBS" + + lx_cplex_test_prog=' + extern "C" { + #include + } + + int main(int argc, char** argv) + { + CPXENVptr env = NULL; + return 0; + }' + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$lx_cplex_test_prog +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + lx_cplex_found=yes +else + lx_cplex_found=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_cplex_found" = x"yes"; then + +$as_echo "#define LEMON_HAVE_CPLEX 1" >>confdefs.h + + lx_lp_found=yes + +$as_echo "#define LEMON_HAVE_LP 1" >>confdefs.h + + lx_mip_found=yes + +$as_echo "#define LEMON_HAVE_MIP 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + CPLEX_CFLAGS="" + CPLEX_LDFLAGS="" + CPLEX_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + CPLEX_LIBS="$CPLEX_LDFLAGS $CPLEX_LIBS" + + + if test x"$lx_cplex_found" = x"yes"; then + HAVE_CPLEX_TRUE= + HAVE_CPLEX_FALSE='#' +else + HAVE_CPLEX_TRUE='#' + HAVE_CPLEX_FALSE= +fi + + + + +# Check whether --with-soplex was given. +if test "${with_soplex+set}" = set; then : + withval=$with_soplex; +else + with_soplex=yes +fi + + + +# Check whether --with-soplex-includedir was given. +if test "${with_soplex_includedir+set}" = set; then : + withval=$with_soplex_includedir; +else + with_soplex_includedir=no +fi + + + +# Check whether --with-soplex-libdir was given. +if test "${with_soplex_libdir+set}" = set; then : + withval=$with_soplex_libdir; +else + with_soplex_libdir=no +fi + + + lx_soplex_found=no + if test x"$with_soplex" != x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SOPLEX" >&5 +$as_echo_n "checking for SOPLEX... " >&6; } + + if test x"$with_soplex_includedir" != x"no"; then + SOPLEX_CXXFLAGS="-I$with_soplex_includedir" + elif test x"$with_soplex" != x"yes"; then + SOPLEX_CXXFLAGS="-I$with_soplex/src" + fi + + if test x"$with_soplex_libdir" != x"no"; then + SOPLEX_LDFLAGS="-L$with_soplex_libdir" + elif test x"$with_soplex" != x"yes"; then + SOPLEX_LDFLAGS="-L$with_soplex/lib" + fi + SOPLEX_LIBS="-lsoplex -lz" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$SOPLEX_CXXFLAGS" + LDFLAGS="$SOPLEX_LDFLAGS" + LIBS="$SOPLEX_LIBS" + + lx_soplex_test_prog=' + #include + + int main(int argc, char** argv) + { + soplex::SoPlex soplex; + return 0; + }' + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$lx_soplex_test_prog +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + lx_soplex_found=yes +else + lx_soplex_found=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_soplex_found" = x"yes"; then + +$as_echo "#define LEMON_HAVE_SOPLEX 1" >>confdefs.h + + lx_lp_found=yes + +$as_echo "#define LEMON_HAVE_LP 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + SOPLEX_CXXFLAGS="" + SOPLEX_LDFLAGS="" + SOPLEX_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS" + + + if test x"$lx_soplex_found" = x"yes"; then + HAVE_SOPLEX_TRUE= + HAVE_SOPLEX_FALSE='#' +else + HAVE_SOPLEX_TRUE='#' + HAVE_SOPLEX_FALSE= +fi + + + + +# Check whether --with-coin was given. +if test "${with_coin+set}" = set; then : + withval=$with_coin; +else + with_coin=yes +fi + + + +# Check whether --with-coin-includedir was given. +if test "${with_coin_includedir+set}" = set; then : + withval=$with_coin_includedir; +else + with_coin_includedir=no +fi + + + +# Check whether --with-coin-libdir was given. +if test "${with_coin_libdir+set}" = set; then : + withval=$with_coin_libdir; +else + with_coin_libdir=no +fi + + + lx_clp_found=no + if test x"$with_coin" != x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CLP" >&5 +$as_echo_n "checking for CLP... " >&6; } + + if test x"$with_coin_includedir" != x"no"; then + CLP_CXXFLAGS="-I$with_coin_includedir" + elif test x"$with_coin" != x"yes"; then + CLP_CXXFLAGS="-I$with_coin/include" + fi + + if test x"$with_coin_libdir" != x"no"; then + CLP_LDFLAGS="-L$with_coin_libdir" + elif test x"$with_coin" != x"yes"; then + CLP_LDFLAGS="-L$with_coin/lib" + fi + CLP_LIBS="-lClp -lCoinUtils -lm" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$CLP_CXXFLAGS" + LDFLAGS="$CLP_LDFLAGS" + LIBS="$CLP_LIBS" + + lx_clp_test_prog=' + #include + + int main(int argc, char** argv) + { + ClpModel clp; + return 0; + }' + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$lx_clp_test_prog +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + lx_clp_found=yes +else + lx_clp_found=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_clp_found" = x"yes"; then + +$as_echo "#define LEMON_HAVE_CLP 1" >>confdefs.h + + lx_lp_found=yes + +$as_echo "#define LEMON_HAVE_LP 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + CLP_CXXFLAGS="" + CLP_LDFLAGS="" + CLP_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS" + + + if test x"$lx_clp_found" = x"yes"; then + HAVE_CLP_TRUE= + HAVE_CLP_FALSE='#' +else + HAVE_CLP_TRUE='#' + HAVE_CLP_FALSE= +fi + + + + lx_cbc_found=no + if test x"$lx_clp_found" = x"yes"; then + if test x"$with_coin" != x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CBC" >&5 +$as_echo_n "checking for CBC... " >&6; } + + if test x"$with_coin_includedir" != x"no"; then + CBC_CXXFLAGS="-I$with_coin_includedir" + elif test x"$with_coin" != x"yes"; then + CBC_CXXFLAGS="-I$with_coin/include" + fi + + if test x"$with_coin_libdir" != x"no"; then + CBC_LDFLAGS="-L$with_coin_libdir" + elif test x"$with_coin" != x"yes"; then + CBC_LDFLAGS="-L$with_coin/lib" + fi + CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$CBC_CXXFLAGS" + LDFLAGS="$CBC_LDFLAGS" + LIBS="$CBC_LIBS" + + lx_cbc_test_prog=' + #include + + int main(int argc, char** argv) + { + CbcModel cbc; + return 0; + }' + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$lx_cbc_test_prog +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + lx_cbc_found=yes +else + lx_cbc_found=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_cbc_found" = x"yes"; then + +$as_echo "#define LEMON_HAVE_CBC 1" >>confdefs.h + + lx_lp_found=yes + +$as_echo "#define LEMON_HAVE_LP 1" >>confdefs.h + + lx_mip_found=yes + +$as_echo "#define LEMON_HAVE_MIP 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + CBC_CXXFLAGS="" + CBC_LDFLAGS="" + CBC_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + fi + CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS" + + + if test x"$lx_cbc_found" = x"yes"; then + HAVE_CBC_TRUE= + HAVE_CBC_FALSE='#' +else + HAVE_CBC_TRUE='#' + HAVE_CBC_FALSE= +fi + + + + if test x"$lx_lp_found" = x"yes"; then + HAVE_LP_TRUE= + HAVE_LP_FALSE='#' +else + HAVE_LP_TRUE='#' + HAVE_LP_FALSE= +fi + + if test x"$lx_mip_found" = x"yes"; then + HAVE_MIP_TRUE= + HAVE_MIP_FALSE='#' +else + HAVE_MIP_TRUE='#' + HAVE_MIP_FALSE= +fi + + +# Check whether --enable-tools was given. +if test "${enable_tools+set}" = set; then : + enableval=$enable_tools; +else + enable_tools=yes +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build the additional tools" >&5 +$as_echo_n "checking whether to build the additional tools... " >&6; } +if test x"$enable_tools" != x"no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + if test x"$enable_tools" != x"no"; then + WANT_TOOLS_TRUE= + WANT_TOOLS_FALSE='#' +else + WANT_TOOLS_TRUE='#' + WANT_TOOLS_FALSE= +fi + + +use_valgrind=no +# Check whether --enable-valgrind was given. +if test "${enable_valgrind+set}" = set; then : + enableval=$enable_valgrind; use_valgrind=yes +fi + + +if [ "$use_valgrind" = "yes" ]; then + # Extract the first word of "valgrind", so it can be a program name with args. +set dummy valgrind; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_HAVE_VALGRIND+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAVE_VALGRIND"; then + ac_cv_prog_HAVE_VALGRIND="$HAVE_VALGRIND" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_HAVE_VALGRIND="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAVE_VALGRIND" && ac_cv_prog_HAVE_VALGRIND="no" +fi +fi +HAVE_VALGRIND=$ac_cv_prog_HAVE_VALGRIND +if test -n "$HAVE_VALGRIND"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_VALGRIND" >&5 +$as_echo "$HAVE_VALGRIND" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + if [ "$HAVE_VALGRIND" = "no" ]; then + as_fn_error $? "Valgrind not found in PATH." "$LINENO" 5 + fi +fi + if test "$use_valgrind" = "yes"; then + USE_VALGRIND_TRUE= + USE_VALGRIND_FALSE='#' +else + USE_VALGRIND_TRUE='#' + USE_VALGRIND_FALSE= +fi + + +for ac_header in limits.h sys/time.h sys/times.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if ${ac_cv_struct_tm+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_cxx_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +for ac_func in gettimeofday times ctime_r +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +CONFIG_STATUS_DEPENDENCIES='$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in' + + +ac_config_files="$ac_config_files Makefile demo/Makefile cmake/version.cmake doc/Doxyfile doc/mainpage.dox lemon/lemon.pc" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_GLPK_TRUE}" && test -z "${HAVE_GLPK_FALSE}"; then + as_fn_error $? "conditional \"HAVE_GLPK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CPLEX_TRUE}" && test -z "${HAVE_CPLEX_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CPLEX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_SOPLEX_TRUE}" && test -z "${HAVE_SOPLEX_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SOPLEX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CLP_TRUE}" && test -z "${HAVE_CLP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CLP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_CBC_TRUE}" && test -z "${HAVE_CBC_FALSE}"; then + as_fn_error $? "conditional \"HAVE_CBC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_LP_TRUE}" && test -z "${HAVE_LP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_LP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_MIP_TRUE}" && test -z "${HAVE_MIP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_MIP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WANT_TOOLS_TRUE}" && test -z "${WANT_TOOLS_FALSE}"; then + as_fn_error $? "conditional \"WANT_TOOLS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${USE_VALGRIND_TRUE}" && test -z "${USE_VALGRIND_FALSE}"; then + as_fn_error $? "conditional \"USE_VALGRIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by LEMON $as_me 1.2.3, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +LEMON config.status 1.2.3 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' +macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' +macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' +enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' +pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' +host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' +host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' +host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' +build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' +build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' +build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' +SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' +Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' +GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' +EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' +FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' +LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' +NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' +LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' +ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' +exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' +lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' +reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' +AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' +STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' +RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' +compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' +GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' +SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' +ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' +need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' +LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' +libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' +version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' +runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' +libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' +soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' +old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' +striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`' +predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`' +postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +SHELL \ +ECHO \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +fix_srcfile_path_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` + ;; +esac + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "lemon/config.h") CONFIG_HEADERS="$CONFIG_HEADERS lemon/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "demo/Makefile") CONFIG_FILES="$CONFIG_FILES demo/Makefile" ;; + "cmake/version.cmake") CONFIG_FILES="$CONFIG_FILES cmake/version.cmake" ;; + "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; + "doc/mainpage.dox") CONFIG_FILES="$CONFIG_FILES doc/mainpage.dox" ;; + "lemon/lemon.pc") CONFIG_FILES="$CONFIG_FILES lemon/lemon.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that does not interpret backslashes. +ECHO=$lt_ECHO + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +echo +echo '****************************** SUMMARY ******************************' +echo +echo Package version............... : $PACKAGE-$VERSION +echo +echo C++ compiler.................. : $CXX +echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS +echo +echo Compiler supports long long... : $long_long_found +echo +echo GLPK support.................. : $lx_glpk_found +echo CPLEX support................. : $lx_cplex_found +echo SOPLEX support................ : $lx_soplex_found +echo CLP support................... : $lx_clp_found +echo CBC support................... : $lx_cbc_found +echo +echo Build additional tools........ : $enable_tools +echo Use valgrind for tests........ : $use_valgrind +echo +echo The packace will be installed in +echo -n ' ' +echo $prefix. +echo +echo '*********************************************************************' + +echo +echo Configure complete, now type \'make\' and then \'make install\'. +echo diff --git a/lemon/configure.ac b/lemon/configure.ac new file mode 100644 index 0000000..520d6bd --- /dev/null +++ b/lemon/configure.ac @@ -0,0 +1,157 @@ +dnl Process this file with autoconf to produce a configure script. + +dnl Version information. +m4_define([lemon_version_number], + [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))]) +dnl m4_define([lemon_version_number], []) +m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))]) +m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))]) +m4_define([lemon_version], [ifelse(lemon_version_number(), + [], + [ifelse(lemon_hg_revision(), + [], + [hg-tip], + [lemon_hg_path().lemon_hg_revision()])], + [lemon_version_number()])]) + +AC_PREREQ([2.59]) +AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc]) +AC_CONFIG_SRCDIR([lemon/list_graph.h]) +AC_CONFIG_HEADERS([config.h lemon/config.h]) + +AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string]) + +dnl Do compilation tests using the C++ compiler. +AC_LANG([C++]) + +dnl Check the existence of long long type. +AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no]) +if test x"$long_long_found" = x"yes"; then + AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.]) +fi + +dnl Checks for programs. +AC_PROG_CXX +AC_PROG_CXXCPP +AC_PROG_INSTALL +AC_DISABLE_SHARED +AC_PROG_LIBTOOL + +AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no]) +AC_CHECK_PROG([python_found],[python],[yes],[no]) +AC_CHECK_PROG([gs_found],[gs],[yes],[no]) + +dnl Detect Intel compiler. +AC_MSG_CHECKING([whether we are using the Intel C++ compiler]) +AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER +choke me +#endif], [ICC=[yes]], [ICC=[no]]) +if test x"$ICC" = x"yes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +dnl Set custom compiler flags when using g++. +if test "$GXX" = yes -a "$ICC" = no; then + WARNINGCXXFLAGS="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas" +fi +AC_SUBST([WARNINGCXXFLAGS]) + +dnl Checks for libraries. +LX_CHECK_GLPK +LX_CHECK_CPLEX +LX_CHECK_SOPLEX +LX_CHECK_COIN + +AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"]) +AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"]) + +dnl Disable/enable building the binary tools. +AC_ARG_ENABLE([tools], +AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@]) +AS_HELP_STRING([--disable-tools], [do not build additional tools]), + [], [enable_tools=yes]) +AC_MSG_CHECKING([whether to build the additional tools]) +if test x"$enable_tools" != x"no"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"]) + +dnl Support for running test cases using valgrind. +use_valgrind=no +AC_ARG_ENABLE([valgrind], +AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]), + [use_valgrind=yes]) + +if [[ "$use_valgrind" = "yes" ]]; then + AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no) + + if [[ "$HAVE_VALGRIND" = "no" ]]; then + AC_MSG_ERROR([Valgrind not found in PATH.]) + fi +fi +AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"]) + +dnl Checks for header files. +AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM + +dnl Checks for library functions. +AC_HEADER_STDC +AC_CHECK_FUNCS(gettimeofday times ctime_r) + +dnl Add dependencies on files generated by configure. +AC_SUBST([CONFIG_STATUS_DEPENDENCIES], + ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in']) + +AC_CONFIG_FILES([ +Makefile +demo/Makefile +cmake/version.cmake +doc/Doxyfile +doc/mainpage.dox +lemon/lemon.pc +]) + +AC_OUTPUT + +echo +echo '****************************** SUMMARY ******************************' +echo +echo Package version............... : $PACKAGE-$VERSION +echo +echo C++ compiler.................. : $CXX +echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS +echo +echo Compiler supports long long... : $long_long_found +echo +echo GLPK support.................. : $lx_glpk_found +echo CPLEX support................. : $lx_cplex_found +echo SOPLEX support................ : $lx_soplex_found +echo CLP support................... : $lx_clp_found +echo CBC support................... : $lx_cbc_found +echo +echo Build additional tools........ : $enable_tools +echo Use valgrind for tests........ : $use_valgrind +echo +echo The packace will be installed in +echo -n ' ' +echo $prefix. +echo +echo '*********************************************************************' + +echo +echo Configure complete, now type \'make\' and then \'make install\'. +echo diff --git a/lemon/demo/.deps/arg_parser_demo.Po b/lemon/demo/.deps/arg_parser_demo.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/demo/.deps/arg_parser_demo.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/demo/.deps/graph_to_eps_demo.Po b/lemon/demo/.deps/graph_to_eps_demo.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/demo/.deps/graph_to_eps_demo.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/demo/.deps/lgf_demo.Po b/lemon/demo/.deps/lgf_demo.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/demo/.deps/lgf_demo.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/demo/CMakeLists.txt b/lemon/demo/CMakeLists.txt new file mode 100644 index 0000000..e0566f4 --- /dev/null +++ b/lemon/demo/CMakeLists.txt @@ -0,0 +1,19 @@ +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} +) + +LINK_DIRECTORIES( + ${PROJECT_BINARY_DIR}/lemon +) + +SET(DEMOS + arg_parser_demo + graph_to_eps_demo + lgf_demo +) + +FOREACH(DEMO_NAME ${DEMOS}) + ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc) + TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon) +ENDFOREACH() diff --git a/lemon/demo/Makefile b/lemon/demo/Makefile new file mode 100644 index 0000000..77521a3 --- /dev/null +++ b/lemon/demo/Makefile @@ -0,0 +1,523 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# demo/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +pkgdatadir = $(datadir)/lemon +pkgincludedir = $(includedir)/lemon +pkglibdir = $(libdir)/lemon +pkglibexecdir = $(libexecdir)/lemon +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-unknown-linux-gnu +host_triplet = x86_64-unknown-linux-gnu +noinst_PROGRAMS = arg_parser_demo$(EXEEXT) graph_to_eps_demo$(EXEEXT) \ + lgf_demo$(EXEEXT) +subdir = demo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/lx_check_coin.m4 \ + $(top_srcdir)/m4/lx_check_cplex.m4 \ + $(top_srcdir)/m4/lx_check_glpk.m4 \ + $(top_srcdir)/m4/lx_check_soplex.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h \ + $(top_builddir)/lemon/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_arg_parser_demo_OBJECTS = arg_parser_demo.$(OBJEXT) +arg_parser_demo_OBJECTS = $(am_arg_parser_demo_OBJECTS) +arg_parser_demo_LDADD = $(LDADD) +arg_parser_demo_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_graph_to_eps_demo_OBJECTS = graph_to_eps_demo.$(OBJEXT) +graph_to_eps_demo_OBJECTS = $(am_graph_to_eps_demo_OBJECTS) +graph_to_eps_demo_LDADD = $(LDADD) +graph_to_eps_demo_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_lgf_demo_OBJECTS = lgf_demo.$(OBJEXT) +lgf_demo_OBJECTS = $(am_lgf_demo_OBJECTS) +lgf_demo_LDADD = $(LDADD) +lgf_demo_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(arg_parser_demo_SOURCES) $(graph_to_eps_demo_SOURCES) \ + $(lgf_demo_SOURCES) +DIST_SOURCES = $(arg_parser_demo_SOURCES) $(graph_to_eps_demo_SOURCES) \ + $(lgf_demo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run aclocal-1.11 +AMTAR = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run tar +AR = ar +AUTOCONF = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoconf +AUTOHEADER = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run autoheader +AUTOMAKE = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run automake-1.11 +AWK = mawk +CBC_CXXFLAGS = +CBC_LIBS = +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CLP_CXXFLAGS = +CLP_LIBS = +CONFIG_STATUS_DEPENDENCIES = $(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in +CPLEX_CFLAGS = +CPLEX_LIBS = +CPPFLAGS = +CXX = g++ +CXXCPP = g++ -E +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -g -O2 +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DSYMUTIL = +DUMPBIN = +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +FGREP = /bin/grep -F +GLPK_CFLAGS = +GLPK_LIBS = +GREP = /bin/grep +HAVE_VALGRIND = +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LD = /usr/bin/ld -m elf_x86_64 +LDFLAGS = +LIBOBJS = +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIPO = +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/carlo/honours/lemon/build-aux/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +NM = /usr/bin/nm -B +NMEDIT = +OBJDUMP = objdump +OBJEXT = o +OTOOL = +OTOOL64 = +PACKAGE = lemon +PACKAGE_BUGREPORT = lemon-user@lemon.cs.elte.hu +PACKAGE_NAME = LEMON +PACKAGE_STRING = LEMON 1.2.3 +PACKAGE_TARNAME = lemon +PACKAGE_URL = +PACKAGE_VERSION = 1.2.3 +PATH_SEPARATOR = : +RANLIB = ranlib +SED = /bin/sed +SET_MAKE = +SHELL = /bin/bash +SOPLEX_CXXFLAGS = +SOPLEX_LIBS = +STRIP = strip +VERSION = 1.2.3 +WARNINGCXXFLAGS = -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas +abs_builddir = /home/carlo/honours/lemon/demo +abs_srcdir = /home/carlo/honours/lemon/demo +abs_top_builddir = /home/carlo/honours/lemon +abs_top_srcdir = /home/carlo/honours/lemon +ac_ct_CC = gcc +ac_ct_CXX = g++ +ac_ct_DUMPBIN = +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = x86_64-unknown-linux-gnu +build_alias = +build_cpu = x86_64 +build_os = linux-gnu +build_vendor = unknown +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +doxygen_found = no +dvidir = ${docdir} +exec_prefix = ${prefix} +gs_found = yes +host = x86_64-unknown-linux-gnu +host_alias = +host_cpu = x86_64 +host_os = linux-gnu +host_vendor = unknown +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/carlo/honours/lemon/build-aux/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +lt_ECHO = echo +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +python_found = yes +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../ +top_builddir = .. +top_srcdir = .. +AM_CXXFLAGS = $(WARNINGCXXFLAGS) +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) +LDADD = $(top_builddir)/lemon/libemon.la +EXTRA_DIST = \ + CMakeLists.txt \ + digraph.lgf + +arg_parser_demo_SOURCES = arg_parser_demo.cc +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc +lgf_demo_SOURCES = lgf_demo.cc +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign demo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign demo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +arg_parser_demo$(EXEEXT): $(arg_parser_demo_OBJECTS) $(arg_parser_demo_DEPENDENCIES) + @rm -f arg_parser_demo$(EXEEXT) + $(CXXLINK) $(arg_parser_demo_OBJECTS) $(arg_parser_demo_LDADD) $(LIBS) +graph_to_eps_demo$(EXEEXT): $(graph_to_eps_demo_OBJECTS) $(graph_to_eps_demo_DEPENDENCIES) + @rm -f graph_to_eps_demo$(EXEEXT) + $(CXXLINK) $(graph_to_eps_demo_OBJECTS) $(graph_to_eps_demo_LDADD) $(LIBS) +lgf_demo$(EXEEXT): $(lgf_demo_OBJECTS) $(lgf_demo_DEPENDENCIES) + @rm -f lgf_demo$(EXEEXT) + $(CXXLINK) $(lgf_demo_OBJECTS) $(lgf_demo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/arg_parser_demo.Po +include ./$(DEPDIR)/graph_to_eps_demo.Po +include ./$(DEPDIR)/lgf_demo.Po + +.cc.o: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ + $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ + $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Plo +# source='$<' object='$@' libtool=yes \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lemon/demo/Makefile.am b/lemon/demo/Makefile.am new file mode 100644 index 0000000..800cd01 --- /dev/null +++ b/lemon/demo/Makefile.am @@ -0,0 +1,17 @@ +AM_CXXFLAGS = $(WARNINGCXXFLAGS) + +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) +LDADD = $(top_builddir)/lemon/libemon.la + +EXTRA_DIST = \ + CMakeLists.txt \ + digraph.lgf + +noinst_PROGRAMS = \ + arg_parser_demo \ + graph_to_eps_demo \ + lgf_demo + +arg_parser_demo_SOURCES = arg_parser_demo.cc +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc +lgf_demo_SOURCES = lgf_demo.cc diff --git a/lemon/demo/Makefile.in b/lemon/demo/Makefile.in new file mode 100644 index 0000000..3e2e039 --- /dev/null +++ b/lemon/demo/Makefile.in @@ -0,0 +1,523 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = arg_parser_demo$(EXEEXT) graph_to_eps_demo$(EXEEXT) \ + lgf_demo$(EXEEXT) +subdir = demo +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/lx_check_coin.m4 \ + $(top_srcdir)/m4/lx_check_cplex.m4 \ + $(top_srcdir)/m4/lx_check_glpk.m4 \ + $(top_srcdir)/m4/lx_check_soplex.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h \ + $(top_builddir)/lemon/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_arg_parser_demo_OBJECTS = arg_parser_demo.$(OBJEXT) +arg_parser_demo_OBJECTS = $(am_arg_parser_demo_OBJECTS) +arg_parser_demo_LDADD = $(LDADD) +arg_parser_demo_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_graph_to_eps_demo_OBJECTS = graph_to_eps_demo.$(OBJEXT) +graph_to_eps_demo_OBJECTS = $(am_graph_to_eps_demo_OBJECTS) +graph_to_eps_demo_LDADD = $(LDADD) +graph_to_eps_demo_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +am_lgf_demo_OBJECTS = lgf_demo.$(OBJEXT) +lgf_demo_OBJECTS = $(am_lgf_demo_OBJECTS) +lgf_demo_LDADD = $(LDADD) +lgf_demo_DEPENDENCIES = $(top_builddir)/lemon/libemon.la +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(arg_parser_demo_SOURCES) $(graph_to_eps_demo_SOURCES) \ + $(lgf_demo_SOURCES) +DIST_SOURCES = $(arg_parser_demo_SOURCES) $(graph_to_eps_demo_SOURCES) \ + $(lgf_demo_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CBC_CXXFLAGS = @CBC_CXXFLAGS@ +CBC_LIBS = @CBC_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLP_CXXFLAGS = @CLP_CXXFLAGS@ +CLP_LIBS = @CLP_LIBS@ +CONFIG_STATUS_DEPENDENCIES = @CONFIG_STATUS_DEPENDENCIES@ +CPLEX_CFLAGS = @CPLEX_CFLAGS@ +CPLEX_LIBS = @CPLEX_LIBS@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GLPK_CFLAGS = @GLPK_CFLAGS@ +GLPK_LIBS = @GLPK_LIBS@ +GREP = @GREP@ +HAVE_VALGRIND = @HAVE_VALGRIND@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOPLEX_CXXFLAGS = @SOPLEX_CXXFLAGS@ +SOPLEX_LIBS = @SOPLEX_LIBS@ +STRIP = @STRIP@ +VERSION = @VERSION@ +WARNINGCXXFLAGS = @WARNINGCXXFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +doxygen_found = @doxygen_found@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gs_found = @gs_found@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +python_found = @python_found@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CXXFLAGS = $(WARNINGCXXFLAGS) +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir) +LDADD = $(top_builddir)/lemon/libemon.la +EXTRA_DIST = \ + CMakeLists.txt \ + digraph.lgf + +arg_parser_demo_SOURCES = arg_parser_demo.cc +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc +lgf_demo_SOURCES = lgf_demo.cc +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign demo/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign demo/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +arg_parser_demo$(EXEEXT): $(arg_parser_demo_OBJECTS) $(arg_parser_demo_DEPENDENCIES) + @rm -f arg_parser_demo$(EXEEXT) + $(CXXLINK) $(arg_parser_demo_OBJECTS) $(arg_parser_demo_LDADD) $(LIBS) +graph_to_eps_demo$(EXEEXT): $(graph_to_eps_demo_OBJECTS) $(graph_to_eps_demo_DEPENDENCIES) + @rm -f graph_to_eps_demo$(EXEEXT) + $(CXXLINK) $(graph_to_eps_demo_OBJECTS) $(graph_to_eps_demo_LDADD) $(LIBS) +lgf_demo$(EXEEXT): $(lgf_demo_OBJECTS) $(lgf_demo_DEPENDENCIES) + @rm -f lgf_demo$(EXEEXT) + $(CXXLINK) $(lgf_demo_OBJECTS) $(lgf_demo_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arg_parser_demo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph_to_eps_demo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lgf_demo.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lemon/demo/arg_parser_demo.cc b/lemon/demo/arg_parser_demo.cc new file mode 100644 index 0000000..1bafac0 --- /dev/null +++ b/lemon/demo/arg_parser_demo.cc @@ -0,0 +1,112 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup demos +///\file +///\brief Argument parser demo +/// +/// This example shows how the argument parser can be used. +/// +/// \include arg_parser_demo.cc + +#include + +using namespace lemon; +int main(int argc, char **argv) +{ + // Initialize the argument parser + ArgParser ap(argc, argv); + int i; + std::string s; + double d = 1.0; + bool b, nh; + bool g1, g2, g3; + + // Add a mandatory integer option with storage reference + ap.refOption("n", "An integer input.", i, true); + // Add a double option with storage reference (the default value is 1.0) + ap.refOption("val", "A double input.", d); + // Add a double option without storage reference (the default value is 3.14) + ap.doubleOption("val2", "A double input.", 3.14); + // Set synonym for -val option + ap.synonym("vals", "val"); + // Add a string option + ap.refOption("name", "A string input.", s); + // Add bool options + ap.refOption("f", "A switch.", b) + .refOption("nohelp", "", nh) + .refOption("gra", "Choice A", g1) + .refOption("grb", "Choice B", g2) + .refOption("grc", "Choice C", g3); + // Bundle -gr* options into a group + ap.optionGroup("gr", "gra") + .optionGroup("gr", "grb") + .optionGroup("gr", "grc"); + // Set the group mandatory + ap.mandatoryGroup("gr"); + // Set the options of the group exclusive (only one option can be given) + ap.onlyOneGroup("gr"); + // Add non-parsed arguments (e.g. input files) + ap.other("infile", "The input file.") + .other("..."); + + // Throw an exception when problems occurs. The default behavior is to + // exit(1) on these cases, but this makes Valgrind falsely warn + // about memory leaks. + ap.throwOnProblems(); + + // Perform the parsing process + // (in case of any error it terminates the program) + // The try {} construct is necessary only if the ap.trowOnProblems() + // setting is in use. + try { + ap.parse(); + } catch (ArgParserException &) { return 1; } + + // Check each option if it has been given and print its value + std::cout << "Parameters of '" << ap.commandName() << "':\n"; + + std::cout << " Value of -n: " << i << std::endl; + if(ap.given("val")) std::cout << " Value of -val: " << d << std::endl; + if(ap.given("val2")) { + d = ap["val2"]; + std::cout << " Value of -val2: " << d << std::endl; + } + if(ap.given("name")) std::cout << " Value of -name: " << s << std::endl; + if(ap.given("f")) std::cout << " -f is given\n"; + if(ap.given("nohelp")) std::cout << " Value of -nohelp: " << nh << std::endl; + if(ap.given("gra")) std::cout << " -gra is given\n"; + if(ap.given("grb")) std::cout << " -grb is given\n"; + if(ap.given("grc")) std::cout << " -grc is given\n"; + + switch(ap.files().size()) { + case 0: + std::cout << " No file argument was given.\n"; + break; + case 1: + std::cout << " 1 file argument was given. It is:\n"; + break; + default: + std::cout << " " + << ap.files().size() << " file arguments were given. They are:\n"; + } + for(unsigned int i=0;i.eps files demonstrating the capability of \ref +/// graphToEps(), and showing how to draw directed graphs, +/// how to handle parallel egdes, how to change the properties (like +/// color, shape, size, title etc.) of nodes and arcs individually +/// using appropriate graph maps. +/// +/// \include graph_to_eps_demo.cc + +#include +#include +#include + +using namespace std; +using namespace lemon; + +int main() +{ + Palette palette; + Palette paletteW(true); + + // Create a small digraph + ListDigraph g; + typedef ListDigraph::Node Node; + typedef ListDigraph::NodeIt NodeIt; + typedef ListDigraph::Arc Arc; + typedef dim2::Point Point; + + Node n1=g.addNode(); + Node n2=g.addNode(); + Node n3=g.addNode(); + Node n4=g.addNode(); + Node n5=g.addNode(); + + ListDigraph::NodeMap coords(g); + ListDigraph::NodeMap sizes(g); + ListDigraph::NodeMap colors(g); + ListDigraph::NodeMap shapes(g); + ListDigraph::ArcMap acolors(g); + ListDigraph::ArcMap widths(g); + + coords[n1]=Point(50,50); sizes[n1]=1; colors[n1]=1; shapes[n1]=0; + coords[n2]=Point(50,70); sizes[n2]=2; colors[n2]=2; shapes[n2]=2; + coords[n3]=Point(70,70); sizes[n3]=1; colors[n3]=3; shapes[n3]=0; + coords[n4]=Point(70,50); sizes[n4]=2; colors[n4]=4; shapes[n4]=1; + coords[n5]=Point(85,60); sizes[n5]=3; colors[n5]=5; shapes[n5]=2; + + Arc a; + + a=g.addArc(n1,n2); acolors[a]=0; widths[a]=1; + a=g.addArc(n2,n3); acolors[a]=0; widths[a]=1; + a=g.addArc(n3,n5); acolors[a]=0; widths[a]=3; + a=g.addArc(n5,n4); acolors[a]=0; widths[a]=1; + a=g.addArc(n4,n1); acolors[a]=0; widths[a]=1; + a=g.addArc(n2,n4); acolors[a]=1; widths[a]=2; + a=g.addArc(n3,n4); acolors[a]=2; widths[a]=1; + + IdMap id(g); + + // Create .eps files showing the digraph with different options + cout << "Create 'graph_to_eps_demo_out_1_pure.eps'" << endl; + graphToEps(g,"graph_to_eps_demo_out_1_pure.eps"). + coords(coords). + title("Sample .eps figure"). + copyright("(C) 2003-2009 LEMON Project"). + run(); + + cout << "Create 'graph_to_eps_demo_out_2.eps'" << endl; + graphToEps(g,"graph_to_eps_demo_out_2.eps"). + coords(coords). + title("Sample .eps figure"). + copyright("(C) 2003-2009 LEMON Project"). + absoluteNodeSizes().absoluteArcWidths(). + nodeScale(2).nodeSizes(sizes). + nodeShapes(shapes). + nodeColors(composeMap(palette,colors)). + arcColors(composeMap(palette,acolors)). + arcWidthScale(.4).arcWidths(widths). + nodeTexts(id).nodeTextSize(3). + run(); + + cout << "Create 'graph_to_eps_demo_out_3_arr.eps'" << endl; + graphToEps(g,"graph_to_eps_demo_out_3_arr.eps"). + title("Sample .eps figure (with arrowheads)"). + copyright("(C) 2003-2009 LEMON Project"). + absoluteNodeSizes().absoluteArcWidths(). + nodeColors(composeMap(palette,colors)). + coords(coords). + nodeScale(2).nodeSizes(sizes). + nodeShapes(shapes). + arcColors(composeMap(palette,acolors)). + arcWidthScale(.4).arcWidths(widths). + nodeTexts(id).nodeTextSize(3). + drawArrows().arrowWidth(2).arrowLength(2). + run(); + + // Add more arcs to the digraph + a=g.addArc(n1,n4); acolors[a]=2; widths[a]=1; + a=g.addArc(n4,n1); acolors[a]=1; widths[a]=2; + + a=g.addArc(n1,n2); acolors[a]=1; widths[a]=1; + a=g.addArc(n1,n2); acolors[a]=2; widths[a]=1; + a=g.addArc(n1,n2); acolors[a]=3; widths[a]=1; + a=g.addArc(n1,n2); acolors[a]=4; widths[a]=1; + a=g.addArc(n1,n2); acolors[a]=5; widths[a]=1; + a=g.addArc(n1,n2); acolors[a]=6; widths[a]=1; + a=g.addArc(n1,n2); acolors[a]=7; widths[a]=1; + + cout << "Create 'graph_to_eps_demo_out_4_par.eps'" << endl; + graphToEps(g,"graph_to_eps_demo_out_4_par.eps"). + title("Sample .eps figure (parallel arcs)"). + copyright("(C) 2003-2009 LEMON Project"). + absoluteNodeSizes().absoluteArcWidths(). + nodeShapes(shapes). + coords(coords). + nodeScale(2).nodeSizes(sizes). + nodeColors(composeMap(palette,colors)). + arcColors(composeMap(palette,acolors)). + arcWidthScale(.4).arcWidths(widths). + nodeTexts(id).nodeTextSize(3). + enableParallel().parArcDist(1.5). + run(); + + cout << "Create 'graph_to_eps_demo_out_5_par_arr.eps'" << endl; + graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps"). + title("Sample .eps figure (parallel arcs and arrowheads)"). + copyright("(C) 2003-2009 LEMON Project"). + absoluteNodeSizes().absoluteArcWidths(). + nodeScale(2).nodeSizes(sizes). + coords(coords). + nodeShapes(shapes). + nodeColors(composeMap(palette,colors)). + arcColors(composeMap(palette,acolors)). + arcWidthScale(.3).arcWidths(widths). + nodeTexts(id).nodeTextSize(3). + enableParallel().parArcDist(1). + drawArrows().arrowWidth(1).arrowLength(1). + run(); + + cout << "Create 'graph_to_eps_demo_out_6_par_arr_a4.eps'" << endl; + graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps"). + title("Sample .eps figure (fits to A4)"). + copyright("(C) 2003-2009 LEMON Project"). + scaleToA4(). + absoluteNodeSizes().absoluteArcWidths(). + nodeScale(2).nodeSizes(sizes). + coords(coords). + nodeShapes(shapes). + nodeColors(composeMap(palette,colors)). + arcColors(composeMap(palette,acolors)). + arcWidthScale(.3).arcWidths(widths). + nodeTexts(id).nodeTextSize(3). + enableParallel().parArcDist(1). + drawArrows().arrowWidth(1).arrowLength(1). + run(); + + // Create an .eps file showing the colors of a default Palette + ListDigraph h; + ListDigraph::NodeMap hcolors(h); + ListDigraph::NodeMap hcoords(h); + + int cols=int(std::sqrt(double(palette.size()))); + for(int i=0;i +#include +#include +#include + +using namespace lemon; + +int main() { + SmartDigraph g; + SmartDigraph::ArcMap cap(g); + SmartDigraph::Node s, t; + + try { + digraphReader(g, "digraph.lgf"). // read the directed graph into g + arcMap("capacity", cap). // read the 'capacity' arc map into cap + node("source", s). // read 'source' node to s + node("target", t). // read 'target' node to t + run(); + } catch (Exception& error) { // check if there was any error + std::cerr << "Error: " << error.what() << std::endl; + return -1; + } + + std::cout << "A digraph is read from 'digraph.lgf'." << std::endl; + std::cout << "Number of nodes: " << countNodes(g) << std::endl; + std::cout << "Number of arcs: " << countArcs(g) << std::endl; + + std::cout << "We can write it to the standard output:" << std::endl; + + digraphWriter(g). // write g to the standard output + arcMap("capacity", cap). // write cap into 'capacity' + node("source", s). // write s to 'source' + node("target", t). // write t to 'target' + run(); + + return 0; +} diff --git a/lemon/doc/CMakeLists.txt b/lemon/doc/CMakeLists.txt new file mode 100644 index 0000000..68a690e --- /dev/null +++ b/lemon/doc/CMakeLists.txt @@ -0,0 +1,74 @@ +SET(PACKAGE_NAME ${PROJECT_NAME}) +SET(PACKAGE_VERSION ${PROJECT_VERSION}) +SET(abs_top_srcdir ${PROJECT_SOURCE_DIR}) +SET(abs_top_builddir ${PROJECT_BINARY_DIR}) + +SET(LEMON_DOC_SOURCE_BROWSER "NO" CACHE STRING "Include source into the doc (YES/NO).") + +CONFIGURE_FILE( + ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in + ${PROJECT_BINARY_DIR}/doc/Doxyfile + @ONLY +) + +CONFIGURE_FILE( + ${PROJECT_SOURCE_DIR}/doc/mainpage.dox.in + ${PROJECT_BINARY_DIR}/doc/mainpage.dox + @ONLY +) + +IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE) + FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/) + SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha) + ADD_CUSTOM_TARGET(html + COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images + COMMAND ${CMAKE_COMMAND} -E make_directory gen-images + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps + COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps + COMMAND ${CMAKE_COMMAND} -E remove_directory html + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox + COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC) + + IF(UNIX) + INSTALL( + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ + DESTINATION share/doc/lemon/html + COMPONENT html_documentation + ) + ELSEIF(WIN32) + INSTALL( + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ + DESTINATION doc + COMPONENT html_documentation + ) + ENDIF() + +ENDIF() + +IF(WGET_FOUND) +ADD_CUSTOM_TARGET(update-external-tags + COMMAND ${CMAKE_COMMAND} -E make_directory dl + # COMMAND ${CMAKE_COMMAND} -E copy libstdc++.tag dl + COMMAND ${WGET_EXECUTABLE} wget -P dl -N libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag + COMMAND ${CMAKE_COMMAND} -E rename dl/libstdc++.tag libstdc++.tag + COMMAND ${CMAKE_COMMAND} -E remove dl/libstdc++.tag + COMMAND ${CMAKE_COMMAND} -E remove_directory dl + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) +ENDIF() diff --git a/lemon/doc/Doxyfile b/lemon/doc/Doxyfile new file mode 100644 index 0000000..a53c7a4 --- /dev/null +++ b/lemon/doc/Doxyfile @@ -0,0 +1,291 @@ +# Doxyfile 1.7.3 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = NO +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = "/home/carlo/honours/lemon" +STRIP_FROM_INC_PATH = "/home/carlo/honours/lemon" +SHORT_NAMES = YES +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +BUILTIN_STL_SUPPORT = YES +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO +SYMBOL_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = YES +SHOW_INCLUDE_FILES = YES +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 5 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = "/home/carlo/honours/lemon/doc/DoxygenLayout.xml" +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = doxygen.log +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = "/home/carlo/honours/lemon/doc" \ + "/home/carlo/honours/lemon/lemon" \ + "/home/carlo/honours/lemon/lemon/bits" \ + "/home/carlo/honours/lemon/lemon/concepts" \ + "/home/carlo/honours/lemon/demo" \ + "/home/carlo/honours/lemon/tools" \ + "/home/carlo/honours/lemon/test/test_tools.h" \ + "/home/carlo/honours/lemon/doc/mainpage.dox" \ + "/home/carlo/honours/lemon/doc/references.dox" +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.h \ + *.cc \ + *.dox +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = "/home/carlo/honours/lemon/demo" \ + "/home/carlo/honours/lemon/LICENSE" \ + "/home/carlo/honours/lemon/doc" +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = "/home/carlo/honours/lemon/doc/images" \ + "/home/carlo/honours/lemon/doc/gen-images" +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = @LEMON_DOC_SOURCE_BROWSER@ +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 2 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_ALIGN_MEMBERS = YES +HTML_DYNAMIC_SECTIONS = YES +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +USE_INLINE_TREES = NO +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_RELPATH = http://www.mathjax.org/mathjax +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = YES +PAPER_TYPE = a4wide +EXTRA_PACKAGES = amsmath \ + amssymb +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = "/home/carlo/honours/lemon/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/ " +GENERATE_TAGFILE = html/lemon.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = NO +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +DOT_NUM_THREADS = 0 +DOT_FONTNAME = FreeSans +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/lemon/doc/Doxyfile.in b/lemon/doc/Doxyfile.in new file mode 100644 index 0000000..e4dcaf8 --- /dev/null +++ b/lemon/doc/Doxyfile.in @@ -0,0 +1,291 @@ +# Doxyfile 1.7.3 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = NO +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = "@abs_top_srcdir@" +STRIP_FROM_INC_PATH = "@abs_top_srcdir@" +SHORT_NAMES = YES +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +BUILTIN_STL_SUPPORT = YES +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO +SYMBOL_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = YES +SHOW_INCLUDE_FILES = YES +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 5 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = "@abs_top_srcdir@/doc/DoxygenLayout.xml" +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = doxygen.log +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = "@abs_top_srcdir@/doc" \ + "@abs_top_srcdir@/lemon" \ + "@abs_top_srcdir@/lemon/bits" \ + "@abs_top_srcdir@/lemon/concepts" \ + "@abs_top_srcdir@/demo" \ + "@abs_top_srcdir@/tools" \ + "@abs_top_srcdir@/test/test_tools.h" \ + "@abs_top_builddir@/doc/mainpage.dox" \ + "@abs_top_builddir@/doc/references.dox" +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.h \ + *.cc \ + *.dox +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = "@abs_top_srcdir@/demo" \ + "@abs_top_srcdir@/LICENSE" \ + "@abs_top_srcdir@/doc" +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = "@abs_top_srcdir@/doc/images" \ + "@abs_top_builddir@/doc/gen-images" +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = @LEMON_DOC_SOURCE_BROWSER@ +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 2 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_ALIGN_MEMBERS = YES +HTML_DYNAMIC_SECTIONS = YES +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +USE_INLINE_TREES = NO +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_RELPATH = http://www.mathjax.org/mathjax +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = YES +PAPER_TYPE = a4wide +EXTRA_PACKAGES = amsmath \ + amssymb +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGEN +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = "@abs_top_builddir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/ " +GENERATE_TAGFILE = html/lemon.tag +ALLEXTERNALS = NO +EXTERNAL_GROUPS = NO +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +DOT_NUM_THREADS = 0 +DOT_FONTNAME = FreeSans +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/lemon/doc/DoxygenLayout.xml b/lemon/doc/DoxygenLayout.xml new file mode 100644 index 0000000..7085f8a --- /dev/null +++ b/lemon/doc/DoxygenLayout.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lemon/doc/Makefile.am b/lemon/doc/Makefile.am new file mode 100644 index 0000000..ee02e50 --- /dev/null +++ b/lemon/doc/Makefile.am @@ -0,0 +1,123 @@ +EXTRA_DIST += \ + doc/Doxyfile.in \ + doc/DoxygenLayout.xml \ + doc/coding_style.dox \ + doc/dirs.dox \ + doc/groups.dox \ + doc/lgf.dox \ + doc/license.dox \ + doc/mainpage.dox \ + doc/migration.dox \ + doc/min_cost_flow.dox \ + doc/named-param.dox \ + doc/namespaces.dox \ + doc/html \ + doc/CMakeLists.txt + +DOC_EPS_IMAGES18 = \ + grid_graph.eps \ + nodeshape_0.eps \ + nodeshape_1.eps \ + nodeshape_2.eps \ + nodeshape_3.eps \ + nodeshape_4.eps + +DOC_EPS_IMAGES27 = \ + bipartite_matching.eps \ + bipartite_partitions.eps \ + connected_components.eps \ + edge_biconnected_components.eps \ + matching.eps \ + node_biconnected_components.eps \ + planar.eps \ + strongly_connected_components.eps + +DOC_EPS_IMAGES = \ + $(DOC_EPS_IMAGES18) \ + $(DOC_EPS_IMAGES27) + +DOC_PNG_IMAGES = \ + $(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png) + +EXTRA_DIST += $(DOC_EPS_IMAGES:%=doc/images/%) + +doc/html: + $(MAKE) $(AM_MAKEFLAGS) html + +GS_COMMAND=gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 + +$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps + -mkdir doc/gen-images + if test ${gs_found} = yes; then \ + $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \ + else \ + echo; \ + echo "Ghostscript not found."; \ + echo; \ + exit 1; \ + fi + +$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps + -mkdir doc/gen-images + if test ${gs_found} = yes; then \ + $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \ + else \ + echo; \ + echo "Ghostscript not found."; \ + echo; \ + exit 1; \ + fi + +references.dox: doc/references.bib + if test ${python_found} = yes; then \ + cd doc; \ + python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \ + cd ..; \ + else \ + echo; \ + echo "Python not found."; \ + echo; \ + exit 1; \ + fi + +html-local: $(DOC_PNG_IMAGES) references.dox + if test ${doxygen_found} = yes; then \ + cd doc; \ + doxygen Doxyfile; \ + cd ..; \ + else \ + echo; \ + echo "Doxygen not found."; \ + echo; \ + exit 1; \ + fi + +clean-local: + -rm -rf doc/html + -rm -f doc/doxygen.log + -rm -f $(DOC_PNG_IMAGES) + -rm -rf doc/gen-images + +update-external-tags: + wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \ + mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \ + rm doc/libstdc++.tag.tmp + +install-html-local: doc/html + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(htmldir)/html + for p in doc/html/*.{html,css,png,map,gif,tag} ; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \ + done + +uninstall-local: + @$(NORMAL_UNINSTALL) + for p in doc/html/*.{html,css,png,map,gif,tag} ; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \ + rm -f $(DESTDIR)$(htmldir)/html/$$f; \ + done + +.PHONY: update-external-tags diff --git a/lemon/doc/coding_style.dox b/lemon/doc/coding_style.dox new file mode 100644 index 0000000..5c6af26 --- /dev/null +++ b/lemon/doc/coding_style.dox @@ -0,0 +1,127 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/*! + +\page coding_style LEMON Coding Style + +\section naming_conv Naming Conventions + +In order to make development easier we have made some conventions +according to coding style. These include names of types, classes, +functions, variables, constants and exceptions. If these conventions +are met in one's code then it is easier to read and maintain +it. Please comply with these conventions if you want to contribute +developing LEMON library. + +\note When the coding style requires the capitalization of an abbreviation, +only the first letter should be upper case. + +\code +XmlReader +\endcode + + +\warning In some cases we diverge from these rules. +This is primary done because STL uses different naming convention and +in certain cases +it is beneficial to provide STL compatible interface. + +\subsection cs-files File Names + +The header file names should look like the following. + +\code +header_file.h +\endcode + +Note that all standard LEMON headers are located in the \c lemon subdirectory, +so you should include them from C++ source like this: + +\code +#include +\endcode + +The source code files use the same style and they have '.cc' extension. + +\code +source_code.cc +\endcode + +\subsection cs-class Classes and other types + +The name of a class or any type should look like the following. + +\code +AllWordsCapitalizedWithoutUnderscores +\endcode + +\subsection cs-func Methods and other functions + +The name of a function should look like the following. + +\code +firstWordLowerCaseRestCapitalizedWithoutUnderscores +\endcode + +\subsection cs-funcs Constants, Macros + +The names of constants and macros should look like the following. + +\code +ALL_UPPER_CASE_WITH_UNDERSCORES +\endcode + +\subsection cs-loc-var Class and instance member variables, auto variables + +The names of class and instance member variables and auto variables +(=variables used locally in methods) should look like the following. + +\code +all_lower_case_with_underscores +\endcode + +\subsection pri-loc-var Private member variables + +Private member variables should start with underscore + +\code +_start_with_underscores +\endcode + +\subsection cs-excep Exceptions + +When writing exceptions please comply the following naming conventions. + +\code +ClassNameEndsWithException +\endcode + +or + +\code +ClassNameEndsWithError +\endcode + +\section header-template Template Header File + +Each LEMON header file should look like this: + +\include template.h + +*/ diff --git a/lemon/doc/dirs.dox b/lemon/doc/dirs.dox new file mode 100644 index 0000000..c242fb2 --- /dev/null +++ b/lemon/doc/dirs.dox @@ -0,0 +1,77 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/** +\dir demo +\brief A collection of demo applications. + +This directory contains several simple demo applications, mainly +for educational purposes. +*/ + +/** +\dir doc +\brief Auxiliary (and the whole generated) documentation. + +This directory contains some auxiliary pages and the whole generated +documentation. +*/ + +/** +\dir test +\brief Test programs. + +This directory contains several test programs that check the consistency +of the code. +*/ + +/** +\dir tools +\brief Some useful executables. + +This directory contains the sources of some useful complete executables. +*/ + +/** +\dir lemon +\brief Base include directory of LEMON. + +This is the base directory of LEMON includes, so each include file must be +prefixed with this, e.g. +\code +#include +#include +\endcode +*/ + +/** +\dir concepts +\brief Concept descriptors and checking classes. + +This directory contains the concept descriptors and concept checking tools. +For more information see the \ref concept "Concepts" module. +*/ + +/** +\dir bits +\brief Auxiliary tools for implementation. + +This directory contains some auxiliary classes for implementing graphs, +maps and some other classes. +As a user you typically don't have to deal with these files. +*/ diff --git a/lemon/doc/groups.dox b/lemon/doc/groups.dox new file mode 100644 index 0000000..7400979 --- /dev/null +++ b/lemon/doc/groups.dox @@ -0,0 +1,702 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +namespace lemon { + +/** +@defgroup datas Data Structures +This group contains the several data structures implemented in LEMON. +*/ + +/** +@defgroup graphs Graph Structures +@ingroup datas +\brief Graph structures implemented in LEMON. + +The implementation of combinatorial algorithms heavily relies on +efficient graph implementations. LEMON offers data structures which are +planned to be easily used in an experimental phase of implementation studies, +and thereafter the program code can be made efficient by small modifications. + +The most efficient implementation of diverse applications require the +usage of different physical graph implementations. These differences +appear in the size of graph we require to handle, memory or time usage +limitations or in the set of operations through which the graph can be +accessed. LEMON provides several physical graph structures to meet +the diverging requirements of the possible users. In order to save on +running time or on memory usage, some structures may fail to provide +some graph features like arc/edge or node deletion. + +Alteration of standard containers need a very limited number of +operations, these together satisfy the everyday requirements. +In the case of graph structures, different operations are needed which do +not alter the physical graph, but gives another view. If some nodes or +arcs have to be hidden or the reverse oriented graph have to be used, then +this is the case. It also may happen that in a flow implementation +the residual graph can be accessed by another algorithm, or a node-set +is to be shrunk for another algorithm. +LEMON also provides a variety of graphs for these requirements called +\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only +in conjunction with other graph representations. + +You are free to use the graph structure that fit your requirements +the best, most graph algorithms and auxiliary data structures can be used +with any graph structure. + +See also: \ref graph_concepts "Graph Structure Concepts". +*/ + +/** +@defgroup graph_adaptors Adaptor Classes for Graphs +@ingroup graphs +\brief Adaptor classes for digraphs and graphs + +This group contains several useful adaptor classes for digraphs and graphs. + +The main parts of LEMON are the different graph structures, generic +graph algorithms, graph concepts, which couple them, and graph +adaptors. While the previous notions are more or less clear, the +latter one needs further explanation. Graph adaptors are graph classes +which serve for considering graph structures in different ways. + +A short example makes this much clearer. Suppose that we have an +instance \c g of a directed graph type, say ListDigraph and an algorithm +\code +template +int algorithm(const Digraph&); +\endcode +is needed to run on the reverse oriented graph. It may be expensive +(in time or in memory usage) to copy \c g with the reversed +arcs. In this case, an adaptor class is used, which (according +to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph. +The adaptor uses the original digraph structure and digraph operations when +methods of the reversed oriented graph are called. This means that the adaptor +have minor memory usage, and do not perform sophisticated algorithmic +actions. The purpose of it is to give a tool for the cases when a +graph have to be used in a specific alteration. If this alteration is +obtained by a usual construction like filtering the node or the arc set or +considering a new orientation, then an adaptor is worthwhile to use. +To come back to the reverse oriented graph, in this situation +\code +template class ReverseDigraph; +\endcode +template class can be used. The code looks as follows +\code +ListDigraph g; +ReverseDigraph rg(g); +int result = algorithm(rg); +\endcode +During running the algorithm, the original digraph \c g is untouched. +This techniques give rise to an elegant code, and based on stable +graph adaptors, complex algorithms can be implemented easily. + +In flow, circulation and matching problems, the residual +graph is of particular importance. Combining an adaptor implementing +this with shortest path algorithms or minimum mean cycle algorithms, +a range of weighted and cardinality optimization algorithms can be +obtained. For other examples, the interested user is referred to the +detailed documentation of particular adaptors. + +The behavior of graph adaptors can be very different. Some of them keep +capabilities of the original graph while in other cases this would be +meaningless. This means that the concepts that they meet depend +on the graph adaptor, and the wrapped graph. +For example, if an arc of a reversed digraph is deleted, this is carried +out by deleting the corresponding arc of the original digraph, thus the +adaptor modifies the original digraph. +However in case of a residual digraph, this operation has no sense. + +Let us stand one more example here to simplify your work. +ReverseDigraph has constructor +\code +ReverseDigraph(Digraph& digraph); +\endcode +This means that in a situation, when a const %ListDigraph& +reference to a graph is given, then it have to be instantiated with +Digraph=const %ListDigraph. +\code +int algorithm1(const ListDigraph& g) { + ReverseDigraph rg(g); + return algorithm2(rg); +} +\endcode +*/ + +/** +@defgroup maps Maps +@ingroup datas +\brief Map structures implemented in LEMON. + +This group contains the map structures implemented in LEMON. + +LEMON provides several special purpose maps and map adaptors that e.g. combine +new maps from existing ones. + +See also: \ref map_concepts "Map Concepts". +*/ + +/** +@defgroup graph_maps Graph Maps +@ingroup maps +\brief Special graph-related maps. + +This group contains maps that are specifically designed to assign +values to the nodes and arcs/edges of graphs. + +If you are looking for the standard graph maps (\c NodeMap, \c ArcMap, +\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts". +*/ + +/** +\defgroup map_adaptors Map Adaptors +\ingroup maps +\brief Tools to create new maps from existing ones + +This group contains map adaptors that are used to create "implicit" +maps from other maps. + +Most of them are \ref concepts::ReadMap "read-only maps". +They can make arithmetic and logical operations between one or two maps +(negation, shifting, addition, multiplication, logical 'and', 'or', +'not' etc.) or e.g. convert a map to another one of different Value type. + +The typical usage of this classes is passing implicit maps to +algorithms. If a function type algorithm is called then the function +type map adaptors can be used comfortable. For example let's see the +usage of map adaptors with the \c graphToEps() function. +\code + Color nodeColor(int deg) { + if (deg >= 2) { + return Color(0.5, 0.0, 0.5); + } else if (deg == 1) { + return Color(1.0, 0.5, 1.0); + } else { + return Color(0.0, 0.0, 0.0); + } + } + + Digraph::NodeMap degree_map(graph); + + graphToEps(graph, "graph.eps") + .coords(coords).scaleToA4().undirected() + .nodeColors(composeMap(functorToMap(nodeColor), degree_map)) + .run(); +\endcode +The \c functorToMap() function makes an \c int to \c Color map from the +\c nodeColor() function. The \c composeMap() compose the \c degree_map +and the previously created map. The composed map is a proper function to +get the color of each node. + +The usage with class type algorithms is little bit harder. In this +case the function type map adaptors can not be used, because the +function map adaptors give back temporary objects. +\code + Digraph graph; + + typedef Digraph::ArcMap DoubleArcMap; + DoubleArcMap length(graph); + DoubleArcMap speed(graph); + + typedef DivMap TimeMap; + TimeMap time(length, speed); + + Dijkstra dijkstra(graph, time); + dijkstra.run(source, target); +\endcode +We have a length map and a maximum speed map on the arcs of a digraph. +The minimum time to pass the arc can be calculated as the division of +the two maps which can be done implicitly with the \c DivMap template +class. We use the implicit minimum time map as the length map of the +\c Dijkstra algorithm. +*/ + +/** +@defgroup paths Path Structures +@ingroup datas +\brief %Path structures implemented in LEMON. + +This group contains the path structures implemented in LEMON. + +LEMON provides flexible data structures to work with paths. +All of them have similar interfaces and they can be copied easily with +assignment operators and copy constructors. This makes it easy and +efficient to have e.g. the Dijkstra algorithm to store its result in +any kind of path structure. + +\sa \ref concepts::Path "Path concept" +*/ + +/** +@defgroup heaps Heap Structures +@ingroup datas +\brief %Heap structures implemented in LEMON. + +This group contains the heap structures implemented in LEMON. + +LEMON provides several heap classes. They are efficient implementations +of the abstract data type \e priority \e queue. They store items with +specified values called \e priorities in such a way that finding and +removing the item with minimum priority are efficient. +The basic operations are adding and erasing items, changing the priority +of an item, etc. + +Heaps are crucial in several algorithms, such as Dijkstra and Prim. +The heap implementations have the same interface, thus any of them can be +used easily in such algorithms. + +\sa \ref concepts::Heap "Heap concept" +*/ + +/** +@defgroup auxdat Auxiliary Data Structures +@ingroup datas +\brief Auxiliary data structures implemented in LEMON. + +This group contains some data structures implemented in LEMON in +order to make it easier to implement combinatorial algorithms. +*/ + +/** +@defgroup geomdat Geometric Data Structures +@ingroup auxdat +\brief Geometric data structures implemented in LEMON. + +This group contains geometric data structures implemented in LEMON. + + - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional + vector with the usual operations. + - \ref lemon::dim2::Box "dim2::Box" can be used to determine the + rectangular bounding box of a set of \ref lemon::dim2::Point + "dim2::Point"'s. +*/ + +/** +@defgroup algs Algorithms +\brief This group contains the several algorithms +implemented in LEMON. + +This group contains the several algorithms +implemented in LEMON. +*/ + +/** +@defgroup search Graph Search +@ingroup algs +\brief Common graph search algorithms. + +This group contains the common graph search algorithms, namely +\e breadth-first \e search (BFS) and \e depth-first \e search (DFS) +\ref clrs01algorithms. +*/ + +/** +@defgroup shortest_path Shortest Path Algorithms +@ingroup algs +\brief Algorithms for finding shortest paths. + +This group contains the algorithms for finding shortest paths in digraphs +\ref clrs01algorithms. + + - \ref Dijkstra algorithm for finding shortest paths from a source node + when all arc lengths are non-negative. + - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths + from a source node when arc lenghts can be either positive or negative, + but the digraph should not contain directed cycles with negative total + length. + - \ref Suurballe A successive shortest path algorithm for finding + arc-disjoint paths between two nodes having minimum total length. +*/ + +/** +@defgroup spantree Minimum Spanning Tree Algorithms +@ingroup algs +\brief Algorithms for finding minimum cost spanning trees and arborescences. + +This group contains the algorithms for finding minimum cost spanning +trees and arborescences \ref clrs01algorithms. +*/ + +/** +@defgroup max_flow Maximum Flow Algorithms +@ingroup algs +\brief Algorithms for finding maximum flows. + +This group contains the algorithms for finding maximum flows and +feasible circulations \ref clrs01algorithms, \ref amo93networkflows. + +The \e maximum \e flow \e problem is to find a flow of maximum value between +a single source and a single target. Formally, there is a \f$G=(V,A)\f$ +digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and +\f$s, t \in V\f$ source and target nodes. +A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the +following optimization problem. + +\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f] +\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu) + \quad \forall u\in V\setminus\{s,t\} \f] +\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f] + +\ref Preflow is an efficient implementation of Goldberg-Tarjan's +preflow push-relabel algorithm \ref goldberg88newapproach for finding +maximum flows. It also provides functions to query the minimum cut, +which is the dual problem of maximum flow. + +\ref Circulation is a preflow push-relabel algorithm implemented directly +for finding feasible circulations, which is a somewhat different problem, +but it is strongly related to maximum flow. +For more information, see \ref Circulation. +*/ + +/** +@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms +@ingroup algs + +\brief Algorithms for finding minimum cost flows and circulations. + +This group contains the algorithms for finding minimum cost flows and +circulations \ref amo93networkflows. For more information about this +problem and its dual solution, see \ref min_cost_flow +"Minimum Cost Flow Problem". + +LEMON contains several algorithms for this problem. + - \ref NetworkSimplex Primal Network Simplex algorithm with various + pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex. + - \ref CostScaling Cost Scaling algorithm based on push/augment and + relabel operations \ref goldberg90approximation, \ref goldberg97efficient, + \ref bunnagel98efficient. + - \ref CapacityScaling Capacity Scaling algorithm based on the successive + shortest path method \ref edmondskarp72theoretical. + - \ref CycleCanceling Cycle-Canceling algorithms, two of which are + strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling. + +In general NetworkSimplex is the most efficient implementation, +but in special cases other algorithms could be faster. +For example, if the total supply and/or capacities are rather small, +CapacityScaling is usually the fastest algorithm (without effective scaling). +*/ + +/** +@defgroup min_cut Minimum Cut Algorithms +@ingroup algs + +\brief Algorithms for finding minimum cut in graphs. + +This group contains the algorithms for finding minimum cut in graphs. + +The \e minimum \e cut \e problem is to find a non-empty and non-complete +\f$X\f$ subset of the nodes with minimum overall capacity on +outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a +\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum +cut is the \f$X\f$ solution of the next optimization problem: + +\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}} + \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f] + +LEMON contains several algorithms related to minimum cut problems: + +- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut + in directed graphs. +- \ref GomoryHu "Gomory-Hu tree computation" for calculating + all-pairs minimum cut in undirected graphs. + +If you want to find minimum cut just between two distinict nodes, +see the \ref max_flow "maximum flow problem". +*/ + +/** +@defgroup min_mean_cycle Minimum Mean Cycle Algorithms +@ingroup algs +\brief Algorithms for finding minimum mean cycles. + +This group contains the algorithms for finding minimum mean cycles +\ref clrs01algorithms, \ref amo93networkflows. + +The \e minimum \e mean \e cycle \e problem is to find a directed cycle +of minimum mean length (cost) in a digraph. +The mean length of a cycle is the average length of its arcs, i.e. the +ratio between the total length of the cycle and the number of arcs on it. + +This problem has an important connection to \e conservative \e length +\e functions, too. A length function on the arcs of a digraph is called +conservative if and only if there is no directed cycle of negative total +length. For an arbitrary length function, the negative of the minimum +cycle mean is the smallest \f$\epsilon\f$ value so that increasing the +arc lengths uniformly by \f$\epsilon\f$ results in a conservative length +function. + +LEMON contains three algorithms for solving the minimum mean cycle problem: +- \ref KarpMmc Karp's original algorithm \ref amo93networkflows, + \ref dasdan98minmeancycle. +- \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved + version of Karp's algorithm \ref dasdan98minmeancycle. +- \ref HowardMmc Howard's policy iteration algorithm + \ref dasdan98minmeancycle. + +In practice, the \ref HowardMmc "Howard" algorithm proved to be by far the +most efficient one, though the best known theoretical bound on its running +time is exponential. +Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms +run in time O(ne) and use space O(n2+e), but the latter one is +typically faster due to the applied early termination scheme. +*/ + +/** +@defgroup matching Matching Algorithms +@ingroup algs +\brief Algorithms for finding matchings in graphs and bipartite graphs. + +This group contains the algorithms for calculating +matchings in graphs and bipartite graphs. The general matching problem is +finding a subset of the edges for which each node has at most one incident +edge. + +There are several different algorithms for calculate matchings in +graphs. The matching problems in bipartite graphs are generally +easier than in general graphs. The goal of the matching optimization +can be finding maximum cardinality, maximum weight or minimum cost +matching. The search can be constrained to find perfect or +maximum cardinality matching. + +The matching algorithms implemented in LEMON: +- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating + maximum cardinality matching in general graphs. +- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating + maximum weighted matching in general graphs. +- \ref MaxWeightedPerfectMatching + Edmond's blossom shrinking algorithm for calculating maximum weighted + perfect matching in general graphs. +- \ref MaxFractionalMatching Push-relabel algorithm for calculating + maximum cardinality fractional matching in general graphs. +- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating + maximum weighted fractional matching in general graphs. +- \ref MaxWeightedPerfectFractionalMatching + Augmenting path algorithm for calculating maximum weighted + perfect fractional matching in general graphs. + +\image html matching.png +\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth +*/ + +/** +@defgroup graph_properties Connectivity and Other Graph Properties +@ingroup algs +\brief Algorithms for discovering the graph properties + +This group contains the algorithms for discovering the graph properties +like connectivity, bipartiteness, euler property, simplicity etc. + +\image html connected_components.png +\image latex connected_components.eps "Connected components" width=\textwidth +*/ + +/** +@defgroup planar Planarity Embedding and Drawing +@ingroup algs +\brief Algorithms for planarity checking, embedding and drawing + +This group contains the algorithms for planarity checking, +embedding and drawing. + +\image html planar.png +\image latex planar.eps "Plane graph" width=\textwidth +*/ + +/** +@defgroup auxalg Auxiliary Algorithms +@ingroup algs +\brief Auxiliary algorithms implemented in LEMON. + +This group contains some algorithms implemented in LEMON +in order to make it easier to implement complex algorithms. +*/ + +/** +@defgroup gen_opt_group General Optimization Tools +\brief This group contains some general optimization frameworks +implemented in LEMON. + +This group contains some general optimization frameworks +implemented in LEMON. +*/ + +/** +@defgroup lp_group LP and MIP Solvers +@ingroup gen_opt_group +\brief LP and MIP solver interfaces for LEMON. + +This group contains LP and MIP solver interfaces for LEMON. +Various LP solvers could be used in the same manner with this +high-level interface. + +The currently supported solvers are \ref glpk, \ref clp, \ref cbc, +\ref cplex, \ref soplex. +*/ + +/** +@defgroup utils Tools and Utilities +\brief Tools and utilities for programming in LEMON + +Tools and utilities for programming in LEMON. +*/ + +/** +@defgroup gutils Basic Graph Utilities +@ingroup utils +\brief Simple basic graph utilities. + +This group contains some simple basic graph utilities. +*/ + +/** +@defgroup misc Miscellaneous Tools +@ingroup utils +\brief Tools for development, debugging and testing. + +This group contains several useful tools for development, +debugging and testing. +*/ + +/** +@defgroup timecount Time Measuring and Counting +@ingroup misc +\brief Simple tools for measuring the performance of algorithms. + +This group contains simple tools for measuring the performance +of algorithms. +*/ + +/** +@defgroup exceptions Exceptions +@ingroup utils +\brief Exceptions defined in LEMON. + +This group contains the exceptions defined in LEMON. +*/ + +/** +@defgroup io_group Input-Output +\brief Graph Input-Output methods + +This group contains the tools for importing and exporting graphs +and graph related data. Now it supports the \ref lgf-format +"LEMON Graph Format", the \c DIMACS format and the encapsulated +postscript (EPS) format. +*/ + +/** +@defgroup lemon_io LEMON Graph Format +@ingroup io_group +\brief Reading and writing LEMON Graph Format. + +This group contains methods for reading and writing +\ref lgf-format "LEMON Graph Format". +*/ + +/** +@defgroup eps_io Postscript Exporting +@ingroup io_group +\brief General \c EPS drawer and graph exporter + +This group contains general \c EPS drawing methods and special +graph exporting tools. +*/ + +/** +@defgroup dimacs_group DIMACS Format +@ingroup io_group +\brief Read and write files in DIMACS format + +Tools to read a digraph from or write it to a file in DIMACS format data. +*/ + +/** +@defgroup nauty_group NAUTY Format +@ingroup io_group +\brief Read \e Nauty format + +Tool to read graphs from \e Nauty format data. +*/ + +/** +@defgroup concept Concepts +\brief Skeleton classes and concept checking classes + +This group contains the data/algorithm skeletons and concept checking +classes implemented in LEMON. + +The purpose of the classes in this group is fourfold. + +- These classes contain the documentations of the %concepts. In order + to avoid document multiplications, an implementation of a concept + simply refers to the corresponding concept class. + +- These classes declare every functions, typedefs etc. an + implementation of the %concepts should provide, however completely + without implementations and real data structures behind the + interface. On the other hand they should provide nothing else. All + the algorithms working on a data structure meeting a certain concept + should compile with these classes. (Though it will not run properly, + of course.) In this way it is easily to check if an algorithm + doesn't use any extra feature of a certain implementation. + +- The concept descriptor classes also provide a checker class + that makes it possible to check whether a certain implementation of a + concept indeed provides all the required features. + +- Finally, They can serve as a skeleton of a new implementation of a concept. +*/ + +/** +@defgroup graph_concepts Graph Structure Concepts +@ingroup concept +\brief Skeleton and concept checking classes for graph structures + +This group contains the skeletons and concept checking classes of +graph structures. +*/ + +/** +@defgroup map_concepts Map Concepts +@ingroup concept +\brief Skeleton and concept checking classes for maps + +This group contains the skeletons and concept checking classes of maps. +*/ + +/** +@defgroup tools Standalone Utility Applications + +Some utility applications are listed here. + +The standard compilation procedure (./configure;make) will compile +them, as well. +*/ + +/** +\anchor demoprograms + +@defgroup demos Demo Programs + +Some demo programs are listed here. Their full source codes can be found in +the \c demo subdirectory of the source tree. + +In order to compile them, use the make demo or the +make check commands. +*/ + +} diff --git a/lemon/doc/images/bipartite_matching.eps b/lemon/doc/images/bipartite_matching.eps new file mode 100644 index 0000000..b5683cb --- /dev/null +++ b/lemon/doc/images/bipartite_matching.eps @@ -0,0 +1,586 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 15 18 829 570 +%%HiResBoundingBox: 15.1913 18.4493 828.078 569.438 +%%Creator: Karbon14 EPS Exportfilter 0.5 +%%CreationDate: (04/15/06 15:20:26) +%%For: (Balazs Dezso) () +%%Title: () + +/N {newpath} def +/C {closepath} def +/m {moveto} def +/c {curveto} def +/l {lineto} def +/s {stroke} def +/f {fill} def +/w {setlinewidth} def +/d {setdash} def +/r {setrgbcolor} def +/S {gsave} def +/R {grestore} def + +N +251.402 32.047 m +532.945 293.946 814.484 555.844 814.484 555.844 c +[] 0 d 1 0 0 r 3.92814 w s + +N +749.012 32.047 m +742.465 293.946 735.918 555.844 735.918 555.844 c +[] 0 d 0 0 0 r 1.96407 w s + +N +539.492 32.047 m +637.703 293.946 735.918 555.844 735.918 555.844 c +[] 0 d 0 0 0 r 1.96407 w s + +N +172.832 32.047 m +454.375 293.946 735.918 555.844 735.918 555.844 c +[] 0 d 0 0 0 r 1.96407 w s + +N +107.355 32.047 m +421.637 293.946 735.918 555.844 735.918 555.844 c +[] 0 d 1 0 0 r 3.92814 w s + +N +644.25 555.844 m +696.633 293.946 749.012 32.047 749.012 32.047 c +[] 0 d 0 0 0 r 1.96407 w s + +N +474.016 555.844 m +611.516 293.946 749.012 32.047 749.012 32.047 c +[] 0 d 1 0 0 r 3.92814 w s + +N +683.535 32.047 m +663.894 293.946 644.25 555.844 644.25 555.844 c +[] 0 d 0 0 0 r 1.96407 w s + +N +120.453 555.844 m +401.992 293.946 683.535 32.047 683.535 32.047 c +[] 0 d 0 0 0 r 1.96407 w s + +N +28.7853 555.844 m +356.16 293.946 683.535 32.047 683.535 32.047 c +[] 0 d 1 0 0 r 3.92814 w s + +N +539.492 32.047 m +546.039 293.946 552.586 555.844 552.586 555.844 c +[] 0 d 1 0 0 r 3.92814 w s + +N +316.875 32.047 m +349.613 293.946 382.351 555.844 382.351 555.844 c +[] 0 d 1 0 0 r 3.92814 w s + +N +107.355 32.047 m +244.855 293.946 382.351 555.844 382.351 555.844 c +[] 0 d 0 0 0 r 1.96407 w s + +N +290.687 555.844 m +375.805 293.946 460.922 32.047 460.922 32.047 c +[] 0 d 1 0 0 r 3.92814 w s + +N +120.453 555.844 m +290.687 293.946 460.922 32.047 460.922 32.047 c +[] 0 d 0 0 0 r 1.96407 w s + +N +172.832 32.047 m +146.64 293.946 120.453 555.844 120.453 555.844 c +[] 0 d 1 0 0 r 3.92814 w s + +N +15.6913 555.844 m +15.6913 555.844 l +15.6913 548.614 21.5553 542.75 28.7853 542.75 c +36.0163 542.75 41.8833 548.614 41.8833 555.844 c +41.8833 563.075 36.0163 568.938 28.7853 568.938 c +21.5553 568.938 15.6913 563.075 15.6913 555.844 c +15.6913 555.844 l +C +S 0 0 0 r f R + +N +16.8833 555.844 m +16.8833 555.844 l +16.8833 549.27 22.2113 543.942 28.7853 543.942 c +35.3593 543.942 40.6913 549.27 40.6913 555.844 c +40.6913 562.418 35.3593 567.747 28.7853 567.747 c +22.2113 567.747 16.8833 562.418 16.8833 555.844 c +16.8833 555.844 l +C +S 1 0.5 1 r f R + +N +107.355 555.844 m +107.355 555.844 l +107.355 548.614 113.223 542.75 120.453 542.75 c +127.683 542.75 133.547 548.614 133.547 555.844 c +133.547 563.075 127.683 568.938 120.453 568.938 c +113.223 568.938 107.355 563.075 107.355 555.844 c +107.355 555.844 l +C +S 0 0 0 r f R + +N +108.547 555.844 m +108.547 555.844 l +108.547 549.27 113.879 543.942 120.453 543.942 c +127.027 543.942 132.355 549.27 132.355 555.844 c +132.355 562.418 127.027 567.747 120.453 567.747 c +113.879 567.747 108.547 562.418 108.547 555.844 c +108.547 555.844 l +C +S 1 0 1 r f R + +N +199.019 555.844 m +199.019 555.844 l +199.019 548.614 204.887 542.75 212.117 542.75 c +219.348 542.75 225.211 548.614 225.211 555.844 c +225.211 563.075 219.348 568.938 212.117 568.938 c +204.887 568.938 199.019 563.075 199.019 555.844 c +199.019 555.844 l +C +S 0 0 0 r f R + +N +200.211 555.844 m +200.211 555.844 l +200.211 549.27 205.543 543.942 212.117 543.942 c +218.691 543.942 224.019 549.27 224.019 555.844 c +224.019 562.418 218.691 567.747 212.117 567.747 c +205.543 567.747 200.211 562.418 200.211 555.844 c +200.211 555.844 l +C +S 1 0.5 1 r f R + +N +277.59 555.844 m +277.59 555.844 l +277.59 548.614 283.457 542.75 290.687 542.75 c +297.918 542.75 303.781 548.614 303.781 555.844 c +303.781 563.075 297.918 568.938 290.687 568.938 c +283.457 568.938 277.59 563.075 277.59 555.844 c +277.59 555.844 l +C +S 0 0 0 r f R + +N +278.781 555.844 m +278.781 555.844 l +278.781 549.27 284.113 543.942 290.687 543.942 c +297.262 543.942 302.59 549.27 302.59 555.844 c +302.59 562.418 297.262 567.747 290.687 567.747 c +284.113 567.747 278.781 562.418 278.781 555.844 c +278.781 555.844 l +C +S 1 0 1 r f R + +N +369.258 555.844 m +369.258 555.844 l +369.258 548.614 375.121 542.75 382.351 542.75 c +389.582 542.75 395.445 548.614 395.445 555.844 c +395.445 563.075 389.582 568.938 382.351 568.938 c +375.121 568.938 369.258 563.075 369.258 555.844 c +369.258 555.844 l +C +S 0 0 0 r f R + +N +370.445 555.844 m +370.445 555.844 l +370.445 549.27 375.777 543.942 382.351 543.942 c +388.926 543.942 394.258 549.27 394.258 555.844 c +394.258 562.418 388.926 567.747 382.351 567.747 c +375.777 567.747 370.445 562.418 370.445 555.844 c +370.445 555.844 l +C +S 1 0 1 r f R + +N +460.922 555.844 m +460.922 555.844 l +460.922 548.614 466.785 542.75 474.016 542.75 c +481.246 542.75 487.109 548.614 487.109 555.844 c +487.109 563.075 481.246 568.938 474.016 568.938 c +466.785 568.938 460.922 563.075 460.922 555.844 c +460.922 555.844 l +C +S 0 0 0 r f R + +N +462.113 555.844 m +462.113 555.844 l +462.113 549.27 467.441 543.942 474.016 543.942 c +480.59 543.942 485.922 549.27 485.922 555.844 c +485.922 562.418 480.59 567.747 474.016 567.747 c +467.441 567.747 462.113 562.418 462.113 555.844 c +462.113 555.844 l +C +S 1 0.5 1 r f R + +N +539.492 555.844 m +539.492 555.844 l +539.492 548.614 545.355 542.75 552.586 542.75 c +559.816 542.75 565.68 548.614 565.68 555.844 c +565.68 563.075 559.816 568.938 552.586 568.938 c +545.355 568.938 539.492 563.075 539.492 555.844 c +539.492 555.844 l +C +S 0 0 0 r f R + +N +540.683 555.844 m +540.683 555.844 l +540.683 549.27 546.012 543.942 552.586 543.942 c +559.16 543.942 564.492 549.27 564.492 555.844 c +564.492 562.418 559.16 567.747 552.586 567.747 c +546.012 567.747 540.683 562.418 540.683 555.844 c +540.683 555.844 l +C +S 1 0 1 r f R + +N +631.156 555.844 m +631.156 555.844 l +631.156 548.614 637.019 542.75 644.25 542.75 c +651.48 542.75 657.348 548.614 657.348 555.844 c +657.348 563.075 651.48 568.938 644.25 568.938 c +637.019 568.938 631.156 563.075 631.156 555.844 c +631.156 555.844 l +C +S 0 0 0 r f R + +N +632.348 555.844 m +632.348 555.844 l +632.348 549.27 637.676 543.942 644.25 543.942 c +650.824 543.942 656.156 549.27 656.156 555.844 c +656.156 562.418 650.824 567.747 644.25 567.747 c +637.676 567.747 632.348 562.418 632.348 555.844 c +632.348 555.844 l +C +S 1 0.5 1 r f R + +N +722.82 555.844 m +722.82 555.844 l +722.82 548.614 728.687 542.75 735.918 542.75 c +743.149 542.75 749.012 548.614 749.012 555.844 c +749.012 563.075 743.149 568.938 735.918 568.938 c +728.687 568.938 722.82 563.075 722.82 555.844 c +722.82 555.844 l +C +S 0 0 0 r f R + +N +724.012 555.844 m +724.012 555.844 l +724.012 549.27 729.344 543.942 735.918 543.942 c +742.492 543.942 747.82 549.27 747.82 555.844 c +747.82 562.418 742.492 567.747 735.918 567.747 c +729.344 567.747 724.012 562.418 724.012 555.844 c +724.012 555.844 l +C +S 1 0 1 r f R + +N +801.391 555.844 m +801.391 555.844 l +801.391 548.614 807.254 542.75 814.484 542.75 c +821.715 542.75 827.578 548.614 827.578 555.844 c +827.578 563.075 821.715 568.938 814.484 568.938 c +807.254 568.938 801.391 563.075 801.391 555.844 c +801.391 555.844 l +C +S 0 0 0 r f R + +N +802.582 555.844 m +802.582 555.844 l +802.582 549.27 807.91 543.942 814.484 543.942 c +821.059 543.942 826.387 549.27 826.387 555.844 c +826.387 562.418 821.059 567.747 814.484 567.747 c +807.91 567.747 802.582 562.418 802.582 555.844 c +802.582 555.844 l +C +S 1 0 1 r f R + +N +15.6913 32.047 m +15.6913 32.047 l +15.6913 24.8165 21.5553 18.9493 28.7853 18.9493 c +36.0163 18.9493 41.8833 24.8165 41.8833 32.047 c +41.8833 39.2775 36.0163 45.1407 28.7853 45.1407 c +21.5553 45.1407 15.6913 39.2775 15.6913 32.047 c +15.6913 32.047 l +C +S 0 0 0 r f R + +N +16.8833 32.047 m +16.8833 32.047 l +16.8833 25.4728 22.2113 20.1407 28.7853 20.1407 c +35.3593 20.1407 40.6913 25.4728 40.6913 32.047 c +40.6913 38.6212 35.3593 43.9493 28.7853 43.9493 c +22.2113 43.9493 16.8833 38.6212 16.8833 32.047 c +16.8833 32.047 l +C +S 0.5 0.5 1 r f R + +N +94.2623 32.047 m +94.2623 32.047 l +94.2623 24.8165 100.125 18.9493 107.355 18.9493 c +114.586 18.9493 120.453 24.8165 120.453 32.047 c +120.453 39.2775 114.586 45.1407 107.355 45.1407 c +100.125 45.1407 94.2623 39.2775 94.2623 32.047 c +94.2623 32.047 l +C +S 0 0 0 r f R + +N +95.4533 32.047 m +95.4533 32.047 l +95.4533 25.4728 100.781 20.1407 107.355 20.1407 c +113.93 20.1407 119.262 25.4728 119.262 32.047 c +119.262 38.6212 113.93 43.9493 107.355 43.9493 c +100.781 43.9493 95.4533 38.6212 95.4533 32.047 c +95.4533 32.047 l +C +S 0.5 0.5 1 r f R + +N +159.734 32.047 m +159.734 32.047 l +159.734 24.8165 165.601 18.9493 172.832 18.9493 c +180.062 18.9493 185.926 24.8165 185.926 32.047 c +185.926 39.2775 180.062 45.1407 172.832 45.1407 c +165.601 45.1407 159.734 39.2775 159.734 32.047 c +159.734 32.047 l +C +S 0 0 0 r f R + +N +160.926 32.047 m +160.926 32.047 l +160.926 25.4728 166.258 20.1407 172.832 20.1407 c +179.406 20.1407 184.734 25.4728 184.734 32.047 c +184.734 38.6212 179.406 43.9493 172.832 43.9493 c +166.258 43.9493 160.926 38.6212 160.926 32.047 c +160.926 32.047 l +C +S 0.5 0.5 1 r f R + +N +238.305 32.047 m +238.305 32.047 l +238.305 24.8165 244.172 18.9493 251.402 18.9493 c +258.633 18.9493 264.496 24.8165 264.496 32.047 c +264.496 39.2775 258.633 45.1407 251.402 45.1407 c +244.172 45.1407 238.305 39.2775 238.305 32.047 c +238.305 32.047 l +C +S 0 0 0 r f R + +N +239.496 32.047 m +239.496 32.047 l +239.496 25.4728 244.828 20.1407 251.402 20.1407 c +257.976 20.1407 263.305 25.4728 263.305 32.047 c +263.305 38.6212 257.976 43.9493 251.402 43.9493 c +244.828 43.9493 239.496 38.6212 239.496 32.047 c +239.496 32.047 l +C +S 0.5 0.5 1 r f R + +N +303.781 32.047 m +303.781 32.047 l +303.781 24.8165 309.644 18.9493 316.875 18.9493 c +324.105 18.9493 329.973 24.8165 329.973 32.047 c +329.973 39.2775 324.105 45.1407 316.875 45.1407 c +309.644 45.1407 303.781 39.2775 303.781 32.047 c +303.781 32.047 l +C +S 0 0 0 r f R + +N +304.973 32.047 m +304.973 32.047 l +304.973 25.4728 310.301 20.1407 316.875 20.1407 c +323.449 20.1407 328.781 25.4728 328.781 32.047 c +328.781 38.6212 323.449 43.9493 316.875 43.9493 c +310.301 43.9493 304.973 38.6212 304.973 32.047 c +304.973 32.047 l +C +S 0.5 0.5 1 r f R + +N +382.351 32.047 m +382.351 32.047 l +382.351 24.8165 388.215 18.9493 395.445 18.9493 c +402.676 18.9493 408.543 24.8165 408.543 32.047 c +408.543 39.2775 402.676 45.1407 395.445 45.1407 c +388.215 45.1407 382.351 39.2775 382.351 32.047 c +382.351 32.047 l +C +S 0 0 0 r f R + +N +383.543 32.047 m +383.543 32.047 l +383.543 25.4728 388.871 20.1407 395.445 20.1407 c +402.019 20.1407 407.351 25.4728 407.351 32.047 c +407.351 38.6212 402.019 43.9493 395.445 43.9493 c +388.871 43.9493 383.543 38.6212 383.543 32.047 c +383.543 32.047 l +C +S 0.5 0.5 1 r f R + +N +447.828 32.047 m +447.828 32.047 l +447.828 24.8165 453.691 18.9493 460.922 18.9493 c +468.152 18.9493 474.016 24.8165 474.016 32.047 c +474.016 39.2775 468.152 45.1407 460.922 45.1407 c +453.691 45.1407 447.828 39.2775 447.828 32.047 c +447.828 32.047 l +C +S 0 0 0 r f R + +N +449.016 32.047 m +449.016 32.047 l +449.016 25.4728 454.348 20.1407 460.922 20.1407 c +467.496 20.1407 472.824 25.4728 472.824 32.047 c +472.824 38.6212 467.496 43.9493 460.922 43.9493 c +454.348 43.9493 449.016 38.6212 449.016 32.047 c +449.016 32.047 l +C +S 0.5 0.5 1 r f R + +N +526.394 32.047 m +526.394 32.047 l +526.394 24.8165 532.262 18.9493 539.492 18.9493 c +546.723 18.9493 552.586 24.8165 552.586 32.047 c +552.586 39.2775 546.723 45.1407 539.492 45.1407 c +532.262 45.1407 526.394 39.2775 526.394 32.047 c +526.394 32.047 l +C +S 0 0 0 r f R + +N +527.586 32.047 m +527.586 32.047 l +527.586 25.4728 532.918 20.1407 539.492 20.1407 c +546.066 20.1407 551.394 25.4728 551.394 32.047 c +551.394 38.6212 546.066 43.9493 539.492 43.9493 c +532.918 43.9493 527.586 38.6212 527.586 32.047 c +527.586 32.047 l +C +S 0.5 0.5 1 r f R + +N +591.871 32.047 m +591.871 32.047 l +591.871 24.8165 597.734 18.9493 604.965 18.9493 c +612.195 18.9493 618.062 24.8165 618.062 32.047 c +618.062 39.2775 612.195 45.1407 604.965 45.1407 c +597.734 45.1407 591.871 39.2775 591.871 32.047 c +591.871 32.047 l +C +S 0 0 0 r f R + +N +593.062 32.047 m +593.062 32.047 l +593.062 25.4728 598.39 20.1407 604.965 20.1407 c +611.539 20.1407 616.871 25.4728 616.871 32.047 c +616.871 38.6212 611.539 43.9493 604.965 43.9493 c +598.39 43.9493 593.062 38.6212 593.062 32.047 c +593.062 32.047 l +C +S 0.5 0.5 1 r f R + +N +670.441 32.047 m +670.441 32.047 l +670.441 24.8165 676.305 18.9493 683.535 18.9493 c +690.766 18.9493 696.633 24.8165 696.633 32.047 c +696.633 39.2775 690.766 45.1407 683.535 45.1407 c +676.305 45.1407 670.441 39.2775 670.441 32.047 c +670.441 32.047 l +C +S 0 0 0 r f R + +N +671.633 32.047 m +671.633 32.047 l +671.633 25.4728 676.961 20.1407 683.535 20.1407 c +690.109 20.1407 695.441 25.4728 695.441 32.047 c +695.441 38.6212 690.109 43.9493 683.535 43.9493 c +676.961 43.9493 671.633 38.6212 671.633 32.047 c +671.633 32.047 l +C +S 0 0 1 r f R + +N +735.918 32.047 m +735.918 32.047 l +735.918 24.8165 741.781 18.9493 749.012 18.9493 c +756.242 18.9493 762.106 24.8165 762.106 32.047 c +762.106 39.2775 756.242 45.1407 749.012 45.1407 c +741.781 45.1407 735.918 39.2775 735.918 32.047 c +735.918 32.047 l +C +S 0 0 0 r f R + +N +737.105 32.047 m +737.105 32.047 l +737.105 25.4728 742.437 20.1407 749.012 20.1407 c +755.586 20.1407 760.914 25.4728 760.914 32.047 c +760.914 38.6212 755.586 43.9493 749.012 43.9493 c +742.437 43.9493 737.105 38.6212 737.105 32.047 c +737.105 32.047 l +C +S 0 0 1 r f R + +N +801.391 32.047 m +801.391 32.047 l +801.391 24.8165 807.254 18.9493 814.484 18.9493 c +821.715 18.9493 827.578 24.8165 827.578 32.047 c +827.578 39.2775 821.715 45.1407 814.484 45.1407 c +807.254 45.1407 801.391 39.2775 801.391 32.047 c +801.391 32.047 l +C +S 0 0 0 r f R + +N +802.582 32.047 m +802.582 32.047 l +802.582 25.4728 807.91 20.1407 814.484 20.1407 c +821.059 20.1407 826.387 25.4728 826.387 32.047 c +826.387 38.6212 821.059 43.9493 814.484 43.9493 c +807.91 43.9493 802.582 38.6212 802.582 32.047 c +802.582 32.047 l +C +S 0.5 0.5 1 r f R + +%%EOF diff --git a/lemon/doc/images/bipartite_partitions.eps b/lemon/doc/images/bipartite_partitions.eps new file mode 100644 index 0000000..5ff348d --- /dev/null +++ b/lemon/doc/images/bipartite_partitions.eps @@ -0,0 +1,114 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: LEMON, graphToEps() +%%CreationDate: Tue Nov 15 16:51:43 2005 +%%BoundingBox: 0 0 842 596 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +90 rotate +0 -842 translate +71.6378 15 translate +0.389093 dup scale +90 rotate +1197.47 -613.138 translate +%Edges: +gsave +513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb +513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb +393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb +393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb +393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb +869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb +869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb +-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb +-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb +-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb +-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb +-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb +-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb +-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb +-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb +-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb +-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb +-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb +79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb +637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb +205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb +399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb +399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb +-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb +-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb +-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb +-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb +-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb +-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb +120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb +grestore +%Nodes: +gsave +-274 -131 20 1 0 0 nc +-607.82 -246.651 20 1 0 0 nc +-484.494 328.869 20 0 0 1 nc +108.644 334.741 20 0 0 1 nc +120.389 -129.198 20 0 0 1 nc +-99.8351 99.8351 20 1 0 0 nc +-211.415 -452.194 20 1 0 0 nc +-860.344 -29.3633 20 0 0 1 nc +-842.726 243.715 20 0 0 1 nc +399.34 88.0898 20 1 0 0 nc +205.543 -322.996 20 1 0 0 nc +637.183 -184.989 20 0 0 1 nc +79.2808 -528.539 20 0 0 1 nc +-499.175 -499.175 20 0 0 1 nc +-880.898 -528.539 20 0 0 1 nc +-1177.47 -234.906 20 1 0 0 nc +-1077.63 161.498 20 1 0 0 nc +-663.61 546.157 20 1 0 0 nc +-82.2171 593.138 20 0 0 1 nc +596.074 302.442 20 0 0 1 nc +869.153 52.8539 20 1 0 0 nc +393.468 566.711 20 1 0 0 nc +513.857 -446.322 20 1 0 0 nc +grestore +grestore +showpage diff --git a/lemon/doc/images/connected_components.eps b/lemon/doc/images/connected_components.eps new file mode 100644 index 0000000..6690733 --- /dev/null +++ b/lemon/doc/images/connected_components.eps @@ -0,0 +1,159 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: LEMON, graphToEps() +%%CreationDate: Fri Nov 4 13:47:12 2005 +%%BoundingBox: 0 0 842 596 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +90 rotate +0 -842 translate +71.0944 15 translate +0.434694 dup scale +90 rotate +860.856 -588.349 translate +%Edges: +gsave +574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb +694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb +422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb +670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb +670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb +588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb +grestore +%Nodes: +gsave +-567.302 43.6423 20 0 0 0 nc +-689.204 -237.261 20 0 0 0 nc +924.667 409.347 20 1 0 0 nc +588.113 544.499 20 1 0 0 nc +670.264 274.195 20 1 0 0 nc +-371.2 568.349 20 0 1 0 nc +-132.697 451.748 20 0 1 0 nc +-416.25 345.746 20 0 1 0 nc +-180.397 245.045 20 0 1 0 nc +-13.4452 133.743 20 0 1 0 nc +-262.548 107.243 20 0 1 0 nc +201.208 38.3422 20 0 1 0 nc +116.407 -173.66 20 0 1 0 nc +-26.6953 -19.9585 20 0 1 0 nc +-539.894 -262.64 20 0 0 1 nc +-323.543 -433.964 20 0 0 1 nc +-309.657 -57.9033 20 0 0 1 nc +-67.9734 -347.42 20 0 0 1 nc +415.393 -289.516 20 0 0 1 nc +730.084 -307.139 20 0 0 1 nc +526.164 32.7279 20 0 0 1 nc +762.812 -17.6227 20 0 0 1 nc +-67.9734 319.727 20 0 0 1 nc +329.797 314.692 20 0 0 1 nc +-5.03507 561.41 20 0 0 1 nc +422.945 521.129 20 0 0 1 nc +-470.779 158.605 20 0 0 1 nc +986.873 -115.807 20 0 0 1 nc +906.312 201.403 20 0 0 1 nc +-767.847 113.289 20 0 0 1 nc +-579.033 445.603 20 0 0 1 nc +-840.856 -246.718 20 0 0 1 nc +206.221 -205.967 20 1 1 0 nc +277.311 -252.33 20 1 1 0 nc +271.13 -175.058 20 1 1 0 nc +366.947 -110.15 20 1 1 0 nc +397.855 -196.694 20 1 1 0 nc +438.037 -88.514 20 1 1 0 nc +286.584 -48.3327 20 1 1 0 nc +212.403 -23.6057 20 1 1 0 nc +280.402 10.3938 20 1 1 0 nc +694.579 115.483 20 1 0 0 nc +574.035 177.301 20 1 0 0 nc +grestore +grestore +showpage diff --git a/lemon/doc/images/edge_biconnected_components.eps b/lemon/doc/images/edge_biconnected_components.eps new file mode 100644 index 0000000..a42d352 --- /dev/null +++ b/lemon/doc/images/edge_biconnected_components.eps @@ -0,0 +1,159 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: LEMON, graphToEps() +%%CreationDate: Fri Nov 4 13:47:12 2005 +%%BoundingBox: 0 0 842 596 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +90 rotate +0 -842 translate +71.0944 15 translate +0.434694 dup scale +90 rotate +860.856 -588.349 translate +%Edges: +gsave +574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb +286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb +438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb +438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb +397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb +366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb +271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb +271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb +277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb +906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb +422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb +422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb +422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb +329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb +-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb +526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb +730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb +116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb +-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb +-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb +-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb +-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb +-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb +-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb +-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb +-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb +-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb +grestore +%Nodes: +gsave +-567.302 43.6423 20 0 0 0 nc +-689.204 -237.261 20 0 0 0 nc +924.667 409.347 20 0 0 1 nc +588.113 544.499 20 0 0 1 nc +670.264 274.195 20 0 0 1 nc +-371.2 568.349 20 1 1 0 nc +-132.697 451.748 20 1 1 0 nc +-416.25 345.746 20 1 1 0 nc +-180.397 245.045 20 1 1 0 nc +-13.4452 133.743 20 1 1 0 nc +-262.548 107.243 20 1 1 0 nc +201.208 38.3422 20 1 1 0 nc +116.407 -173.66 20 1 1 0 nc +-26.6953 -19.9585 20 1 1 0 nc +-539.894 -262.64 20 0 0.5 0 nc +-323.543 -433.964 20 0 0.5 0 nc +-309.657 -57.9033 20 0 0.5 0 nc +-67.9734 -347.42 20 0 0.5 0 nc +415.393 -289.516 20 0.5 0 0 nc +730.084 -307.139 20 0.5 0 0 nc +526.164 32.7279 20 0.5 0 0 nc +762.812 -17.6227 20 0.5 0 0 nc +-67.9734 319.727 20 0.5 0 0 nc +329.797 314.692 20 0.5 0 0 nc +-5.03507 561.41 20 0.5 0 0 nc +422.945 521.129 20 0.5 0 0 nc +-470.779 158.605 20 0 1 1 nc +986.873 -115.807 20 0.5 0 0 nc +906.312 201.403 20 0.5 0 0 nc +-767.847 113.289 20 0 1 1 nc +-579.033 445.603 20 0 1 1 nc +-840.856 -246.718 20 1 0 1 nc +206.221 -205.967 20 0 0 0.5 nc +277.311 -252.33 20 0 0 0.5 nc +271.13 -175.058 20 0 0 0.5 nc +366.947 -110.15 20 0 0 0.5 nc +397.855 -196.694 20 0 0 0.5 nc +438.037 -88.514 20 0 0 0.5 nc +286.584 -48.3327 20 0 0 0.5 nc +212.403 -23.6057 20 0 0 0.5 nc +280.402 10.3938 20 0 0 0.5 nc +694.579 115.483 20 1 0 0 nc +574.035 177.301 20 0 1 0 nc +grestore +grestore +showpage diff --git a/lemon/doc/images/grid_graph.eps b/lemon/doc/images/grid_graph.eps new file mode 100644 index 0000000..6dbf477 --- /dev/null +++ b/lemon/doc/images/grid_graph.eps @@ -0,0 +1,286 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: Grid undirected graph +%%Copyright: (C) 2006 LEMON Project +%%Creator: LEMON, graphToEps() +%%CreationDate: Fri Sep 29 11:55:56 2006 +%%BoundingBox: 0 0 985 1144 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +2 2 scale +50 40 translate +5.5000 5.5000 scale +% 1.14018 1.14018 translate +%Edges: +gsave +70 80 70 90 0 0 0 0.5000 l +70 70 70 80 0 0 0 0.5000 l +70 60 70 70 0 0 0 0.5000 l +70 50 70 60 0 0 0 0.5000 l +70 40 70 50 0 0 0 0.5000 l +70 30 70 40 0 0 0 0.5000 l +70 20 70 30 0 0 0 0.5000 l +70 10 70 20 0 0 0 0.5000 l +70 0 70 10 0 0 0 0.5000 l +60 80 60 90 0 0 0 0.5000 l +60 70 60 80 0 0 0 0.5000 l +60 60 60 70 0 0 0 0.5000 l +60 50 60 60 0 0 0 0.5000 l +60 40 60 50 0 0 0 0.5000 l +60 30 60 40 0 0 0 0.5000 l +60 20 60 30 0 0 0 0.5000 l +60 10 60 20 0 0 0 0.5000 l +60 0 60 10 0 0 0 0.5000 l +50 80 50 90 0 0 0 0.5000 l +50 70 50 80 0 0 0 0.5000 l +50 60 50 70 0 0 0 0.5000 l +50 50 50 60 0 0 0 0.5000 l +50 40 50 50 0 0 0 0.5000 l +50 30 50 40 0 0 0 0.5000 l +50 20 50 30 0 0 0 0.5000 l +50 10 50 20 0 0 0 0.5000 l +50 0 50 10 0 0 0 0.5000 l +40 80 40 90 0 0 0 0.5000 l +40 70 40 80 0 0 0 0.5000 l +40 60 40 70 0 0 0 0.5000 l +40 50 40 60 0 0 0 0.5000 l +40 40 40 50 0 0 0 0.5000 l +40 30 40 40 0 0 0 0.5000 l +40 20 40 30 0 0 0 0.5000 l +40 10 40 20 0 0 0 0.5000 l +40 0 40 10 0 0 0 0.5000 l +30 80 30 90 0 0 0 0.5000 l +30 70 30 80 0 0 0 0.5000 l +30 60 30 70 0 0 0 0.5000 l +30 50 30 60 0 0 0 0.5000 l +30 40 30 50 0 0 0 0.5000 l +30 30 30 40 0 0 0 0.5000 l +30 20 30 30 0 0 0 0.5000 l +30 10 30 20 0 0 0 0.5000 l +30 0 30 10 0 0 0 0.5000 l +20 80 20 90 0 0 0 0.5000 l +20 70 20 80 0 0 0 0.5000 l +20 60 20 70 0 0 0 0.5000 l +20 50 20 60 0 0 0 0.5000 l +20 40 20 50 0 0 0 0.5000 l +20 30 20 40 0 0 0 0.5000 l +20 20 20 30 0 0 0 0.5000 l +20 10 20 20 0 0 0 0.5000 l +20 0 20 10 0 0 0 0.5000 l +10 80 10 90 0 0 0 0.5000 l +10 70 10 80 0 0 0 0.5000 l +10 60 10 70 0 0 0 0.5000 l +10 50 10 60 0 0 0 0.5000 l +10 40 10 50 0 0 0 0.5000 l +10 30 10 40 0 0 0 0.5000 l +10 20 10 30 0 0 0 0.5000 l +10 10 10 20 0 0 0 0.5000 l +10 0 10 10 0 0 0 0.5000 l +0 80 0 90 0 0 0 0.5000 l +0 70 0 80 0 0 0 0.5000 l +0 60 0 70 0 0 0 0.5000 l +0 50 0 60 0 0 0 0.5000 l +0 40 0 50 0 0 0 0.5000 l +0 30 0 40 0 0 0 0.5000 l +0 20 0 30 0 0 0 0.5000 l +0 10 0 20 0 0 0 0.5000 l +0 0 0 10 0 0 0 0.5000 l +60 90 70 90 0 0 0 0.5000 l +60 80 70 80 0 0 0 0.5000 l +60 70 70 70 0 0 0 0.5000 l +60 60 70 60 0 0 0 0.5000 l +60 50 70 50 0 0 0 0.5000 l +60 40 70 40 0 0 0 0.5000 l +60 30 70 30 0 0 0 0.5000 l +60 20 70 20 0 0 0 0.5000 l +60 10 70 10 0 0 0 0.5000 l +60 0 70 0 0 0 0 0.5000 l +50 90 60 90 0 0 0 0.5000 l +50 80 60 80 0 0 0 0.5000 l +50 70 60 70 0 0 0 0.5000 l +50 60 60 60 0 0 0 0.5000 l +50 50 60 50 0 0 0 0.5000 l +50 40 60 40 0 0 0 0.5000 l +50 30 60 30 0 0 0 0.5000 l +50 20 60 20 0 0 0 0.5000 l +50 10 60 10 0 0 0 0.5000 l +50 0 60 0 0 0 0 0.5000 l +40 90 50 90 0 0 0 0.5000 l +40 80 50 80 0 0 0 0.5000 l +40 70 50 70 0 0 0 0.5000 l +40 60 50 60 0 0 0 0.5000 l +40 50 50 50 0 0 0 0.5000 l +40 40 50 40 0 0 0 0.5000 l +40 30 50 30 0 0 0 0.5000 l +40 20 50 20 0 0 0 0.5000 l +40 10 50 10 0 0 0 0.5000 l +40 0 50 0 0 0 0 0.5000 l +30 90 40 90 0 0 0 0.5000 l +30 80 40 80 0 0 0 0.5000 l +30 70 40 70 0 0 0 0.5000 l +30 60 40 60 0 0 0 0.5000 l +30 50 40 50 0 0 0 0.5000 l +30 40 40 40 0 0 0 0.5000 l +30 30 40 30 0 0 0 0.5000 l +30 20 40 20 0 0 0 0.5000 l +30 10 40 10 0 0 0 0.5000 l +30 0 40 0 0 0 0 0.5000 l +20 90 30 90 0 0 0 0.5000 l +20 80 30 80 0 0 0 0.5000 l +20 70 30 70 0 0 0 0.5000 l +20 60 30 60 0 0 0 0.5000 l +20 50 30 50 0 0 0 0.5000 l +20 40 30 40 0 0 0 0.5000 l +20 30 30 30 0 0 0 0.5000 l +20 20 30 20 0 0 0 0.5000 l +20 10 30 10 0 0 0 0.5000 l +20 0 30 0 0 0 0 0.5000 l +10 90 20 90 0 0 0 0.5000 l +10 80 20 80 0 0 0 0.5000 l +10 70 20 70 0 0 0 0.5000 l +10 60 20 60 0 0 0 0.5000 l +10 50 20 50 0 0 0 0.5000 l +10 40 20 40 0 0 0 0.5000 l +10 30 20 30 0 0 0 0.5000 l +10 20 20 20 0 0 0 0.5000 l +10 10 20 10 0 0 0 0.5000 l +10 0 20 0 0 0 0 0.5000 l +0 90 10 90 0 0 0 0.5000 l +0 80 10 80 0 0 0 0.5000 l +0 70 10 70 0 0 0 0.5000 l +0 60 10 60 0 0 0 0.5000 l +0 50 10 50 0 0 0 0.5000 l +0 40 10 40 0 0 0 0.5000 l +0 30 10 30 0 0 0 0.5000 l +0 20 10 20 0 0 0 0.5000 l +0 10 10 10 0 0 0 0.5000 l +0 0 10 0 0 0 0 0.5000 l +grestore +%Nodes: +gsave +70 90 1.4000 0 0 0 nc +70 80 1.4000 1 1 1 nc +70 70 1.4000 1 1 1 nc +70 60 1.4000 1 1 1 nc +70 50 1.4000 1 1 1 nc +70 40 1.4000 1 1 1 nc +70 30 1.4000 1 1 1 nc +70 20 1.4000 1 1 1 nc +70 10 1.4000 1 1 1 nc +70 0 1.4000 0 0 0 nc +60 90 1.4000 1 1 1 nc +60 80 1.4000 1 1 1 nc +60 70 1.4000 1 1 1 nc +60 60 1.4000 1 1 1 nc +60 50 1.4000 1 1 1 nc +60 40 1.4000 1 1 1 nc +60 30 1.4000 1 1 1 nc +60 20 1.4000 1 1 1 nc +60 10 1.4000 1 1 1 nc +60 0 1.4000 1 1 1 nc +50 90 1.4000 1 1 1 nc +50 80 1.4000 1 1 1 nc +50 70 1.4000 1 1 1 nc +50 60 1.4000 1 1 1 nc +50 50 1.4000 1 1 1 nc +50 40 1.4000 1 1 1 nc +50 30 1.4000 1 1 1 nc +50 20 1.4000 1 1 1 nc +50 10 1.4000 1 1 1 nc +50 0 1.4000 1 1 1 nc +40 90 1.4000 1 1 1 nc +40 80 1.4000 1 1 1 nc +40 70 1.4000 1 1 1 nc +40 60 1.4000 1 1 1 nc +40 50 1.4000 1 1 1 nc +40 40 1.4000 1 1 1 nc +40 30 1.4000 1 1 1 nc +40 20 1.4000 1 1 1 nc +40 10 1.4000 1 1 1 nc +40 0 1.4000 1 1 1 nc +30 90 1.4000 1 1 1 nc +30 80 1.4000 1 1 1 nc +30 70 1.4000 1 1 1 nc +30 60 1.4000 1 1 1 nc +30 50 1.4000 1 1 1 nc +30 40 1.4000 1 1 1 nc +30 30 1.4000 1 1 1 nc +30 20 1.4000 1 1 1 nc +30 10 1.4000 1 1 1 nc +30 0 1.4000 1 1 1 nc +20 90 1.4000 1 1 1 nc +20 80 1.4000 1 1 1 nc +20 70 1.4000 1 1 1 nc +20 60 1.4000 1 1 1 nc +20 50 1.4000 1 1 1 nc +20 40 1.4000 1 1 1 nc +20 30 1.4000 1 1 1 nc +20 20 1.4000 1 1 1 nc +20 10 1.4000 1 1 1 nc +20 0 1.4000 1 1 1 nc +10 90 1.4000 1 1 1 nc +10 80 1.4000 1 1 1 nc +10 70 1.4000 1 1 1 nc +10 60 1.4000 1 1 1 nc +10 50 1.4000 1 1 1 nc +10 40 1.4000 1 1 1 nc +10 30 1.4000 1 1 1 nc +10 20 1.4000 1 1 1 nc +10 10 1.4000 1 1 1 nc +10 0 1.4000 1 1 1 nc +0 90 1.4000 0 0 0 nc +0 80 1.4000 1 1 1 nc +0 70 1.4000 1 1 1 nc +0 60 1.4000 1 1 1 nc +0 50 1.4000 1 1 1 nc +0 40 1.4000 1 1 1 nc +0 30 1.4000 1 1 1 nc +0 20 1.4000 1 1 1 nc +0 10 1.4000 1 1 1 nc +0 0 1.4000 0 0 0 nc +grestore +gsave +/fosi 3.5 def +(Helvetica) findfont fosi scalefont setfont +0 0 0 setrgbcolor +0 95 ((0,height-1)) cshow +67 95 ((width-1,height-1)) cshow +0 -5 ((0,0)) cshow +70 -5 ((width-1,0)) cshow +grestore +grestore +showpage diff --git a/lemon/doc/images/matching.eps b/lemon/doc/images/matching.eps new file mode 100644 index 0000000..2f418bd --- /dev/null +++ b/lemon/doc/images/matching.eps @@ -0,0 +1,130 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: LEMON, graphToEps() +%%CreationDate: Sun Mar 14 09:08:34 2010 +%%BoundingBox: -353 -264 559 292 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub + lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto + 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nmale { + 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto + 5 index 4 index 1 mul 1.5 mul add + 5 index 5 index 3 sqrt 1.5 mul mul add + 1 index 1 index lineto + 1 index 1 index 7 index sub moveto + 1 index 1 index lineto + exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto + stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +%Arcs: +gsave +140.321 266.249 -327.729 150.06 0 0 0 4.99223 l +82.1207 -238.726 -245.288 -110.743 0 0 0 4.99223 l +336.635 -229.036 533.603 13.109 0 0 0 4.99223 l +53.8598 -45.8071 -245.288 -110.743 0 0 0 4.99223 l +-75.5617 118.579 -327.729 150.06 0 0 0 4.99223 l +-327.729 150.06 -245.288 -110.743 1 0 0 11.9813 l +533.603 13.109 218.184 -84.2955 0 0 0 4.99223 l +39.87 175.035 141.163 67.2575 0 0 0 4.99223 l +53.8598 -45.8071 -75.5617 118.579 0 0 0 4.99223 l +-102.406 -141.267 82.1207 -238.726 0 0 0 4.99223 l +399.144 166.894 533.603 13.109 1 0 0 11.9813 l +39.87 175.035 140.321 266.249 1 0 0 11.9813 l +399.144 166.894 140.321 266.249 0 0 0 4.99223 l +399.144 166.894 141.163 67.2575 0 0 0 4.99223 l +53.8598 -45.8071 204.765 -173.77 0 0 0 4.99223 l +82.1207 -238.726 204.765 -173.77 0 0 0 4.99223 l +258.227 61.658 399.144 166.894 0 0 0 4.99223 l +53.8598 -45.8071 -102.406 -141.267 1 0 0 11.9813 l +175.073 -37.4477 141.163 67.2575 0 0 0 4.99223 l +258.227 61.658 380 0 0 0 0 4.99223 l +34.6739 40.8267 -75.5617 118.579 1 0 0 11.9813 l +380 0 533.603 13.109 0 0 0 4.99223 l +175.073 -37.4477 380 0 0 0 0 4.99223 l +218.184 -84.2955 204.765 -173.77 0 0 0 4.99223 l +53.8598 -45.8071 34.6739 40.8267 0 0 0 4.99223 l +167.905 -213.988 82.1207 -238.726 1 0 0 11.9813 l +336.635 -229.036 204.765 -173.77 1 0 0 11.9813 l +336.635 -229.036 167.905 -213.988 0 0 0 4.99223 l +329.08 -26.3098 218.184 -84.2955 0 0 0 4.99223 l +39.87 175.035 -75.5617 118.579 0 0 0 4.99223 l +53.8598 -45.8071 175.073 -37.4477 0 0 0 4.99223 l +34.6739 40.8267 141.163 67.2575 0 0 0 4.99223 l +258.227 61.658 141.163 67.2575 1 0 0 11.9813 l +175.073 -37.4477 218.184 -84.2955 1 0 0 11.9813 l +380 0 329.08 -26.3098 1 0 0 11.9813 l +grestore +%Nodes: +gsave +-245.288 -110.743 14.9767 1 1 1 nc +204.765 -173.77 14.9767 1 1 1 nc +-327.729 150.06 14.9767 1 1 1 nc +-75.5617 118.579 14.9767 1 1 1 nc +218.184 -84.2955 14.9767 1 1 1 nc +140.321 266.249 14.9767 1 1 1 nc +141.163 67.2575 14.9767 1 1 1 nc +82.1207 -238.726 14.9767 1 1 1 nc +329.08 -26.3098 14.9767 1 1 1 nc +-102.406 -141.267 14.9767 1 1 1 nc +533.603 13.109 14.9767 1 1 1 nc +167.905 -213.988 14.9767 1 1 1 nc +336.635 -229.036 14.9767 1 1 1 nc +380 0 14.9767 1 1 1 nc +399.144 166.894 14.9767 1 1 1 nc +34.6739 40.8267 14.9767 1 1 1 nc +39.87 175.035 14.9767 1 1 1 nc +175.073 -37.4477 14.9767 1 1 1 nc +53.8598 -45.8071 14.9767 1 1 1 nc +258.227 61.658 14.9767 1 1 1 nc +grestore +grestore +showpage diff --git a/lemon/doc/images/node_biconnected_components.eps b/lemon/doc/images/node_biconnected_components.eps new file mode 100644 index 0000000..a6839c0 --- /dev/null +++ b/lemon/doc/images/node_biconnected_components.eps @@ -0,0 +1,159 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: LEMON, graphToEps() +%%CreationDate: Fri Nov 4 13:47:12 2005 +%%BoundingBox: 0 0 842 596 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +90 rotate +0 -842 translate +71.0944 15 translate +0.434694 dup scale +90 rotate +860.856 -588.349 translate +%Edges: +gsave +574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5 lb +694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb +280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb +280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb +212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb +286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb +286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb +438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb +438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb +397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb +366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb +271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb +271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb +277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb +-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb +-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb +-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb +-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb +906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb +906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb +986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb +-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb +422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb +422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb +422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb +-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb +329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb +-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb +762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb +762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb +526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb +730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb +415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb +-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb +-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb +-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb +-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb +-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb +-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb +-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb +-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb +116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb +-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb +-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb +-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb +-180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb +-180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb +-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb +-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb +-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb +670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb +670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb +588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb +-689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb +-689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb +grestore +%Nodes: +gsave +-567.302 43.6423 20 0 0 1 nc +-689.204 -237.261 20 0 0 1 nc +924.667 409.347 20 0 0 1 nc +588.113 544.499 20 0 0 1 nc +670.264 274.195 20 1 0 0 nc +-371.2 568.349 20 0 0 1 nc +-132.697 451.748 20 1 0 0 nc +-416.25 345.746 20 0 0 1 nc +-180.397 245.045 20 1 0 0 nc +-13.4452 133.743 20 0 0 1 nc +-262.548 107.243 20 0 0 1 nc +201.208 38.3422 20 0 0 1 nc +116.407 -173.66 20 0 0 1 nc +-26.6953 -19.9585 20 1 0 0 nc +-539.894 -262.64 20 0 0 1 nc +-323.543 -433.964 20 0 0 1 nc +-309.657 -57.9033 20 1 0 0 nc +-67.9734 -347.42 20 1 0 0 nc +415.393 -289.516 20 1 0 0 nc +730.084 -307.139 20 0 0 1 nc +526.164 32.7279 20 1 0 0 nc +762.812 -17.6227 20 1 0 0 nc +-67.9734 319.727 20 0 0 1 nc +329.797 314.692 20 0 0 1 nc +-5.03507 561.41 20 0 0 1 nc +422.945 521.129 20 0 0 1 nc +-470.779 158.605 20 1 0 0 nc +986.873 -115.807 20 0 0 1 nc +906.312 201.403 20 0 0 1 nc +-767.847 113.289 20 1 0 0 nc +-579.033 445.603 20 0 0 1 nc +-840.856 -246.718 20 0 0 1 nc +206.221 -205.967 20 0 0 1 nc +277.311 -252.33 20 0 0 1 nc +271.13 -175.058 20 1 0 0 nc +366.947 -110.15 20 1 0 0 nc +397.855 -196.694 20 0 0 1 nc +438.037 -88.514 20 0 0 1 nc +286.584 -48.3327 20 1 0 0 nc +212.403 -23.6057 20 0 0 1 nc +280.402 10.3938 20 0 0 1 nc +694.579 115.483 20 0 0 1 nc +574.035 177.301 20 0 0 1 nc +grestore +grestore +showpage diff --git a/lemon/doc/images/nodeshape_0.eps b/lemon/doc/images/nodeshape_0.eps new file mode 100644 index 0000000..5f2f4a8 --- /dev/null +++ b/lemon/doc/images/nodeshape_0.eps @@ -0,0 +1,57 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: LEMON GraphToEps figure +%%Creator: LEMON GraphToEps function +%%BoundingBox: 0 0 200 200 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +100 dup scale +%Edges: +gsave +grestore +%Nodes: +gsave +1 1 1 0.2 1 0.2 nc +grestore +grestore +showpage diff --git a/lemon/doc/images/nodeshape_1.eps b/lemon/doc/images/nodeshape_1.eps new file mode 100644 index 0000000..e8b1104 --- /dev/null +++ b/lemon/doc/images/nodeshape_1.eps @@ -0,0 +1,57 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: LEMON GraphToEps figure +%%Creator: LEMON GraphToEps function +%%BoundingBox: 0 0 200 200 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +100 dup scale +%Edges: +gsave +grestore +%Nodes: +gsave +1 1 1 0.2 1 0.2 nsq +grestore +grestore +showpage diff --git a/lemon/doc/images/nodeshape_2.eps b/lemon/doc/images/nodeshape_2.eps new file mode 100644 index 0000000..5dcc4aa --- /dev/null +++ b/lemon/doc/images/nodeshape_2.eps @@ -0,0 +1,57 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: LEMON GraphToEps figure +%%Creator: LEMON GraphToEps function +%%BoundingBox: 0 0 200 200 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +100 dup scale +%Edges: +gsave +grestore +%Nodes: +gsave +1 1 1 0.2 1 0.2 ndi +grestore +grestore +showpage diff --git a/lemon/doc/images/nodeshape_3.eps b/lemon/doc/images/nodeshape_3.eps new file mode 100644 index 0000000..bc736af --- /dev/null +++ b/lemon/doc/images/nodeshape_3.eps @@ -0,0 +1,77 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: LEMON GraphToEps figure +%%Creator: LEMON GraphToEps function +%%BoundingBox: 0 0 256 372 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub + lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto + 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nmale { + 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto + 5 index 4 index 1 mul 1.5 mul add + 5 index 5 index 3 sqrt 1.5 mul mul add + 1 index 1 index lineto + 1 index 1 index 7 index sub moveto + 1 index 1 index lineto + exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto + stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +100 dup scale +%Edges: +gsave +grestore +%Nodes: +gsave +1 1 1 0.2 1 0.2 nmale +grestore +grestore +showpage diff --git a/lemon/doc/images/nodeshape_4.eps b/lemon/doc/images/nodeshape_4.eps new file mode 100644 index 0000000..e9fa575 --- /dev/null +++ b/lemon/doc/images/nodeshape_4.eps @@ -0,0 +1,77 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: LEMON GraphToEps figure +%%Creator: LEMON GraphToEps function +%%BoundingBox: 0 -199 200 200 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub + lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto + 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nmale { + 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto + 5 index 4 index 1 mul 1.5 mul add + 5 index 5 index 3 sqrt 1.5 mul mul add + 1 index 1 index lineto + 1 index 1 index 7 index sub moveto + 1 index 1 index lineto + exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto + stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +100 dup scale +%Edges: +gsave +grestore +%Nodes: +gsave +1 1 1 0.2 1 0.2 nfemale +grestore +grestore +showpage diff --git a/lemon/doc/images/planar.eps b/lemon/doc/images/planar.eps new file mode 100644 index 0000000..97d0aaf --- /dev/null +++ b/lemon/doc/images/planar.eps @@ -0,0 +1,181 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: LEMON, graphToEps() +%%CreationDate: Fri Oct 19 18:32:32 2007 +%%BoundingBox: 0 0 596 842 +%%DocumentPaperSizes: a4 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub + lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto + 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nmale { + 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth + newpath 5 index 5 index moveto + 5 index 4 index 1 mul 1.5 mul add + 5 index 5 index 3 sqrt 1.5 mul mul add + 1 index 1 index lineto + 1 index 1 index 7 index sub moveto + 1 index 1 index lineto + exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto + stroke + 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/arrl 1 def +/arrw 0.3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +15 138.307 translate +12.7843 dup scale +90 rotate +0.608112 -43.6081 translate +%Edges: +gsave +9 31 9.5 30.5 10 30 0 0 0 0.091217 lb +9 31 5.5 34.5 2 38 0 0 0 0.091217 lb +9 31 25.5 16 42 1 0 0 0 0.091217 lb +3 40 23 20.5 43 1 0 0 0 0.091217 lb +3 40 22.5 20.5 42 1 0 0 0 0.091217 lb +3 40 2.5 40.5 2 41 0 0 0 0.091217 lb +13 25 10.5 24.5 8 24 0 0 0 0.091217 lb +13 25 12 27 11 29 0 0 0 0.091217 lb +3 4 2.5 3 2 2 0 0 0 0.091217 lb +3 4 4.5 3 6 2 0 0 0 0.091217 lb +6 25 7 24.5 8 24 0 0 0 0.091217 lb +6 25 6 24.5 6 24 0 0 0 0.091217 lb +34 2 33.5 2 33 2 0 0 0 0.091217 lb +34 2 35 2 36 2 0 0 0 0.091217 lb +6 8 16 9 26 10 0 0 0 0.091217 lb +6 8 6 10.5 6 13 0 0 0 0.091217 lb +6 8 6 7.5 6 7 0 0 0 0.091217 lb +26 10 27.5 8.5 29 7 0 0 0 0.091217 lb +26 10 27.5 9 29 8 0 0 0 0.091217 lb +10 30 10.5 29.5 11 29 0 0 0 0.091217 lb +8 24 7 23.5 6 23 0 0 0 0.091217 lb +8 24 8 24.5 8 25 0 0 0 0.091217 lb +33 2 32.5 2 32 2 0 0 0 0.091217 lb +29 7 17.5 7 6 7 0 0 0 0.091217 lb +2 2 1.5 22 1 42 0 0 0 0.091217 lb +2 2 3.5 2 5 2 0 0 0 0.091217 lb +21 15 13.5 14.5 6 14 0 0 0 0.091217 lb +21 15 21 15.5 21 16 0 0 0 0.091217 lb +1 42 0.5 42.5 0 43 0 0 0 0.091217 lb +1 42 1.5 41.5 2 41 0 0 0 0.091217 lb +6 15 6 15.5 6 16 0 0 0 0.091217 lb +6 15 6 14.5 6 14 0 0 0 0.091217 lb +43 1 22 0.5 1 0 0 0 0 0.091217 lb +31 2 18.5 2 6 2 0 0 0 0.091217 lb +31 2 31.5 2 32 2 0 0 0 0.091217 lb +6 24 6 23.5 6 23 0 0 0 0.091217 lb +6 16 6 16.5 6 17 0 0 0 0.091217 lb +6 23 6 20 6 17 0 0 0 0.091217 lb +6 2 5.5 2 5 2 0 0 0 0.091217 lb +6 2 6 4.5 6 7 0 0 0 0.091217 lb +0 43 0.5 21.5 1 0 0 0 0 0.091217 lb +1 1 19.5 1.5 38 2 0 0 0 0.091217 lb +1 1 1 0.5 1 0 0 0 0 0.091217 lb +2 38 5.5 31.5 9 25 0 0 0 0.091217 lb +25 13 15.5 13 6 13 0 0 0 0.091217 lb +25 13 15.5 13.5 6 14 0 0 0 0.091217 lb +8 25 8.5 25 9 25 0 0 0 0.091217 lb +11 29 24.5 15.5 38 2 0 0 0 0.091217 lb +6 17 11.5 18 17 19 0 0 0 0.091217 lb +16 23 26.5 12.5 37 2 0 0 0 0.091217 lb +16 23 18.5 19.5 21 16 0 0 0 0.091217 lb +36 2 36.5 2 37 2 0 0 0 0.091217 lb +36 2 32.5 5 29 8 0 0 0 0.091217 lb +6 13 6 13.5 6 14 0 0 0 0.091217 lb +37 2 37.5 2 38 2 0 0 0 0.091217 lb +21 16 19 17.5 17 19 0 0 0 0.091217 lb +grestore +%Nodes: +gsave +29 8 0.304556 1 1 1 nc +2 41 0.304556 1 1 1 nc +6 7 0.304556 1 1 1 nc +5 2 0.304556 1 1 1 nc +17 19 0.304556 1 1 1 nc +21 16 0.304556 1 1 1 nc +1 0 0.304556 1 1 1 nc +9 25 0.304556 1 1 1 nc +6 14 0.304556 1 1 1 nc +42 1 0.304556 1 1 1 nc +38 2 0.304556 1 1 1 nc +37 2 0.304556 1 1 1 nc +6 13 0.304556 1 1 1 nc +36 2 0.304556 1 1 1 nc +16 23 0.304556 1 1 1 nc +6 17 0.304556 1 1 1 nc +11 29 0.304556 1 1 1 nc +8 25 0.304556 1 1 1 nc +32 2 0.304556 1 1 1 nc +25 13 0.304556 1 1 1 nc +2 38 0.304556 1 1 1 nc +1 1 0.304556 1 1 1 nc +0 43 0.304556 1 1 1 nc +6 2 0.304556 1 1 1 nc +6 23 0.304556 1 1 1 nc +6 16 0.304556 1 1 1 nc +6 24 0.304556 1 1 1 nc +31 2 0.304556 1 1 1 nc +43 1 0.304556 1 1 1 nc +6 15 0.304556 1 1 1 nc +1 42 0.304556 1 1 1 nc +21 15 0.304556 1 1 1 nc +2 2 0.304556 1 1 1 nc +29 7 0.304556 1 1 1 nc +33 2 0.304556 1 1 1 nc +8 24 0.304556 1 1 1 nc +10 30 0.304556 1 1 1 nc +26 10 0.304556 1 1 1 nc +6 8 0.304556 1 1 1 nc +34 2 0.304556 1 1 1 nc +6 25 0.304556 1 1 1 nc +3 4 0.304556 1 1 1 nc +13 25 0.304556 1 1 1 nc +3 40 0.304556 1 1 1 nc +9 31 0.304556 1 1 1 nc +grestore +grestore +showpage diff --git a/lemon/doc/images/strongly_connected_components.eps b/lemon/doc/images/strongly_connected_components.eps new file mode 100644 index 0000000..0f0d8fe --- /dev/null +++ b/lemon/doc/images/strongly_connected_components.eps @@ -0,0 +1,180 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: LEMON, graphToEps() +%%CreationDate: Fri Nov 4 13:47:12 2005 +%%BoundingBox: 0 0 842 596 +%%EndComments +/lb { setlinewidth setrgbcolor newpath moveto + 4 2 roll 1 index 1 index curveto stroke } bind def +/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def +/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def +/sq { newpath 2 index 1 index add 2 index 2 index add moveto + 2 index 1 index sub 2 index 2 index add lineto + 2 index 1 index sub 2 index 2 index sub lineto + 2 index 1 index add 2 index 2 index sub lineto + closepath pop pop pop} bind def +/di { newpath 2 index 1 index add 2 index moveto + 2 index 2 index 2 index add lineto + 2 index 1 index sub 2 index lineto + 2 index 2 index 2 index sub lineto + closepath pop pop pop} bind def +/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill + setrgbcolor 1.1 div c fill + } bind def +/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill + setrgbcolor 1.1 div sq fill + } bind def +/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill + setrgbcolor 1.1 div di fill + } bind def +/arrl 10 def +/arrw 3 def +/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def +/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def + /w exch def /len exch def + newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto + len w sub arrl sub dx dy lrl + arrw dy dx neg lrl + dx arrl w add mul dy w 2 div arrw add mul sub + dy arrl w add mul dx w 2 div arrw add mul add rlineto + dx arrl w add mul neg dy w 2 div arrw add mul sub + dy arrl w add mul neg dx w 2 div arrw add mul add rlineto + arrw dy dx neg lrl + len w sub arrl sub neg dx dy lrl + closepath fill } bind def +/cshow { 2 index 2 index moveto dup stringwidth pop + neg 2 div fosi .35 mul neg rmoveto show pop pop} def + +gsave +90 rotate +0 -842 translate +77.1122 15 translate +0.585745 dup scale +90 rotate +695.963 -397.916 translate +%Edges: +gsave +2 setlinewidth 0 0 1 setrgbcolor newpath +218.178 27.2723 moveto +192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke +newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +44.8044 15.5841 moveto +119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke +newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill +2 setlinewidth 1 0 0 setrgbcolor newpath +218.178 27.2723 moveto +285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke +newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +157.79 -130.517 moveto +108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke +newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill +2 setlinewidth 1 0 0 setrgbcolor newpath +-105.193 -261.035 moveto +-35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke +newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-465.576 -42.8564 moveto +-559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke +newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-574.666 -153.893 moveto +-528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke +newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill +2 setlinewidth 1 0 0 setrgbcolor newpath +-490.901 120.777 moveto +-480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke +newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-675.963 -3.89604 moveto +-632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke +newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-490.901 120.777 moveto +-435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke +newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-266.879 114.933 moveto +-367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke +newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-368.176 331.163 moveto +-322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke +newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill +2 setlinewidth 1 0 0 setrgbcolor newpath +-266.879 114.933 moveto +-224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke +newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-251.294 -335.059 moveto +-189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke +newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-389.604 -136.361 moveto +-327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke +newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill +2 setlinewidth 1 0 0 setrgbcolor newpath +5.84406 175.322 moveto +-76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke +newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +169.478 311.683 moveto +96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke +newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +342.851 111.037 moveto +263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke +newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +5.84406 175.322 moveto +163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke +newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +342.851 111.037 moveto +497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke +newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +364.28 -222.074 moveto +354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke +newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +670.118 -118.829 moveto +528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke +newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill +2 setlinewidth 1 0 0 setrgbcolor newpath +-105.193 -261.035 moveto +118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke +newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-105.193 -261.035 moveto +-160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke +newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill +2 setlinewidth 0 0 1 setrgbcolor newpath +-227.918 -40.9084 moveto +-298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke +newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill +grestore +%Nodes: +gsave +-389.604 -136.361 20 0 1 0 nc +-227.918 -40.9084 20 0 1 0 nc +-105.193 -261.035 20 0 1 0 nc +364.28 -222.074 20 1 1 0 nc +670.118 -118.829 20 1 1 0 nc +342.851 111.037 20 1 1 0 nc +5.84406 175.322 20 1 1 0 nc +169.478 311.683 20 1 1 0 nc +-173.374 377.916 20 1 0 1 nc +-251.294 -335.059 20 0 1 0 nc +-266.879 114.933 20 0 0 0 nc +-368.176 331.163 20 0 0 0 nc +-490.901 120.777 20 0 0 0 nc +-574.666 -153.893 20 1 0 0 nc +-675.963 -3.89604 20 1 0 0 nc +-465.576 -42.8564 20 1 0 0 nc +44.8044 15.5841 20 0 0 1 nc +157.79 -130.517 20 0 0 1 nc +218.178 27.2723 20 0 0 1 nc +grestore +grestore +showpage diff --git a/lemon/doc/lgf.dox b/lemon/doc/lgf.dox new file mode 100644 index 0000000..b5bf2f5 --- /dev/null +++ b/lemon/doc/lgf.dox @@ -0,0 +1,118 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +namespace lemon { +/*! + + + +\page lgf-format LEMON Graph Format (LGF) + +The \e LGF is a column oriented +file format for storing graphs and associated data like +node and edge maps. + +Each line with \c '#' first non-whitespace +character is considered as a comment line. + +Otherwise the file consists of sections starting with +a header line. The header lines starts with an \c '@' character followed by the +type of section. The standard section types are \c \@nodes, \c +\@arcs and \c \@edges +and \@attributes. Each header line may also have an optional +\e name, which can be use to distinguish the sections of the same +type. + +The standard sections are column oriented, each line consists of +tokens separated by whitespaces. A token can be \e plain or +\e quoted. A plain token is just a sequence of non-whitespace characters, +while a quoted token is a +character sequence surrounded by double quotes, and it can also +contain whitespaces and escape sequences. + +The \c \@nodes section describes a set of nodes and associated +maps. The first is a header line, its columns are the names of the +maps appearing in the following lines. +One of the maps must be called \c +"label", which plays special role in the file. +The following +non-empty lines until the next section describes nodes of the +graph. Each line contains the values of the node maps +associated to the current node. + +\code + @nodes + label coordinates size title + 1 (10,20) 10 "First node" + 2 (80,80) 8 "Second node" + 3 (40,10) 10 "Third node" +\endcode + +The \c \@arcs section is very similar to the \c \@nodes section, it +again starts with a header line describing the names of the maps, but +the \c "label" map is not obligatory here. The following lines +describe the arcs. The first two tokens of each line are the source +and the target node of the arc, respectively, then come the map +values. The source and target tokens must be node labels. + +\code + @arcs + capacity + 1 2 16 + 1 3 12 + 2 3 18 +\endcode + +If there is no map in the \c \@arcs section at all, then it must be +indicated by a sole '-' sign in the first line. + +\code + @arcs + - + 1 2 + 1 3 + 2 3 +\endcode + +The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can +also store the edge set of an undirected graph. In such case there is +a conventional method for store arc maps in the file, if two columns +have the same caption with \c '+' and \c '-' prefix, then these columns +can be regarded as the values of an arc map. + +The \c \@attributes section contains key-value pairs, each line +consists of two tokens, an attribute name, and then an attribute +value. The value of the attribute could be also a label value of a +node or an edge, or even an edge label prefixed with \c '+' or \c '-', +which regards to the forward or backward directed arc of the +corresponding edge. + +\code + @attributes + source 1 + target 3 + caption "LEMON test digraph" +\endcode + +The \e LGF can contain extra sections, but there is no restriction on +the format of such sections. + +*/ +} + +// LocalWords: whitespace whitespaces diff --git a/lemon/doc/license.dox b/lemon/doc/license.dox new file mode 100644 index 0000000..a40939b --- /dev/null +++ b/lemon/doc/license.dox @@ -0,0 +1,25 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/** + +\page license License Terms + +\verbinclude LICENSE + +*/ diff --git a/lemon/doc/mainpage.dox b/lemon/doc/mainpage.dox new file mode 100644 index 0000000..b947bae --- /dev/null +++ b/lemon/doc/mainpage.dox @@ -0,0 +1,61 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/** +\mainpage LEMON 1.2.3 Documentation + +\section intro Introduction + +LEMON stands for Library for Efficient Modeling +and Optimization in Networks. +It is a C++ template library providing efficient implementations of common +data structures and algorithms with focus on combinatorial optimization +tasks connected mainly with graphs and networks. + + +LEMON is an open source +project. +You are free to use it in your commercial or +non-commercial applications under very permissive +\ref license "license terms". + + +The project is maintained by the +Egerváry Research Group on +Combinatorial Optimization \ref egres +at the Operations Research Department of the +Eötvös Loránd University, +Budapest, Hungary. +LEMON is also a member of the COIN-OR +initiative \ref coinor. + +\section howtoread How to Read the Documentation + +If you would like to get to know the library, see +LEMON Tutorial. + +If you are interested in starting to use the library, see the Installation +Guide. + +If you know what you are looking for, then try to find it under the +Modules section. + +If you are a user of the old (0.x) series of LEMON, please check out the +\ref migration "Migration Guide" for the backward incompatibilities. +*/ diff --git a/lemon/doc/mainpage.dox.in b/lemon/doc/mainpage.dox.in new file mode 100644 index 0000000..86f124d --- /dev/null +++ b/lemon/doc/mainpage.dox.in @@ -0,0 +1,61 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/** +\mainpage @PACKAGE_NAME@ @PACKAGE_VERSION@ Documentation + +\section intro Introduction + +LEMON stands for Library for Efficient Modeling +and Optimization in Networks. +It is a C++ template library providing efficient implementations of common +data structures and algorithms with focus on combinatorial optimization +tasks connected mainly with graphs and networks. + + +LEMON is an open source +project. +You are free to use it in your commercial or +non-commercial applications under very permissive +\ref license "license terms". + + +The project is maintained by the +Egerváry Research Group on +Combinatorial Optimization \ref egres +at the Operations Research Department of the +Eötvös Loránd University, +Budapest, Hungary. +LEMON is also a member of the COIN-OR +initiative \ref coinor. + +\section howtoread How to Read the Documentation + +If you would like to get to know the library, see +LEMON Tutorial. + +If you are interested in starting to use the library, see the Installation +Guide. + +If you know what you are looking for, then try to find it under the +Modules section. + +If you are a user of the old (0.x) series of LEMON, please check out the +\ref migration "Migration Guide" for the backward incompatibilities. +*/ diff --git a/lemon/doc/migration.dox b/lemon/doc/migration.dox new file mode 100644 index 0000000..3117aa3 --- /dev/null +++ b/lemon/doc/migration.dox @@ -0,0 +1,145 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +namespace lemon { +/*! + +\page migration Migration from the 0.x Series + +This guide gives an in depth description on what has changed compared +to the 0.x release series. + +Many of these changes adjusted automatically by the +lemon-0.x-to-1.x.sh tool. Those requiring manual +update are typeset boldface. + +\section migration-graph Graph Related Name Changes + +- \ref concepts::Digraph "Directed graphs" are called \c Digraph and + they have Arcs (instead of Edges), while + \ref concepts::Graph "undirected graphs" are called \c Graph + (instead of \c UGraph) and they have Edges (instead of + UEdges). These changes reflected thoroughly everywhere in + the library. Namely, + - \c Graph -> \c Digraph + - \c %ListGraph -> \c ListDigraph, \c %SmartGraph -> \c SmartDigraph etc. + - \c UGraph -> \c Graph + - \c ListUGraph -> \c ListGraph, \c SmartUGraph -> \c SmartGraph etc. + - \c Edge -> \c Arc, \c UEdge -> \c Edge + - \c EdgeMap -> \c ArcMap, \c UEdgeMap -> \c EdgeMap + - \c EdgeIt -> \c ArcIt, \c UEdgeIt -> \c EdgeIt + - Class names and function names containing the words \c graph, + \c ugraph, \e edge or \e arc should also be updated. +- The two endpoints of an (\e undirected) \c Edge can be obtained by the + u() and v() member function of the graph + (instead of source() and target()). This change + must be done by hand. + \n Of course, you can still use source() and target() + for Arcs (directed edges). + +\warning +The lemon-0.x-to-1.x.sh script replaces the words \c graph, +\c ugraph, \c edge and \c uedge in your own identifiers and in +strings, comments etc. as well as in all LEMON specific identifiers. +So use the script carefully and make a backup copy of your source files +before applying the script to them. + +\section migration-lgf LGF tools + - The \ref lgf-format "LGF file format" has changed, + \@nodeset has changed to \@nodes, + \@edgeset and \@uedgeset to \@arcs or + \@edges, which become completely equivalents. The + \@nodes, \@edges and \@uedges sections are + removed from the format, the content of them should be + the part of \@attributes section. The data fields in + the sections must follow a strict format, they must be either character + sequences without whitespaces or quoted strings. + - The LemonReader and LemonWriter core interfaces + are no longer available. + - The implementation of the general section readers and writers has changed + they are simple functors now. Beside the old + stream based section handling, currently line oriented section + reading and writing are also supported. In the + section readers the lines must be counted manually. The sections + should be read and written with the SectionWriter and SectionReader + classes. + - Instead of the item readers and writers, item converters should be + used. The converters are functors, which map the type to + std::string or std::string to the type. The converters for standard + containers hasn't yet been implemented in the new LEMON. The converters + can return strings in any format, because if it is necessary, the LGF + writer and reader will quote and unquote the given value. + - The DigraphReader and DigraphWriter can used similarly to the + 0.x series, however the read or write prefix of + the member functions are removed. + - The new LEMON supports the function like interface, the \c + digraphReader and \c digraphWriter functions are more convenient than + using the classes directly. + +\section migration-search BFS, DFS and Dijkstra +- Using the function interface of BFS, DFS and %Dijkstra both source and + target nodes can be given as parameters of the run() function + (instead of \c bfs(), \c dfs() or \c dijkstra() itself). +- \ref named-templ-param "Named class template parameters" of \c Bfs, + \c Dfs, \c Dijkstra, \c BfsVisit, \c DfsVisit are renamed to start + with "Set" instead of "Def". Namely, + - \c DefPredMap -> \c SetPredMap + - \c DefDistMap -> \c SetDistMap + - \c DefReachedMap -> \c SetReachedMap + - \c DefProcessedMap -> \c SetProcessedMap + - \c DefHeap -> \c SetHeap + - \c DefStandardHeap -> \c SetStandardHeap + - \c DefOperationTraits -> \c SetOperationTraits + - \c DefProcessedMapToBeDefaultMap -> \c SetStandardProcessedMap + +\section migration-error Exceptions and Debug tools + +The class hierarchy of exceptions has largely been simplified. Now, +only the i/o related tools may throw exceptions. All other exceptions +have been replaced with either the \c LEMON_ASSERT or the \c LEMON_DEBUG +macros. + +On the other hand, the parameter order of constructors of the +exceptions has been changed. See \ref IoError and \ref FormatError for +more details. + +\section migration-other Others +- The contents of graph_utils.h are moved to core.h + and maps.h. core.h is included by all graph types, + therefore it usually do not have to be included directly. +- path_utils.h is merged to \c path.h. +- The semantic of the assignment operations and copy constructors of maps + are still under discussion. So, you must copy them by hand (i.e. copy + each entry one-by-one) +- The parameters of the graph copying tools (i.e. \c GraphCopy, + \c DigraphCopy) have to be given in the from-to order. +- \c copyDigraph() and \c copyGraph() are renamed to \c digraphCopy() + and \c graphCopy(), respectively. +- The interface of \ref DynArcLookUp has changed. It is now the same as + of \ref ArcLookUp and \ref AllArcLookUp +- Some map types should also been renamed. Namely, + - \c IntegerMap -> \c RangeMap + - \c StdMap -> \c SparseMap + - \c FunctorMap -> \c FunctorToMap + - \c MapFunctor -> \c MapToFunctor + - \c ForkWriteMap -> \c ForkMap + - \c StoreBoolMap -> \c LoggerBoolMap +- \c dim2::BoundingBox -> \c dim2::Box + +*/ +} diff --git a/lemon/doc/min_cost_flow.dox b/lemon/doc/min_cost_flow.dox new file mode 100644 index 0000000..ae8f044 --- /dev/null +++ b/lemon/doc/min_cost_flow.dox @@ -0,0 +1,153 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +namespace lemon { + +/** +\page min_cost_flow Minimum Cost Flow Problem + +\section mcf_def Definition (GEQ form) + +The \e minimum \e cost \e flow \e problem is to find a feasible flow of +minimum total cost from a set of supply nodes to a set of demand nodes +in a network with capacity constraints (lower and upper bounds) +and arc costs \ref amo93networkflows. + +Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$, +\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and +upper bounds for the flow values on the arcs, for which +\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$, +\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow +on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the +signed supply values of the nodes. +If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$ +supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with +\f$-sup(u)\f$ demand. +A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution +of the following optimization problem. + +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f] +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq + sup(u) \quad \forall u\in V \f] +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f] + +The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be +zero or negative in order to have a feasible solution (since the sum +of the expressions on the left-hand side of the inequalities is zero). +It means that the total demand must be greater or equal to the total +supply and all the supplies have to be carried out from the supply nodes, +but there could be demands that are not satisfied. +If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand +constraints have to be satisfied with equality, i.e. all demands +have to be satisfied and all supplies have to be used. + + +\section mcf_algs Algorithms + +LEMON contains several algorithms for solving this problem, for more +information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms". + +A feasible solution for this problem can be found using \ref Circulation. + + +\section mcf_dual Dual Solution + +The dual solution of the minimum cost flow problem is represented by +node potentials \f$\pi: V\rightarrow\mathbf{R}\f$. +An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal +if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials +the following \e complementary \e slackness optimality conditions hold. + + - For all \f$uv\in A\f$ arcs: + - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$; + - if \f$lower(uv)"less or equal" (LEQ) supply/demand constraints, +instead of the "greater or equal" (GEQ) constraints. + +\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f] +\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq + sup(u) \quad \forall u\in V \f] +\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f] + +It means that the total demand must be less or equal to the +total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or +positive) and all the demands have to be satisfied, but there +could be supplies that are not carried out from the supply +nodes. +The equality form is also a special case of this form, of course. + +You could easily transform this case to the \ref mcf_def "GEQ form" +of the problem by reversing the direction of the arcs and taking the +negative of the supply values (e.g. using \ref ReverseDigraph and +\ref NegMap adaptors). +However \ref NetworkSimplex algorithm also supports this form directly +for the sake of convenience. + +Note that the optimality conditions for this supply constraint type are +slightly differ from the conditions that are discussed for the GEQ form, +namely the potentials have to be non-negative instead of non-positive. +An \f$f: A\rightarrow\mathbf{R}\f$ feasible solution of this problem +is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ +node potentials the following conditions hold. + + - For all \f$uv\in A\f$ arcs: + - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$; + - if \f$lower(uv)run() executes the algorithm itself. + +\note Although it is a class, namedFn is used pretty much like as it were +a function. That it why we called it namedFn instead of \c NamedFn. + +\note In fact, the final .run() could be made unnecessary, +because the algorithm could also be implemented in the destructor of +\c namedFn instead. This however would make it impossible to implement +functions with return values, and would also cause serious problems when +implementing \ref named-templ-func-param "named template parameters". +Therefore, by convention, .run() must be used +explicitly to execute a function having named parameters +everywhere in LEMON. + +\section named-templ-func-param Named Function Template Parameters + +A named parameter can also be a template function. The usage is +exactly the same, but the implementation behind is a kind of black +magic and they are the dirtiest part of the LEMON code. + +You will probably never need to know how it works, but if you really +committed, have a look at \ref lemon/graph_to_eps.h for an example. + +\section traits-classes Traits Classes + +A similar game can also be played when defining classes. In this case +the type of the class attributes can be changed. Initially we have to +define a special class called Traits Class defining the +default type of the attributes. Then the types of these attributes can +be changed in the same way as described in the next section. + +See \ref lemon::DijkstraDefaultTraits for an +example how a traits class implementation looks like. + +\section named-templ-param Named Class Template Parameters + +If we would like to change the type of an attribute in a class that +was instantiated by using a traits class as a template parameter, and +the class contains named parameters, we do not have to instantiate again +the class with new traits class, but instead adaptor classes can +be used as shown in the following example. + +\code +Dijkstra<>::SetPredMap >::Create +\endcode + +It can also be used in conjunction with other named template +parameters in arbitrary order. + +\code +Dijkstra<>::SetDistMap::SetPredMap >::Create +\endcode + +The result will be an instantiated Dijkstra class, in which the +DistMap and the PredMap is modified. + +*/ diff --git a/lemon/doc/namespaces.dox b/lemon/doc/namespaces.dox new file mode 100644 index 0000000..248ca20 --- /dev/null +++ b/lemon/doc/namespaces.dox @@ -0,0 +1,30 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/// The namespace of LEMON + +/// The namespace of LEMON +/// +namespace lemon { + + /// The namespace of LEMON concepts and concept checking classes + + /// The namespace of LEMON concepts and concept checking classes + /// + namespace concepts {} +} diff --git a/lemon/lemon/.deps/.dirstamp b/lemon/lemon/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/lemon/lemon/.deps/lemon_libemon_la-arg_parser.Plo b/lemon/lemon/.deps/lemon_libemon_la-arg_parser.Plo new file mode 100644 index 0000000..7ca478f --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-arg_parser.Plo @@ -0,0 +1,357 @@ +lemon/lemon_libemon_la-arg_parser.lo: lemon/arg_parser.cc \ + lemon/arg_parser.h /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/stl_construct.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/vector.tcc /usr/include/c++/4.7/map \ + /usr/include/c++/4.7/bits/stl_tree.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/stl_map.h \ + /usr/include/c++/4.7/bits/stl_multimap.h /usr/include/c++/4.7/list \ + /usr/include/c++/4.7/bits/stl_list.h /usr/include/c++/4.7/bits/list.tcc \ + /usr/include/c++/4.7/string /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/xlocale.h /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/iosfwd \ + /usr/include/c++/4.7/cctype /usr/include/ctype.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/basic_string.tcc /usr/include/c++/4.7/iostream \ + /usr/include/c++/4.7/ostream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/bits/locale_classes.h \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc \ + /usr/include/c++/4.7/bits/ostream.tcc /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/bits/istream.tcc /usr/include/c++/4.7/sstream \ + /usr/include/c++/4.7/bits/sstream.tcc /usr/include/c++/4.7/algorithm \ + /usr/include/c++/4.7/utility /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_algo.h /usr/include/c++/4.7/cstdlib \ + /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h /usr/include/alloca.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h \ + /usr/include/c++/4.7/bits/stl_tempbuf.h lemon/assert.h lemon/error.h \ + /usr/include/c++/4.7/memory \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h + +lemon/arg_parser.h: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +/usr/include/c++/4.7/map: + +/usr/include/c++/4.7/bits/stl_tree.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/stl_map.h: + +/usr/include/c++/4.7/bits/stl_multimap.h: + +/usr/include/c++/4.7/list: + +/usr/include/c++/4.7/bits/stl_list.h: + +/usr/include/c++/4.7/bits/list.tcc: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/xlocale.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +lemon/assert.h: + +lemon/error.h: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: diff --git a/lemon/lemon/.deps/lemon_libemon_la-base.Plo b/lemon/lemon/.deps/lemon_libemon_la-base.Plo new file mode 100644 index 0000000..0aeb30e --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-base.Plo @@ -0,0 +1,348 @@ +lemon/lemon_libemon_la-base.lo: lemon/base.cc lemon/tolerance.h \ + lemon/core.h /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/stl_construct.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/vector.tcc /usr/include/c++/4.7/algorithm \ + /usr/include/c++/4.7/utility /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_algo.h /usr/include/c++/4.7/cstdlib \ + /usr/include/stdlib.h /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h \ + /usr/include/c++/4.7/bits/stl_tempbuf.h lemon/config.h \ + lemon/bits/enable_if.h lemon/bits/traits.h lemon/assert.h lemon/error.h \ + /usr/include/c++/4.7/string /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/iosfwd \ + /usr/include/c++/4.7/cctype /usr/include/ctype.h \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/basic_string.tcc /usr/include/c++/4.7/sstream \ + /usr/include/c++/4.7/istream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/bits/locale_classes.h \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc /usr/include/c++/4.7/ostream \ + /usr/include/c++/4.7/bits/ostream.tcc \ + /usr/include/c++/4.7/bits/istream.tcc \ + /usr/include/c++/4.7/bits/sstream.tcc /usr/include/c++/4.7/iostream \ + /usr/include/c++/4.7/memory \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h + +lemon/tolerance.h: + +lemon/core.h: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +lemon/config.h: + +lemon/bits/enable_if.h: + +lemon/bits/traits.h: + +lemon/assert.h: + +lemon/error.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: diff --git a/lemon/lemon/.deps/lemon_libemon_la-cbc.Plo b/lemon/lemon/.deps/lemon_libemon_la-cbc.Plo new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-cbc.Plo @@ -0,0 +1 @@ +# dummy diff --git a/lemon/lemon/.deps/lemon_libemon_la-clp.Plo b/lemon/lemon/.deps/lemon_libemon_la-clp.Plo new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-clp.Plo @@ -0,0 +1 @@ +# dummy diff --git a/lemon/lemon/.deps/lemon_libemon_la-color.Plo b/lemon/lemon/.deps/lemon_libemon_la-color.Plo new file mode 100644 index 0000000..3a3ecba --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-color.Plo @@ -0,0 +1,399 @@ +lemon/lemon_libemon_la-color.lo: lemon/color.cc lemon/color.h \ + /usr/include/c++/4.7/vector /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/stl_construct.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/vector.tcc lemon/math.h \ + /usr/include/c++/4.7/cmath /usr/include/math.h \ + /usr/include/x86_64-linux-gnu/bits/huge_val.h \ + /usr/include/x86_64-linux-gnu/bits/huge_valf.h \ + /usr/include/x86_64-linux-gnu/bits/huge_vall.h \ + /usr/include/x86_64-linux-gnu/bits/inf.h \ + /usr/include/x86_64-linux-gnu/bits/nan.h \ + /usr/include/x86_64-linux-gnu/bits/mathdef.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mathinline.h lemon/maps.h \ + /usr/include/c++/4.7/iterator /usr/include/c++/4.7/ostream \ + /usr/include/c++/4.7/ios /usr/include/c++/4.7/iosfwd \ + /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/xlocale.h /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/cctype \ + /usr/include/ctype.h /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/locale_classes.h /usr/include/c++/4.7/string \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/bits/basic_string.tcc \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc \ + /usr/include/c++/4.7/bits/ostream.tcc /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/bits/istream.tcc \ + /usr/include/c++/4.7/bits/stream_iterator.h \ + /usr/include/c++/4.7/functional /usr/include/c++/4.7/map \ + /usr/include/c++/4.7/bits/stl_tree.h /usr/include/c++/4.7/bits/stl_map.h \ + /usr/include/c++/4.7/bits/stl_multimap.h lemon/core.h \ + /usr/include/c++/4.7/algorithm /usr/include/c++/4.7/utility \ + /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_algo.h /usr/include/c++/4.7/cstdlib \ + /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h /usr/include/alloca.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h \ + /usr/include/c++/4.7/bits/stl_tempbuf.h lemon/config.h \ + lemon/bits/enable_if.h lemon/bits/traits.h lemon/assert.h lemon/error.h \ + /usr/include/c++/4.7/sstream /usr/include/c++/4.7/bits/sstream.tcc \ + /usr/include/c++/4.7/iostream /usr/include/c++/4.7/memory \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h + +lemon/color.h: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +lemon/math.h: + +/usr/include/c++/4.7/cmath: + +/usr/include/math.h: + +/usr/include/x86_64-linux-gnu/bits/huge_val.h: + +/usr/include/x86_64-linux-gnu/bits/huge_valf.h: + +/usr/include/x86_64-linux-gnu/bits/huge_vall.h: + +/usr/include/x86_64-linux-gnu/bits/inf.h: + +/usr/include/x86_64-linux-gnu/bits/nan.h: + +/usr/include/x86_64-linux-gnu/bits/mathdef.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathinline.h: + +lemon/maps.h: + +/usr/include/c++/4.7/iterator: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/xlocale.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/bits/stream_iterator.h: + +/usr/include/c++/4.7/functional: + +/usr/include/c++/4.7/map: + +/usr/include/c++/4.7/bits/stl_tree.h: + +/usr/include/c++/4.7/bits/stl_map.h: + +/usr/include/c++/4.7/bits/stl_multimap.h: + +lemon/core.h: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +lemon/config.h: + +lemon/bits/enable_if.h: + +lemon/bits/traits.h: + +lemon/assert.h: + +lemon/error.h: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: diff --git a/lemon/lemon/.deps/lemon_libemon_la-cplex.Plo b/lemon/lemon/.deps/lemon_libemon_la-cplex.Plo new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-cplex.Plo @@ -0,0 +1 @@ +# dummy diff --git a/lemon/lemon/.deps/lemon_libemon_la-glpk.Plo b/lemon/lemon/.deps/lemon_libemon_la-glpk.Plo new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-glpk.Plo @@ -0,0 +1 @@ +# dummy diff --git a/lemon/lemon/.deps/lemon_libemon_la-lp_base.Plo b/lemon/lemon/.deps/lemon_libemon_la-lp_base.Plo new file mode 100644 index 0000000..47bbbe0 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-lp_base.Plo @@ -0,0 +1,393 @@ +lemon/lemon_libemon_la-lp_base.lo: lemon/lp_base.cc lemon/lp_base.h \ + /usr/include/c++/4.7/iostream \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/ostream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/iosfwd /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/xlocale.h /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/cctype \ + /usr/include/ctype.h /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/locale_classes.h /usr/include/c++/4.7/string \ + /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/bits/basic_string.tcc \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc \ + /usr/include/c++/4.7/bits/ostream.tcc /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/bits/istream.tcc /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_construct.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/vector.tcc /usr/include/c++/4.7/map \ + /usr/include/c++/4.7/bits/stl_tree.h /usr/include/c++/4.7/bits/stl_map.h \ + /usr/include/c++/4.7/bits/stl_multimap.h /usr/include/c++/4.7/limits \ + lemon/math.h /usr/include/c++/4.7/cmath /usr/include/math.h \ + /usr/include/x86_64-linux-gnu/bits/huge_val.h \ + /usr/include/x86_64-linux-gnu/bits/huge_valf.h \ + /usr/include/x86_64-linux-gnu/bits/huge_vall.h \ + /usr/include/x86_64-linux-gnu/bits/inf.h \ + /usr/include/x86_64-linux-gnu/bits/nan.h \ + /usr/include/x86_64-linux-gnu/bits/mathdef.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mathinline.h lemon/error.h \ + /usr/include/c++/4.7/sstream /usr/include/c++/4.7/bits/sstream.tcc \ + /usr/include/c++/4.7/cstdlib /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h /usr/include/alloca.h \ + /usr/include/c++/4.7/memory /usr/include/c++/4.7/bits/stl_tempbuf.h \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h lemon/assert.h lemon/core.h \ + /usr/include/c++/4.7/algorithm /usr/include/c++/4.7/utility \ + /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_algo.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h lemon/config.h \ + lemon/bits/enable_if.h lemon/bits/traits.h lemon/bits/solver_bits.h + +lemon/lp_base.h: + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/xlocale.h: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +/usr/include/c++/4.7/map: + +/usr/include/c++/4.7/bits/stl_tree.h: + +/usr/include/c++/4.7/bits/stl_map.h: + +/usr/include/c++/4.7/bits/stl_multimap.h: + +/usr/include/c++/4.7/limits: + +lemon/math.h: + +/usr/include/c++/4.7/cmath: + +/usr/include/math.h: + +/usr/include/x86_64-linux-gnu/bits/huge_val.h: + +/usr/include/x86_64-linux-gnu/bits/huge_valf.h: + +/usr/include/x86_64-linux-gnu/bits/huge_vall.h: + +/usr/include/x86_64-linux-gnu/bits/inf.h: + +/usr/include/x86_64-linux-gnu/bits/nan.h: + +/usr/include/x86_64-linux-gnu/bits/mathdef.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathinline.h: + +lemon/error.h: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: + +lemon/assert.h: + +lemon/core.h: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +lemon/config.h: + +lemon/bits/enable_if.h: + +lemon/bits/traits.h: + +lemon/bits/solver_bits.h: diff --git a/lemon/lemon/.deps/lemon_libemon_la-lp_skeleton.Plo b/lemon/lemon/.deps/lemon_libemon_la-lp_skeleton.Plo new file mode 100644 index 0000000..15f9c57 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-lp_skeleton.Plo @@ -0,0 +1,395 @@ +lemon/lemon_libemon_la-lp_skeleton.lo: lemon/lp_skeleton.cc \ + lemon/lp_skeleton.h lemon/lp_base.h /usr/include/c++/4.7/iostream \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/ostream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/iosfwd /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/xlocale.h /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/cctype \ + /usr/include/ctype.h /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/locale_classes.h /usr/include/c++/4.7/string \ + /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/bits/basic_string.tcc \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc \ + /usr/include/c++/4.7/bits/ostream.tcc /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/bits/istream.tcc /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_construct.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/vector.tcc /usr/include/c++/4.7/map \ + /usr/include/c++/4.7/bits/stl_tree.h /usr/include/c++/4.7/bits/stl_map.h \ + /usr/include/c++/4.7/bits/stl_multimap.h /usr/include/c++/4.7/limits \ + lemon/math.h /usr/include/c++/4.7/cmath /usr/include/math.h \ + /usr/include/x86_64-linux-gnu/bits/huge_val.h \ + /usr/include/x86_64-linux-gnu/bits/huge_valf.h \ + /usr/include/x86_64-linux-gnu/bits/huge_vall.h \ + /usr/include/x86_64-linux-gnu/bits/inf.h \ + /usr/include/x86_64-linux-gnu/bits/nan.h \ + /usr/include/x86_64-linux-gnu/bits/mathdef.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mathinline.h lemon/error.h \ + /usr/include/c++/4.7/sstream /usr/include/c++/4.7/bits/sstream.tcc \ + /usr/include/c++/4.7/cstdlib /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h /usr/include/alloca.h \ + /usr/include/c++/4.7/memory /usr/include/c++/4.7/bits/stl_tempbuf.h \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h lemon/assert.h lemon/core.h \ + /usr/include/c++/4.7/algorithm /usr/include/c++/4.7/utility \ + /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_algo.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h lemon/config.h \ + lemon/bits/enable_if.h lemon/bits/traits.h lemon/bits/solver_bits.h + +lemon/lp_skeleton.h: + +lemon/lp_base.h: + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/xlocale.h: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +/usr/include/c++/4.7/map: + +/usr/include/c++/4.7/bits/stl_tree.h: + +/usr/include/c++/4.7/bits/stl_map.h: + +/usr/include/c++/4.7/bits/stl_multimap.h: + +/usr/include/c++/4.7/limits: + +lemon/math.h: + +/usr/include/c++/4.7/cmath: + +/usr/include/math.h: + +/usr/include/x86_64-linux-gnu/bits/huge_val.h: + +/usr/include/x86_64-linux-gnu/bits/huge_valf.h: + +/usr/include/x86_64-linux-gnu/bits/huge_vall.h: + +/usr/include/x86_64-linux-gnu/bits/inf.h: + +/usr/include/x86_64-linux-gnu/bits/nan.h: + +/usr/include/x86_64-linux-gnu/bits/mathdef.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathinline.h: + +lemon/error.h: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: + +lemon/assert.h: + +lemon/core.h: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +lemon/config.h: + +lemon/bits/enable_if.h: + +lemon/bits/traits.h: + +lemon/bits/solver_bits.h: diff --git a/lemon/lemon/.deps/lemon_libemon_la-random.Plo b/lemon/lemon/.deps/lemon_libemon_la-random.Plo new file mode 100644 index 0000000..3737c46 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-random.Plo @@ -0,0 +1,410 @@ +lemon/lemon_libemon_la-random.lo: lemon/random.cc lemon/random.h \ + /usr/include/c++/4.7/algorithm /usr/include/c++/4.7/utility \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/stl_algo.h \ + /usr/include/c++/4.7/cstdlib /usr/include/stdlib.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h \ + /usr/include/c++/4.7/bits/stl_tempbuf.h \ + /usr/include/c++/4.7/bits/stl_construct.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/iterator \ + /usr/include/c++/4.7/ostream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/iosfwd /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/cctype \ + /usr/include/ctype.h /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/locale_classes.h /usr/include/c++/4.7/string \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/bits/basic_string.tcc \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc \ + /usr/include/c++/4.7/bits/ostream.tcc /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/bits/istream.tcc \ + /usr/include/c++/4.7/bits/stream_iterator.h /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/vector.tcc /usr/include/c++/4.7/limits \ + /usr/include/c++/4.7/fstream /usr/include/c++/4.7/bits/codecvt.h \ + /usr/include/c++/4.7/cstdio /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h \ + /usr/include/c++/4.7/bits/fstream.tcc lemon/math.h \ + /usr/include/c++/4.7/cmath /usr/include/math.h \ + /usr/include/x86_64-linux-gnu/bits/huge_val.h \ + /usr/include/x86_64-linux-gnu/bits/huge_valf.h \ + /usr/include/x86_64-linux-gnu/bits/huge_vall.h \ + /usr/include/x86_64-linux-gnu/bits/inf.h \ + /usr/include/x86_64-linux-gnu/bits/nan.h \ + /usr/include/x86_64-linux-gnu/bits/mathdef.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mathinline.h lemon/dim2.h \ + /usr/include/c++/4.7/iostream /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/c++/4.7/ctime /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h + +lemon/random.h: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/iterator: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/bits/stream_iterator.h: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +/usr/include/c++/4.7/limits: + +/usr/include/c++/4.7/fstream: + +/usr/include/c++/4.7/bits/codecvt.h: + +/usr/include/c++/4.7/cstdio: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h: + +/usr/include/c++/4.7/bits/fstream.tcc: + +lemon/math.h: + +/usr/include/c++/4.7/cmath: + +/usr/include/math.h: + +/usr/include/x86_64-linux-gnu/bits/huge_val.h: + +/usr/include/x86_64-linux-gnu/bits/huge_valf.h: + +/usr/include/x86_64-linux-gnu/bits/huge_vall.h: + +/usr/include/x86_64-linux-gnu/bits/inf.h: + +/usr/include/x86_64-linux-gnu/bits/nan.h: + +/usr/include/x86_64-linux-gnu/bits/mathdef.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathinline.h: + +lemon/dim2.h: + +/usr/include/c++/4.7/iostream: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/c++/4.7/ctime: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: diff --git a/lemon/lemon/.deps/lemon_libemon_la-soplex.Plo b/lemon/lemon/.deps/lemon_libemon_la-soplex.Plo new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/lemon/.deps/lemon_libemon_la-soplex.Plo @@ -0,0 +1 @@ +# dummy diff --git a/lemon/lemon/.dirstamp b/lemon/lemon/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/lemon/lemon/CMakeLists.txt b/lemon/lemon/CMakeLists.txt new file mode 100644 index 0000000..b43e3f2 --- /dev/null +++ b/lemon/lemon/CMakeLists.txt @@ -0,0 +1,80 @@ +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} +) + +CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/config.h +) + +CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc + @ONLY +) + +SET(LEMON_SOURCES + arg_parser.cc + base.cc + color.cc + lp_base.cc + lp_skeleton.cc + random.cc + bits/windows.cc +) + +IF(LEMON_HAVE_GLPK) + SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc) + INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS}) + IF(WIN32) + INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin) + INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin) + INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin) + ENDIF() +ENDIF() + +IF(LEMON_HAVE_CPLEX) + SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc) + INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS}) +ENDIF() + +IF(LEMON_HAVE_CLP) + SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc) + INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS}) +ENDIF() + +IF(LEMON_HAVE_CBC) + SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc) + INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS}) +ENDIF() + +ADD_LIBRARY(lemon ${LEMON_SOURCES}) +IF(UNIX) + SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon) +ENDIF() + +INSTALL( + TARGETS lemon + ARCHIVE DESTINATION lib + COMPONENT library +) + +INSTALL( + DIRECTORY . bits concepts + DESTINATION include/lemon + COMPONENT headers + FILES_MATCHING PATTERN "*.h" +) + +INSTALL( + FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h + DESTINATION include/lemon + COMPONENT headers +) + +INSTALL( + FILES ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc + DESTINATION lib/pkgconfig +) + diff --git a/lemon/lemon/Makefile.am b/lemon/lemon/Makefile.am new file mode 100644 index 0000000..7df1e4a --- /dev/null +++ b/lemon/lemon/Makefile.am @@ -0,0 +1,151 @@ +EXTRA_DIST += \ + lemon/lemon.pc.in \ + lemon/lemon.pc.cmake \ + lemon/CMakeLists.txt \ + lemon/config.h.cmake + +pkgconfig_DATA += lemon/lemon.pc + +lib_LTLIBRARIES += lemon/libemon.la + +lemon_libemon_la_SOURCES = \ + lemon/arg_parser.cc \ + lemon/base.cc \ + lemon/color.cc \ + lemon/lp_base.cc \ + lemon/lp_skeleton.cc \ + lemon/random.cc \ + lemon/bits/windows.cc + +nodist_lemon_HEADERS = lemon/config.h + +lemon_libemon_la_CXXFLAGS = \ + $(AM_CXXFLAGS) \ + $(GLPK_CFLAGS) \ + $(CPLEX_CFLAGS) \ + $(SOPLEX_CXXFLAGS) \ + $(CLP_CXXFLAGS) \ + $(CBC_CXXFLAGS) + +lemon_libemon_la_LDFLAGS = \ + $(GLPK_LIBS) \ + $(CPLEX_LIBS) \ + $(SOPLEX_LIBS) \ + $(CLP_LIBS) \ + $(CBC_LIBS) + +if HAVE_GLPK +lemon_libemon_la_SOURCES += lemon/glpk.cc +endif + +if HAVE_CPLEX +lemon_libemon_la_SOURCES += lemon/cplex.cc +endif + +if HAVE_SOPLEX +lemon_libemon_la_SOURCES += lemon/soplex.cc +endif + +if HAVE_CLP +lemon_libemon_la_SOURCES += lemon/clp.cc +endif + +if HAVE_CBC +lemon_libemon_la_SOURCES += lemon/cbc.cc +endif + +lemon_HEADERS += \ + lemon/adaptors.h \ + lemon/arg_parser.h \ + lemon/assert.h \ + lemon/bellman_ford.h \ + lemon/bfs.h \ + lemon/bin_heap.h \ + lemon/binomial_heap.h \ + lemon/bucket_heap.h \ + lemon/capacity_scaling.h \ + lemon/cbc.h \ + lemon/circulation.h \ + lemon/clp.h \ + lemon/color.h \ + lemon/concept_check.h \ + lemon/connectivity.h \ + lemon/core.h \ + lemon/cost_scaling.h \ + lemon/counter.h \ + lemon/cplex.h \ + lemon/cycle_canceling.h \ + lemon/dfs.h \ + lemon/dheap.h \ + lemon/dijkstra.h \ + lemon/dim2.h \ + lemon/dimacs.h \ + lemon/edge_set.h \ + lemon/elevator.h \ + lemon/error.h \ + lemon/euler.h \ + lemon/fib_heap.h \ + lemon/fractional_matching.h \ + lemon/full_graph.h \ + lemon/glpk.h \ + lemon/gomory_hu.h \ + lemon/graph_to_eps.h \ + lemon/grid_graph.h \ + lemon/hartmann_orlin_mmc.h \ + lemon/howard_mmc.h \ + lemon/hypercube_graph.h \ + lemon/karp_mmc.h \ + lemon/kruskal.h \ + lemon/hao_orlin.h \ + lemon/lgf_reader.h \ + lemon/lgf_writer.h \ + lemon/list_graph.h \ + lemon/lp.h \ + lemon/lp_base.h \ + lemon/lp_skeleton.h \ + lemon/maps.h \ + lemon/matching.h \ + lemon/math.h \ + lemon/min_cost_arborescence.h \ + lemon/nauty_reader.h \ + lemon/network_simplex.h \ + lemon/pairing_heap.h \ + lemon/path.h \ + lemon/planarity.h \ + lemon/preflow.h \ + lemon/quad_heap.h \ + lemon/radix_heap.h \ + lemon/radix_sort.h \ + lemon/random.h \ + lemon/smart_graph.h \ + lemon/soplex.h \ + lemon/static_graph.h \ + lemon/suurballe.h \ + lemon/time_measure.h \ + lemon/tolerance.h \ + lemon/unionfind.h \ + lemon/bits/windows.h + +bits_HEADERS += \ + lemon/bits/alteration_notifier.h \ + lemon/bits/array_map.h \ + lemon/bits/bezier.h \ + lemon/bits/default_map.h \ + lemon/bits/edge_set_extender.h \ + lemon/bits/enable_if.h \ + lemon/bits/graph_adaptor_extender.h \ + lemon/bits/graph_extender.h \ + lemon/bits/map_extender.h \ + lemon/bits/path_dump.h \ + lemon/bits/solver_bits.h \ + lemon/bits/traits.h \ + lemon/bits/variant.h \ + lemon/bits/vector_map.h + +concept_HEADERS += \ + lemon/concepts/digraph.h \ + lemon/concepts/graph.h \ + lemon/concepts/graph_components.h \ + lemon/concepts/heap.h \ + lemon/concepts/maps.h \ + lemon/concepts/path.h diff --git a/lemon/lemon/adaptors.h b/lemon/lemon/adaptors.h new file mode 100644 index 0000000..9379b76 --- /dev/null +++ b/lemon/lemon/adaptors.h @@ -0,0 +1,3638 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_ADAPTORS_H +#define LEMON_ADAPTORS_H + +/// \ingroup graph_adaptors +/// \file +/// \brief Adaptor classes for digraphs and graphs +/// +/// This file contains several useful adaptors for digraphs and graphs. + +#include +#include +#include + +#include +#include +#include + +#include + +namespace lemon { + +#ifdef _MSC_VER +#define LEMON_SCOPE_FIX(OUTER, NESTED) OUTER::NESTED +#else +#define LEMON_SCOPE_FIX(OUTER, NESTED) typename OUTER::template NESTED +#endif + + template + class DigraphAdaptorBase { + public: + typedef DGR Digraph; + typedef DigraphAdaptorBase Adaptor; + + protected: + DGR* _digraph; + DigraphAdaptorBase() : _digraph(0) { } + void initialize(DGR& digraph) { _digraph = &digraph; } + + public: + DigraphAdaptorBase(DGR& digraph) : _digraph(&digraph) { } + + typedef typename DGR::Node Node; + typedef typename DGR::Arc Arc; + + void first(Node& i) const { _digraph->first(i); } + void first(Arc& i) const { _digraph->first(i); } + void firstIn(Arc& i, const Node& n) const { _digraph->firstIn(i, n); } + void firstOut(Arc& i, const Node& n ) const { _digraph->firstOut(i, n); } + + void next(Node& i) const { _digraph->next(i); } + void next(Arc& i) const { _digraph->next(i); } + void nextIn(Arc& i) const { _digraph->nextIn(i); } + void nextOut(Arc& i) const { _digraph->nextOut(i); } + + Node source(const Arc& a) const { return _digraph->source(a); } + Node target(const Arc& a) const { return _digraph->target(a); } + + typedef NodeNumTagIndicator NodeNumTag; + int nodeNum() const { return _digraph->nodeNum(); } + + typedef ArcNumTagIndicator ArcNumTag; + int arcNum() const { return _digraph->arcNum(); } + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const { + return _digraph->findArc(u, v, prev); + } + + Node addNode() { return _digraph->addNode(); } + Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); } + + void erase(const Node& n) { _digraph->erase(n); } + void erase(const Arc& a) { _digraph->erase(a); } + + void clear() { _digraph->clear(); } + + int id(const Node& n) const { return _digraph->id(n); } + int id(const Arc& a) const { return _digraph->id(a); } + + Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); } + Arc arcFromId(int ix) const { return _digraph->arcFromId(ix); } + + int maxNodeId() const { return _digraph->maxNodeId(); } + int maxArcId() const { return _digraph->maxArcId(); } + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); } + + typedef typename ItemSetTraits::ItemNotifier ArcNotifier; + ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); } + + template + class NodeMap : public DGR::template NodeMap { + typedef typename DGR::template NodeMap Parent; + + public: + explicit NodeMap(const Adaptor& adaptor) + : Parent(*adaptor._digraph) {} + NodeMap(const Adaptor& adaptor, const V& value) + : Parent(*adaptor._digraph, value) { } + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + template + class ArcMap : public DGR::template ArcMap { + typedef typename DGR::template ArcMap Parent; + + public: + explicit ArcMap(const DigraphAdaptorBase& adaptor) + : Parent(*adaptor._digraph) {} + ArcMap(const DigraphAdaptorBase& adaptor, const V& value) + : Parent(*adaptor._digraph, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + }; + + template + class GraphAdaptorBase { + public: + typedef GR Graph; + + protected: + GR* _graph; + + GraphAdaptorBase() : _graph(0) {} + + void initialize(GR& graph) { _graph = &graph; } + + public: + GraphAdaptorBase(GR& graph) : _graph(&graph) {} + + typedef typename GR::Node Node; + typedef typename GR::Arc Arc; + typedef typename GR::Edge Edge; + + void first(Node& i) const { _graph->first(i); } + void first(Arc& i) const { _graph->first(i); } + void first(Edge& i) const { _graph->first(i); } + void firstIn(Arc& i, const Node& n) const { _graph->firstIn(i, n); } + void firstOut(Arc& i, const Node& n ) const { _graph->firstOut(i, n); } + void firstInc(Edge &i, bool &d, const Node &n) const { + _graph->firstInc(i, d, n); + } + + void next(Node& i) const { _graph->next(i); } + void next(Arc& i) const { _graph->next(i); } + void next(Edge& i) const { _graph->next(i); } + void nextIn(Arc& i) const { _graph->nextIn(i); } + void nextOut(Arc& i) const { _graph->nextOut(i); } + void nextInc(Edge &i, bool &d) const { _graph->nextInc(i, d); } + + Node u(const Edge& e) const { return _graph->u(e); } + Node v(const Edge& e) const { return _graph->v(e); } + + Node source(const Arc& a) const { return _graph->source(a); } + Node target(const Arc& a) const { return _graph->target(a); } + + typedef NodeNumTagIndicator NodeNumTag; + int nodeNum() const { return _graph->nodeNum(); } + + typedef ArcNumTagIndicator ArcNumTag; + int arcNum() const { return _graph->arcNum(); } + + typedef EdgeNumTagIndicator EdgeNumTag; + int edgeNum() const { return _graph->edgeNum(); } + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(const Node& u, const Node& v, + const Arc& prev = INVALID) const { + return _graph->findArc(u, v, prev); + } + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& u, const Node& v, + const Edge& prev = INVALID) const { + return _graph->findEdge(u, v, prev); + } + + Node addNode() { return _graph->addNode(); } + Edge addEdge(const Node& u, const Node& v) { return _graph->addEdge(u, v); } + + void erase(const Node& i) { _graph->erase(i); } + void erase(const Edge& i) { _graph->erase(i); } + + void clear() { _graph->clear(); } + + bool direction(const Arc& a) const { return _graph->direction(a); } + Arc direct(const Edge& e, bool d) const { return _graph->direct(e, d); } + + int id(const Node& v) const { return _graph->id(v); } + int id(const Arc& a) const { return _graph->id(a); } + int id(const Edge& e) const { return _graph->id(e); } + + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); } + Arc arcFromId(int ix) const { return _graph->arcFromId(ix); } + Edge edgeFromId(int ix) const { return _graph->edgeFromId(ix); } + + int maxNodeId() const { return _graph->maxNodeId(); } + int maxArcId() const { return _graph->maxArcId(); } + int maxEdgeId() const { return _graph->maxEdgeId(); } + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); } + + typedef typename ItemSetTraits::ItemNotifier ArcNotifier; + ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); } + + typedef typename ItemSetTraits::ItemNotifier EdgeNotifier; + EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); } + + template + class NodeMap : public GR::template NodeMap { + typedef typename GR::template NodeMap Parent; + + public: + explicit NodeMap(const GraphAdaptorBase& adapter) + : Parent(*adapter._graph) {} + NodeMap(const GraphAdaptorBase& adapter, const V& value) + : Parent(*adapter._graph, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + template + class ArcMap : public GR::template ArcMap { + typedef typename GR::template ArcMap Parent; + + public: + explicit ArcMap(const GraphAdaptorBase& adapter) + : Parent(*adapter._graph) {} + ArcMap(const GraphAdaptorBase& adapter, const V& value) + : Parent(*adapter._graph, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class EdgeMap : public GR::template EdgeMap { + typedef typename GR::template EdgeMap Parent; + + public: + explicit EdgeMap(const GraphAdaptorBase& adapter) + : Parent(*adapter._graph) {} + EdgeMap(const GraphAdaptorBase& adapter, const V& value) + : Parent(*adapter._graph, value) {} + + private: + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + template + class ReverseDigraphBase : public DigraphAdaptorBase { + typedef DigraphAdaptorBase Parent; + public: + typedef DGR Digraph; + protected: + ReverseDigraphBase() : Parent() { } + public: + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + void firstIn(Arc& a, const Node& n) const { Parent::firstOut(a, n); } + void firstOut(Arc& a, const Node& n ) const { Parent::firstIn(a, n); } + + void nextIn(Arc& a) const { Parent::nextOut(a); } + void nextOut(Arc& a) const { Parent::nextIn(a); } + + Node source(const Arc& a) const { return Parent::target(a); } + Node target(const Arc& a) const { return Parent::source(a); } + + Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); } + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(const Node& u, const Node& v, + const Arc& prev = INVALID) const { + return Parent::findArc(v, u, prev); + } + + }; + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for reversing the orientation of the arcs in + /// a digraph. + /// + /// ReverseDigraph can be used for reversing the arcs in a digraph. + /// It conforms to the \ref concepts::Digraph "Digraph" concept. + /// + /// The adapted digraph can also be modified through this adaptor + /// by adding or removing nodes or arcs, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides item counting in the same time as the adapted + /// digraph structure. + /// + /// \tparam DGR The type of the adapted digraph. + /// It must conform to the \ref concepts::Digraph "Digraph" concept. + /// It can also be specified to be \c const. + /// + /// \note The \c Node and \c Arc types of this adaptor and the adapted + /// digraph are convertible to each other. + template +#ifdef DOXYGEN + class ReverseDigraph { +#else + class ReverseDigraph : + public DigraphAdaptorExtender > { +#endif + typedef DigraphAdaptorExtender > Parent; + public: + /// The type of the adapted digraph. + typedef DGR Digraph; + protected: + ReverseDigraph() { } + public: + + /// \brief Constructor + /// + /// Creates a reverse digraph adaptor for the given digraph. + explicit ReverseDigraph(DGR& digraph) { + Parent::initialize(digraph); + } + }; + + /// \brief Returns a read-only ReverseDigraph adaptor + /// + /// This function just returns a read-only \ref ReverseDigraph adaptor. + /// \ingroup graph_adaptors + /// \relates ReverseDigraph + template + ReverseDigraph reverseDigraph(const DGR& digraph) { + return ReverseDigraph(digraph); + } + + + template + class SubDigraphBase : public DigraphAdaptorBase { + typedef DigraphAdaptorBase Parent; + public: + typedef DGR Digraph; + typedef NF NodeFilterMap; + typedef AF ArcFilterMap; + + typedef SubDigraphBase Adaptor; + protected: + NF* _node_filter; + AF* _arc_filter; + SubDigraphBase() + : Parent(), _node_filter(0), _arc_filter(0) { } + + void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) { + Parent::initialize(digraph); + _node_filter = &node_filter; + _arc_filter = &arc_filter; + } + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + void first(Node& i) const { + Parent::first(i); + while (i != INVALID && !(*_node_filter)[i]) Parent::next(i); + } + + void first(Arc& i) const { + Parent::first(i); + while (i != INVALID && (!(*_arc_filter)[i] + || !(*_node_filter)[Parent::source(i)] + || !(*_node_filter)[Parent::target(i)])) + Parent::next(i); + } + + void firstIn(Arc& i, const Node& n) const { + Parent::firstIn(i, n); + while (i != INVALID && (!(*_arc_filter)[i] + || !(*_node_filter)[Parent::source(i)])) + Parent::nextIn(i); + } + + void firstOut(Arc& i, const Node& n) const { + Parent::firstOut(i, n); + while (i != INVALID && (!(*_arc_filter)[i] + || !(*_node_filter)[Parent::target(i)])) + Parent::nextOut(i); + } + + void next(Node& i) const { + Parent::next(i); + while (i != INVALID && !(*_node_filter)[i]) Parent::next(i); + } + + void next(Arc& i) const { + Parent::next(i); + while (i != INVALID && (!(*_arc_filter)[i] + || !(*_node_filter)[Parent::source(i)] + || !(*_node_filter)[Parent::target(i)])) + Parent::next(i); + } + + void nextIn(Arc& i) const { + Parent::nextIn(i); + while (i != INVALID && (!(*_arc_filter)[i] + || !(*_node_filter)[Parent::source(i)])) + Parent::nextIn(i); + } + + void nextOut(Arc& i) const { + Parent::nextOut(i); + while (i != INVALID && (!(*_arc_filter)[i] + || !(*_node_filter)[Parent::target(i)])) + Parent::nextOut(i); + } + + void status(const Node& n, bool v) const { _node_filter->set(n, v); } + void status(const Arc& a, bool v) const { _arc_filter->set(a, v); } + + bool status(const Node& n) const { return (*_node_filter)[n]; } + bool status(const Arc& a) const { return (*_arc_filter)[a]; } + + typedef False NodeNumTag; + typedef False ArcNumTag; + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(const Node& source, const Node& target, + const Arc& prev = INVALID) const { + if (!(*_node_filter)[source] || !(*_node_filter)[target]) { + return INVALID; + } + Arc arc = Parent::findArc(source, target, prev); + while (arc != INVALID && !(*_arc_filter)[arc]) { + arc = Parent::findArc(source, target, arc); + } + return arc; + } + + public: + + template + class NodeMap + : public SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, NodeMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, NodeMap)> Parent; + + public: + typedef V Value; + + NodeMap(const SubDigraphBase& adaptor) + : Parent(adaptor) {} + NodeMap(const SubDigraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class ArcMap + : public SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, ArcMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, ArcMap)> Parent; + + public: + typedef V Value; + + ArcMap(const SubDigraphBase& adaptor) + : Parent(adaptor) {} + ArcMap(const SubDigraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + template + class SubDigraphBase + : public DigraphAdaptorBase { + typedef DigraphAdaptorBase Parent; + public: + typedef DGR Digraph; + typedef NF NodeFilterMap; + typedef AF ArcFilterMap; + + typedef SubDigraphBase Adaptor; + protected: + NF* _node_filter; + AF* _arc_filter; + SubDigraphBase() + : Parent(), _node_filter(0), _arc_filter(0) { } + + void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) { + Parent::initialize(digraph); + _node_filter = &node_filter; + _arc_filter = &arc_filter; + } + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + void first(Node& i) const { + Parent::first(i); + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i); + } + + void first(Arc& i) const { + Parent::first(i); + while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i); + } + + void firstIn(Arc& i, const Node& n) const { + Parent::firstIn(i, n); + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i); + } + + void firstOut(Arc& i, const Node& n) const { + Parent::firstOut(i, n); + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i); + } + + void next(Node& i) const { + Parent::next(i); + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i); + } + void next(Arc& i) const { + Parent::next(i); + while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i); + } + void nextIn(Arc& i) const { + Parent::nextIn(i); + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i); + } + + void nextOut(Arc& i) const { + Parent::nextOut(i); + while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i); + } + + void status(const Node& n, bool v) const { _node_filter->set(n, v); } + void status(const Arc& a, bool v) const { _arc_filter->set(a, v); } + + bool status(const Node& n) const { return (*_node_filter)[n]; } + bool status(const Arc& a) const { return (*_arc_filter)[a]; } + + typedef False NodeNumTag; + typedef False ArcNumTag; + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(const Node& source, const Node& target, + const Arc& prev = INVALID) const { + if (!(*_node_filter)[source] || !(*_node_filter)[target]) { + return INVALID; + } + Arc arc = Parent::findArc(source, target, prev); + while (arc != INVALID && !(*_arc_filter)[arc]) { + arc = Parent::findArc(source, target, arc); + } + return arc; + } + + template + class NodeMap + : public SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, NodeMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, NodeMap)> Parent; + + public: + typedef V Value; + + NodeMap(const SubDigraphBase& adaptor) + : Parent(adaptor) {} + NodeMap(const SubDigraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class ArcMap + : public SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, ArcMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(DigraphAdaptorBase, ArcMap)> Parent; + + public: + typedef V Value; + + ArcMap(const SubDigraphBase& adaptor) + : Parent(adaptor) {} + ArcMap(const SubDigraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for hiding nodes and arcs in a digraph + /// + /// SubDigraph can be used for hiding nodes and arcs in a digraph. + /// A \c bool node map and a \c bool arc map must be specified, which + /// define the filters for nodes and arcs. + /// Only the nodes and arcs with \c true filter value are + /// shown in the subdigraph. The arcs that are incident to hidden + /// nodes are also filtered out. + /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept. + /// + /// The adapted digraph can also be modified through this adaptor + /// by adding or removing nodes or arcs, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides only linear time counting for nodes and arcs. + /// + /// \tparam DGR The type of the adapted digraph. + /// It must conform to the \ref concepts::Digraph "Digraph" concept. + /// It can also be specified to be \c const. + /// \tparam NF The type of the node filter map. + /// It must be a \c bool (or convertible) node map of the + /// adapted digraph. The default type is + /// \ref concepts::Digraph::NodeMap "DGR::NodeMap". + /// \tparam AF The type of the arc filter map. + /// It must be \c bool (or convertible) arc map of the + /// adapted digraph. The default type is + /// \ref concepts::Digraph::ArcMap "DGR::ArcMap". + /// + /// \note The \c Node and \c Arc types of this adaptor and the adapted + /// digraph are convertible to each other. + /// + /// \see FilterNodes + /// \see FilterArcs +#ifdef DOXYGEN + template + class SubDigraph { +#else + template, + typename AF = typename DGR::template ArcMap > + class SubDigraph : + public DigraphAdaptorExtender > { +#endif + public: + /// The type of the adapted digraph. + typedef DGR Digraph; + /// The type of the node filter map. + typedef NF NodeFilterMap; + /// The type of the arc filter map. + typedef AF ArcFilterMap; + + typedef DigraphAdaptorExtender > + Parent; + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + protected: + SubDigraph() { } + public: + + /// \brief Constructor + /// + /// Creates a subdigraph for the given digraph with the + /// given node and arc filter maps. + SubDigraph(DGR& digraph, NF& node_filter, AF& arc_filter) { + Parent::initialize(digraph, node_filter, arc_filter); + } + + /// \brief Sets the status of the given node + /// + /// This function sets the status of the given node. + /// It is done by simply setting the assigned value of \c n + /// to \c v in the node filter map. + void status(const Node& n, bool v) const { Parent::status(n, v); } + + /// \brief Sets the status of the given arc + /// + /// This function sets the status of the given arc. + /// It is done by simply setting the assigned value of \c a + /// to \c v in the arc filter map. + void status(const Arc& a, bool v) const { Parent::status(a, v); } + + /// \brief Returns the status of the given node + /// + /// This function returns the status of the given node. + /// It is \c true if the given node is enabled (i.e. not hidden). + bool status(const Node& n) const { return Parent::status(n); } + + /// \brief Returns the status of the given arc + /// + /// This function returns the status of the given arc. + /// It is \c true if the given arc is enabled (i.e. not hidden). + bool status(const Arc& a) const { return Parent::status(a); } + + /// \brief Disables the given node + /// + /// This function disables the given node in the subdigraph, + /// so the iteration jumps over it. + /// It is the same as \ref status() "status(n, false)". + void disable(const Node& n) const { Parent::status(n, false); } + + /// \brief Disables the given arc + /// + /// This function disables the given arc in the subdigraph, + /// so the iteration jumps over it. + /// It is the same as \ref status() "status(a, false)". + void disable(const Arc& a) const { Parent::status(a, false); } + + /// \brief Enables the given node + /// + /// This function enables the given node in the subdigraph. + /// It is the same as \ref status() "status(n, true)". + void enable(const Node& n) const { Parent::status(n, true); } + + /// \brief Enables the given arc + /// + /// This function enables the given arc in the subdigraph. + /// It is the same as \ref status() "status(a, true)". + void enable(const Arc& a) const { Parent::status(a, true); } + + }; + + /// \brief Returns a read-only SubDigraph adaptor + /// + /// This function just returns a read-only \ref SubDigraph adaptor. + /// \ingroup graph_adaptors + /// \relates SubDigraph + template + SubDigraph + subDigraph(const DGR& digraph, + NF& node_filter, AF& arc_filter) { + return SubDigraph + (digraph, node_filter, arc_filter); + } + + template + SubDigraph + subDigraph(const DGR& digraph, + const NF& node_filter, AF& arc_filter) { + return SubDigraph + (digraph, node_filter, arc_filter); + } + + template + SubDigraph + subDigraph(const DGR& digraph, + NF& node_filter, const AF& arc_filter) { + return SubDigraph + (digraph, node_filter, arc_filter); + } + + template + SubDigraph + subDigraph(const DGR& digraph, + const NF& node_filter, const AF& arc_filter) { + return SubDigraph + (digraph, node_filter, arc_filter); + } + + + template + class SubGraphBase : public GraphAdaptorBase { + typedef GraphAdaptorBase Parent; + public: + typedef GR Graph; + typedef NF NodeFilterMap; + typedef EF EdgeFilterMap; + + typedef SubGraphBase Adaptor; + protected: + + NF* _node_filter; + EF* _edge_filter; + + SubGraphBase() + : Parent(), _node_filter(0), _edge_filter(0) { } + + void initialize(GR& graph, NF& node_filter, EF& edge_filter) { + Parent::initialize(graph); + _node_filter = &node_filter; + _edge_filter = &edge_filter; + } + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + typedef typename Parent::Edge Edge; + + void first(Node& i) const { + Parent::first(i); + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i); + } + + void first(Arc& i) const { + Parent::first(i); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::source(i)] + || !(*_node_filter)[Parent::target(i)])) + Parent::next(i); + } + + void first(Edge& i) const { + Parent::first(i); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::u(i)] + || !(*_node_filter)[Parent::v(i)])) + Parent::next(i); + } + + void firstIn(Arc& i, const Node& n) const { + Parent::firstIn(i, n); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::source(i)])) + Parent::nextIn(i); + } + + void firstOut(Arc& i, const Node& n) const { + Parent::firstOut(i, n); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::target(i)])) + Parent::nextOut(i); + } + + void firstInc(Edge& i, bool& d, const Node& n) const { + Parent::firstInc(i, d, n); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::u(i)] + || !(*_node_filter)[Parent::v(i)])) + Parent::nextInc(i, d); + } + + void next(Node& i) const { + Parent::next(i); + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i); + } + + void next(Arc& i) const { + Parent::next(i); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::source(i)] + || !(*_node_filter)[Parent::target(i)])) + Parent::next(i); + } + + void next(Edge& i) const { + Parent::next(i); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::u(i)] + || !(*_node_filter)[Parent::v(i)])) + Parent::next(i); + } + + void nextIn(Arc& i) const { + Parent::nextIn(i); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::source(i)])) + Parent::nextIn(i); + } + + void nextOut(Arc& i) const { + Parent::nextOut(i); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::target(i)])) + Parent::nextOut(i); + } + + void nextInc(Edge& i, bool& d) const { + Parent::nextInc(i, d); + while (i!=INVALID && (!(*_edge_filter)[i] + || !(*_node_filter)[Parent::u(i)] + || !(*_node_filter)[Parent::v(i)])) + Parent::nextInc(i, d); + } + + void status(const Node& n, bool v) const { _node_filter->set(n, v); } + void status(const Edge& e, bool v) const { _edge_filter->set(e, v); } + + bool status(const Node& n) const { return (*_node_filter)[n]; } + bool status(const Edge& e) const { return (*_edge_filter)[e]; } + + typedef False NodeNumTag; + typedef False ArcNumTag; + typedef False EdgeNumTag; + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(const Node& u, const Node& v, + const Arc& prev = INVALID) const { + if (!(*_node_filter)[u] || !(*_node_filter)[v]) { + return INVALID; + } + Arc arc = Parent::findArc(u, v, prev); + while (arc != INVALID && !(*_edge_filter)[arc]) { + arc = Parent::findArc(u, v, arc); + } + return arc; + } + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& u, const Node& v, + const Edge& prev = INVALID) const { + if (!(*_node_filter)[u] || !(*_node_filter)[v]) { + return INVALID; + } + Edge edge = Parent::findEdge(u, v, prev); + while (edge != INVALID && !(*_edge_filter)[edge]) { + edge = Parent::findEdge(u, v, edge); + } + return edge; + } + + template + class NodeMap + : public SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, NodeMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, NodeMap)> Parent; + + public: + typedef V Value; + + NodeMap(const SubGraphBase& adaptor) + : Parent(adaptor) {} + NodeMap(const SubGraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class ArcMap + : public SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, ArcMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, ArcMap)> Parent; + + public: + typedef V Value; + + ArcMap(const SubGraphBase& adaptor) + : Parent(adaptor) {} + ArcMap(const SubGraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class EdgeMap + : public SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, EdgeMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, EdgeMap)> Parent; + + public: + typedef V Value; + + EdgeMap(const SubGraphBase& adaptor) + : Parent(adaptor) {} + + EdgeMap(const SubGraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + template + class SubGraphBase + : public GraphAdaptorBase { + typedef GraphAdaptorBase Parent; + public: + typedef GR Graph; + typedef NF NodeFilterMap; + typedef EF EdgeFilterMap; + + typedef SubGraphBase Adaptor; + protected: + NF* _node_filter; + EF* _edge_filter; + SubGraphBase() + : Parent(), _node_filter(0), _edge_filter(0) { } + + void initialize(GR& graph, NF& node_filter, EF& edge_filter) { + Parent::initialize(graph); + _node_filter = &node_filter; + _edge_filter = &edge_filter; + } + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + typedef typename Parent::Edge Edge; + + void first(Node& i) const { + Parent::first(i); + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i); + } + + void first(Arc& i) const { + Parent::first(i); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i); + } + + void first(Edge& i) const { + Parent::first(i); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i); + } + + void firstIn(Arc& i, const Node& n) const { + Parent::firstIn(i, n); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i); + } + + void firstOut(Arc& i, const Node& n) const { + Parent::firstOut(i, n); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i); + } + + void firstInc(Edge& i, bool& d, const Node& n) const { + Parent::firstInc(i, d, n); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d); + } + + void next(Node& i) const { + Parent::next(i); + while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i); + } + void next(Arc& i) const { + Parent::next(i); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i); + } + void next(Edge& i) const { + Parent::next(i); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i); + } + void nextIn(Arc& i) const { + Parent::nextIn(i); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i); + } + + void nextOut(Arc& i) const { + Parent::nextOut(i); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i); + } + void nextInc(Edge& i, bool& d) const { + Parent::nextInc(i, d); + while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d); + } + + void status(const Node& n, bool v) const { _node_filter->set(n, v); } + void status(const Edge& e, bool v) const { _edge_filter->set(e, v); } + + bool status(const Node& n) const { return (*_node_filter)[n]; } + bool status(const Edge& e) const { return (*_edge_filter)[e]; } + + typedef False NodeNumTag; + typedef False ArcNumTag; + typedef False EdgeNumTag; + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(const Node& u, const Node& v, + const Arc& prev = INVALID) const { + Arc arc = Parent::findArc(u, v, prev); + while (arc != INVALID && !(*_edge_filter)[arc]) { + arc = Parent::findArc(u, v, arc); + } + return arc; + } + + typedef FindEdgeTagIndicator FindEdgeTag; + Edge findEdge(const Node& u, const Node& v, + const Edge& prev = INVALID) const { + Edge edge = Parent::findEdge(u, v, prev); + while (edge != INVALID && !(*_edge_filter)[edge]) { + edge = Parent::findEdge(u, v, edge); + } + return edge; + } + + template + class NodeMap + : public SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, NodeMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, NodeMap)> Parent; + + public: + typedef V Value; + + NodeMap(const SubGraphBase& adaptor) + : Parent(adaptor) {} + NodeMap(const SubGraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class ArcMap + : public SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, ArcMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, ArcMap)> Parent; + + public: + typedef V Value; + + ArcMap(const SubGraphBase& adaptor) + : Parent(adaptor) {} + ArcMap(const SubGraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class EdgeMap + : public SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, EdgeMap)> { + typedef SubMapExtender, + LEMON_SCOPE_FIX(GraphAdaptorBase, EdgeMap)> Parent; + + public: + typedef V Value; + + EdgeMap(const SubGraphBase& adaptor) + : Parent(adaptor) {} + + EdgeMap(const SubGraphBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for hiding nodes and edges in an undirected + /// graph. + /// + /// SubGraph can be used for hiding nodes and edges in a graph. + /// A \c bool node map and a \c bool edge map must be specified, which + /// define the filters for nodes and edges. + /// Only the nodes and edges with \c true filter value are + /// shown in the subgraph. The edges that are incident to hidden + /// nodes are also filtered out. + /// This adaptor conforms to the \ref concepts::Graph "Graph" concept. + /// + /// The adapted graph can also be modified through this adaptor + /// by adding or removing nodes or edges, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides only linear time counting for nodes, edges and arcs. + /// + /// \tparam GR The type of the adapted graph. + /// It must conform to the \ref concepts::Graph "Graph" concept. + /// It can also be specified to be \c const. + /// \tparam NF The type of the node filter map. + /// It must be a \c bool (or convertible) node map of the + /// adapted graph. The default type is + /// \ref concepts::Graph::NodeMap "GR::NodeMap". + /// \tparam EF The type of the edge filter map. + /// It must be a \c bool (or convertible) edge map of the + /// adapted graph. The default type is + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap". + /// + /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the + /// adapted graph are convertible to each other. + /// + /// \see FilterNodes + /// \see FilterEdges +#ifdef DOXYGEN + template + class SubGraph { +#else + template, + typename EF = typename GR::template EdgeMap > + class SubGraph : + public GraphAdaptorExtender > { +#endif + public: + /// The type of the adapted graph. + typedef GR Graph; + /// The type of the node filter map. + typedef NF NodeFilterMap; + /// The type of the edge filter map. + typedef EF EdgeFilterMap; + + typedef GraphAdaptorExtender > + Parent; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + + protected: + SubGraph() { } + public: + + /// \brief Constructor + /// + /// Creates a subgraph for the given graph with the given node + /// and edge filter maps. + SubGraph(GR& graph, NF& node_filter, EF& edge_filter) { + initialize(graph, node_filter, edge_filter); + } + + /// \brief Sets the status of the given node + /// + /// This function sets the status of the given node. + /// It is done by simply setting the assigned value of \c n + /// to \c v in the node filter map. + void status(const Node& n, bool v) const { Parent::status(n, v); } + + /// \brief Sets the status of the given edge + /// + /// This function sets the status of the given edge. + /// It is done by simply setting the assigned value of \c e + /// to \c v in the edge filter map. + void status(const Edge& e, bool v) const { Parent::status(e, v); } + + /// \brief Returns the status of the given node + /// + /// This function returns the status of the given node. + /// It is \c true if the given node is enabled (i.e. not hidden). + bool status(const Node& n) const { return Parent::status(n); } + + /// \brief Returns the status of the given edge + /// + /// This function returns the status of the given edge. + /// It is \c true if the given edge is enabled (i.e. not hidden). + bool status(const Edge& e) const { return Parent::status(e); } + + /// \brief Disables the given node + /// + /// This function disables the given node in the subdigraph, + /// so the iteration jumps over it. + /// It is the same as \ref status() "status(n, false)". + void disable(const Node& n) const { Parent::status(n, false); } + + /// \brief Disables the given edge + /// + /// This function disables the given edge in the subgraph, + /// so the iteration jumps over it. + /// It is the same as \ref status() "status(e, false)". + void disable(const Edge& e) const { Parent::status(e, false); } + + /// \brief Enables the given node + /// + /// This function enables the given node in the subdigraph. + /// It is the same as \ref status() "status(n, true)". + void enable(const Node& n) const { Parent::status(n, true); } + + /// \brief Enables the given edge + /// + /// This function enables the given edge in the subgraph. + /// It is the same as \ref status() "status(e, true)". + void enable(const Edge& e) const { Parent::status(e, true); } + + }; + + /// \brief Returns a read-only SubGraph adaptor + /// + /// This function just returns a read-only \ref SubGraph adaptor. + /// \ingroup graph_adaptors + /// \relates SubGraph + template + SubGraph + subGraph(const GR& graph, NF& node_filter, EF& edge_filter) { + return SubGraph + (graph, node_filter, edge_filter); + } + + template + SubGraph + subGraph(const GR& graph, const NF& node_filter, EF& edge_filter) { + return SubGraph + (graph, node_filter, edge_filter); + } + + template + SubGraph + subGraph(const GR& graph, NF& node_filter, const EF& edge_filter) { + return SubGraph + (graph, node_filter, edge_filter); + } + + template + SubGraph + subGraph(const GR& graph, const NF& node_filter, const EF& edge_filter) { + return SubGraph + (graph, node_filter, edge_filter); + } + + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for hiding nodes in a digraph or a graph. + /// + /// FilterNodes adaptor can be used for hiding nodes in a digraph or a + /// graph. A \c bool node map must be specified, which defines the filter + /// for the nodes. Only the nodes with \c true filter value and the + /// arcs/edges incident to nodes both with \c true filter value are shown + /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph + /// "Digraph" concept or the \ref concepts::Graph "Graph" concept + /// depending on the \c GR template parameter. + /// + /// The adapted (di)graph can also be modified through this adaptor + /// by adding or removing nodes or arcs/edges, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides only linear time item counting. + /// + /// \tparam GR The type of the adapted digraph or graph. + /// It must conform to the \ref concepts::Digraph "Digraph" concept + /// or the \ref concepts::Graph "Graph" concept. + /// It can also be specified to be \c const. + /// \tparam NF The type of the node filter map. + /// It must be a \c bool (or convertible) node map of the + /// adapted (di)graph. The default type is + /// \ref concepts::Graph::NodeMap "GR::NodeMap". + /// + /// \note The \c Node and Arc/Edge types of this adaptor and the + /// adapted (di)graph are convertible to each other. +#ifdef DOXYGEN + template + class FilterNodes { +#else + template, + typename Enable = void> + class FilterNodes : + public DigraphAdaptorExtender< + SubDigraphBase >, + true> > { +#endif + typedef DigraphAdaptorExtender< + SubDigraphBase >, + true> > Parent; + + public: + + typedef GR Digraph; + typedef NF NodeFilterMap; + + typedef typename Parent::Node Node; + + protected: + ConstMap > const_true_map; + + FilterNodes() : const_true_map() {} + + public: + + /// \brief Constructor + /// + /// Creates a subgraph for the given digraph or graph with the + /// given node filter map. + FilterNodes(GR& graph, NF& node_filter) + : Parent(), const_true_map() + { + Parent::initialize(graph, node_filter, const_true_map); + } + + /// \brief Sets the status of the given node + /// + /// This function sets the status of the given node. + /// It is done by simply setting the assigned value of \c n + /// to \c v in the node filter map. + void status(const Node& n, bool v) const { Parent::status(n, v); } + + /// \brief Returns the status of the given node + /// + /// This function returns the status of the given node. + /// It is \c true if the given node is enabled (i.e. not hidden). + bool status(const Node& n) const { return Parent::status(n); } + + /// \brief Disables the given node + /// + /// This function disables the given node, so the iteration + /// jumps over it. + /// It is the same as \ref status() "status(n, false)". + void disable(const Node& n) const { Parent::status(n, false); } + + /// \brief Enables the given node + /// + /// This function enables the given node. + /// It is the same as \ref status() "status(n, true)". + void enable(const Node& n) const { Parent::status(n, true); } + + }; + + template + class FilterNodes >::type> : + public GraphAdaptorExtender< + SubGraphBase >, + true> > { + + typedef GraphAdaptorExtender< + SubGraphBase >, + true> > Parent; + + public: + + typedef GR Graph; + typedef NF NodeFilterMap; + + typedef typename Parent::Node Node; + + protected: + ConstMap > const_true_map; + + FilterNodes() : const_true_map() {} + + public: + + FilterNodes(GR& graph, NodeFilterMap& node_filter) : + Parent(), const_true_map() { + Parent::initialize(graph, node_filter, const_true_map); + } + + void status(const Node& n, bool v) const { Parent::status(n, v); } + bool status(const Node& n) const { return Parent::status(n); } + void disable(const Node& n) const { Parent::status(n, false); } + void enable(const Node& n) const { Parent::status(n, true); } + + }; + + + /// \brief Returns a read-only FilterNodes adaptor + /// + /// This function just returns a read-only \ref FilterNodes adaptor. + /// \ingroup graph_adaptors + /// \relates FilterNodes + template + FilterNodes + filterNodes(const GR& graph, NF& node_filter) { + return FilterNodes(graph, node_filter); + } + + template + FilterNodes + filterNodes(const GR& graph, const NF& node_filter) { + return FilterNodes(graph, node_filter); + } + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for hiding arcs in a digraph. + /// + /// FilterArcs adaptor can be used for hiding arcs in a digraph. + /// A \c bool arc map must be specified, which defines the filter for + /// the arcs. Only the arcs with \c true filter value are shown in the + /// subdigraph. This adaptor conforms to the \ref concepts::Digraph + /// "Digraph" concept. + /// + /// The adapted digraph can also be modified through this adaptor + /// by adding or removing nodes or arcs, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides only linear time counting for nodes and arcs. + /// + /// \tparam DGR The type of the adapted digraph. + /// It must conform to the \ref concepts::Digraph "Digraph" concept. + /// It can also be specified to be \c const. + /// \tparam AF The type of the arc filter map. + /// It must be a \c bool (or convertible) arc map of the + /// adapted digraph. The default type is + /// \ref concepts::Digraph::ArcMap "DGR::ArcMap". + /// + /// \note The \c Node and \c Arc types of this adaptor and the adapted + /// digraph are convertible to each other. +#ifdef DOXYGEN + template + class FilterArcs { +#else + template > + class FilterArcs : + public DigraphAdaptorExtender< + SubDigraphBase >, + AF, false> > { +#endif + typedef DigraphAdaptorExtender< + SubDigraphBase >, + AF, false> > Parent; + + public: + + /// The type of the adapted digraph. + typedef DGR Digraph; + /// The type of the arc filter map. + typedef AF ArcFilterMap; + + typedef typename Parent::Arc Arc; + + protected: + ConstMap > const_true_map; + + FilterArcs() : const_true_map() {} + + public: + + /// \brief Constructor + /// + /// Creates a subdigraph for the given digraph with the given arc + /// filter map. + FilterArcs(DGR& digraph, ArcFilterMap& arc_filter) + : Parent(), const_true_map() { + Parent::initialize(digraph, const_true_map, arc_filter); + } + + /// \brief Sets the status of the given arc + /// + /// This function sets the status of the given arc. + /// It is done by simply setting the assigned value of \c a + /// to \c v in the arc filter map. + void status(const Arc& a, bool v) const { Parent::status(a, v); } + + /// \brief Returns the status of the given arc + /// + /// This function returns the status of the given arc. + /// It is \c true if the given arc is enabled (i.e. not hidden). + bool status(const Arc& a) const { return Parent::status(a); } + + /// \brief Disables the given arc + /// + /// This function disables the given arc in the subdigraph, + /// so the iteration jumps over it. + /// It is the same as \ref status() "status(a, false)". + void disable(const Arc& a) const { Parent::status(a, false); } + + /// \brief Enables the given arc + /// + /// This function enables the given arc in the subdigraph. + /// It is the same as \ref status() "status(a, true)". + void enable(const Arc& a) const { Parent::status(a, true); } + + }; + + /// \brief Returns a read-only FilterArcs adaptor + /// + /// This function just returns a read-only \ref FilterArcs adaptor. + /// \ingroup graph_adaptors + /// \relates FilterArcs + template + FilterArcs + filterArcs(const DGR& digraph, AF& arc_filter) { + return FilterArcs(digraph, arc_filter); + } + + template + FilterArcs + filterArcs(const DGR& digraph, const AF& arc_filter) { + return FilterArcs(digraph, arc_filter); + } + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for hiding edges in a graph. + /// + /// FilterEdges adaptor can be used for hiding edges in a graph. + /// A \c bool edge map must be specified, which defines the filter for + /// the edges. Only the edges with \c true filter value are shown in the + /// subgraph. This adaptor conforms to the \ref concepts::Graph + /// "Graph" concept. + /// + /// The adapted graph can also be modified through this adaptor + /// by adding or removing nodes or edges, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides only linear time counting for nodes, edges and arcs. + /// + /// \tparam GR The type of the adapted graph. + /// It must conform to the \ref concepts::Graph "Graph" concept. + /// It can also be specified to be \c const. + /// \tparam EF The type of the edge filter map. + /// It must be a \c bool (or convertible) edge map of the + /// adapted graph. The default type is + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap". + /// + /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the + /// adapted graph are convertible to each other. +#ifdef DOXYGEN + template + class FilterEdges { +#else + template > + class FilterEdges : + public GraphAdaptorExtender< + SubGraphBase >, + EF, false> > { +#endif + typedef GraphAdaptorExtender< + SubGraphBase >, + EF, false> > Parent; + + public: + + /// The type of the adapted graph. + typedef GR Graph; + /// The type of the edge filter map. + typedef EF EdgeFilterMap; + + typedef typename Parent::Edge Edge; + + protected: + ConstMap > const_true_map; + + FilterEdges() : const_true_map(true) { + Parent::setNodeFilterMap(const_true_map); + } + + public: + + /// \brief Constructor + /// + /// Creates a subgraph for the given graph with the given edge + /// filter map. + FilterEdges(GR& graph, EF& edge_filter) + : Parent(), const_true_map() { + Parent::initialize(graph, const_true_map, edge_filter); + } + + /// \brief Sets the status of the given edge + /// + /// This function sets the status of the given edge. + /// It is done by simply setting the assigned value of \c e + /// to \c v in the edge filter map. + void status(const Edge& e, bool v) const { Parent::status(e, v); } + + /// \brief Returns the status of the given edge + /// + /// This function returns the status of the given edge. + /// It is \c true if the given edge is enabled (i.e. not hidden). + bool status(const Edge& e) const { return Parent::status(e); } + + /// \brief Disables the given edge + /// + /// This function disables the given edge in the subgraph, + /// so the iteration jumps over it. + /// It is the same as \ref status() "status(e, false)". + void disable(const Edge& e) const { Parent::status(e, false); } + + /// \brief Enables the given edge + /// + /// This function enables the given edge in the subgraph. + /// It is the same as \ref status() "status(e, true)". + void enable(const Edge& e) const { Parent::status(e, true); } + + }; + + /// \brief Returns a read-only FilterEdges adaptor + /// + /// This function just returns a read-only \ref FilterEdges adaptor. + /// \ingroup graph_adaptors + /// \relates FilterEdges + template + FilterEdges + filterEdges(const GR& graph, EF& edge_filter) { + return FilterEdges(graph, edge_filter); + } + + template + FilterEdges + filterEdges(const GR& graph, const EF& edge_filter) { + return FilterEdges(graph, edge_filter); + } + + + template + class UndirectorBase { + public: + typedef DGR Digraph; + typedef UndirectorBase Adaptor; + + typedef True UndirectedTag; + + typedef typename Digraph::Arc Edge; + typedef typename Digraph::Node Node; + + class Arc { + friend class UndirectorBase; + protected: + Edge _edge; + bool _forward; + + Arc(const Edge& edge, bool forward) + : _edge(edge), _forward(forward) {} + + public: + Arc() {} + + Arc(Invalid) : _edge(INVALID), _forward(true) {} + + operator const Edge&() const { return _edge; } + + bool operator==(const Arc &other) const { + return _forward == other._forward && _edge == other._edge; + } + bool operator!=(const Arc &other) const { + return _forward != other._forward || _edge != other._edge; + } + bool operator<(const Arc &other) const { + return _forward < other._forward || + (_forward == other._forward && _edge < other._edge); + } + }; + + void first(Node& n) const { + _digraph->first(n); + } + + void next(Node& n) const { + _digraph->next(n); + } + + void first(Arc& a) const { + _digraph->first(a._edge); + a._forward = true; + } + + void next(Arc& a) const { + if (a._forward) { + a._forward = false; + } else { + _digraph->next(a._edge); + a._forward = true; + } + } + + void first(Edge& e) const { + _digraph->first(e); + } + + void next(Edge& e) const { + _digraph->next(e); + } + + void firstOut(Arc& a, const Node& n) const { + _digraph->firstIn(a._edge, n); + if (a._edge != INVALID ) { + a._forward = false; + } else { + _digraph->firstOut(a._edge, n); + a._forward = true; + } + } + void nextOut(Arc &a) const { + if (!a._forward) { + Node n = _digraph->target(a._edge); + _digraph->nextIn(a._edge); + if (a._edge == INVALID) { + _digraph->firstOut(a._edge, n); + a._forward = true; + } + } + else { + _digraph->nextOut(a._edge); + } + } + + void firstIn(Arc &a, const Node &n) const { + _digraph->firstOut(a._edge, n); + if (a._edge != INVALID ) { + a._forward = false; + } else { + _digraph->firstIn(a._edge, n); + a._forward = true; + } + } + void nextIn(Arc &a) const { + if (!a._forward) { + Node n = _digraph->source(a._edge); + _digraph->nextOut(a._edge); + if (a._edge == INVALID ) { + _digraph->firstIn(a._edge, n); + a._forward = true; + } + } + else { + _digraph->nextIn(a._edge); + } + } + + void firstInc(Edge &e, bool &d, const Node &n) const { + d = true; + _digraph->firstOut(e, n); + if (e != INVALID) return; + d = false; + _digraph->firstIn(e, n); + } + + void nextInc(Edge &e, bool &d) const { + if (d) { + Node s = _digraph->source(e); + _digraph->nextOut(e); + if (e != INVALID) return; + d = false; + _digraph->firstIn(e, s); + } else { + _digraph->nextIn(e); + } + } + + Node u(const Edge& e) const { + return _digraph->source(e); + } + + Node v(const Edge& e) const { + return _digraph->target(e); + } + + Node source(const Arc &a) const { + return a._forward ? _digraph->source(a._edge) : _digraph->target(a._edge); + } + + Node target(const Arc &a) const { + return a._forward ? _digraph->target(a._edge) : _digraph->source(a._edge); + } + + static Arc direct(const Edge &e, bool d) { + return Arc(e, d); + } + + static bool direction(const Arc &a) { return a._forward; } + + Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); } + Arc arcFromId(int ix) const { + return direct(_digraph->arcFromId(ix >> 1), bool(ix & 1)); + } + Edge edgeFromId(int ix) const { return _digraph->arcFromId(ix); } + + int id(const Node &n) const { return _digraph->id(n); } + int id(const Arc &a) const { + return (_digraph->id(a) << 1) | (a._forward ? 1 : 0); + } + int id(const Edge &e) const { return _digraph->id(e); } + + int maxNodeId() const { return _digraph->maxNodeId(); } + int maxArcId() const { return (_digraph->maxArcId() << 1) | 1; } + int maxEdgeId() const { return _digraph->maxArcId(); } + + Node addNode() { return _digraph->addNode(); } + Edge addEdge(const Node& u, const Node& v) { + return _digraph->addArc(u, v); + } + + void erase(const Node& i) { _digraph->erase(i); } + void erase(const Edge& i) { _digraph->erase(i); } + + void clear() { _digraph->clear(); } + + typedef NodeNumTagIndicator NodeNumTag; + int nodeNum() const { return _digraph->nodeNum(); } + + typedef ArcNumTagIndicator ArcNumTag; + int arcNum() const { return 2 * _digraph->arcNum(); } + + typedef ArcNumTag EdgeNumTag; + int edgeNum() const { return _digraph->arcNum(); } + + typedef FindArcTagIndicator FindArcTag; + Arc findArc(Node s, Node t, Arc p = INVALID) const { + if (p == INVALID) { + Edge arc = _digraph->findArc(s, t); + if (arc != INVALID) return direct(arc, true); + arc = _digraph->findArc(t, s); + if (arc != INVALID) return direct(arc, false); + } else if (direction(p)) { + Edge arc = _digraph->findArc(s, t, p); + if (arc != INVALID) return direct(arc, true); + arc = _digraph->findArc(t, s); + if (arc != INVALID) return direct(arc, false); + } else { + Edge arc = _digraph->findArc(t, s, p); + if (arc != INVALID) return direct(arc, false); + } + return INVALID; + } + + typedef FindArcTag FindEdgeTag; + Edge findEdge(Node s, Node t, Edge p = INVALID) const { + if (s != t) { + if (p == INVALID) { + Edge arc = _digraph->findArc(s, t); + if (arc != INVALID) return arc; + arc = _digraph->findArc(t, s); + if (arc != INVALID) return arc; + } else if (_digraph->source(p) == s) { + Edge arc = _digraph->findArc(s, t, p); + if (arc != INVALID) return arc; + arc = _digraph->findArc(t, s); + if (arc != INVALID) return arc; + } else { + Edge arc = _digraph->findArc(t, s, p); + if (arc != INVALID) return arc; + } + } else { + return _digraph->findArc(s, t, p); + } + return INVALID; + } + + private: + + template + class ArcMapBase { + private: + + typedef typename DGR::template ArcMap MapImpl; + + public: + + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + + typedef V Value; + typedef Arc Key; + typedef typename MapTraits::ConstReturnValue ConstReturnValue; + typedef typename MapTraits::ReturnValue ReturnValue; + typedef typename MapTraits::ConstReturnValue ConstReference; + typedef typename MapTraits::ReturnValue Reference; + + ArcMapBase(const UndirectorBase& adaptor) : + _forward(*adaptor._digraph), _backward(*adaptor._digraph) {} + + ArcMapBase(const UndirectorBase& adaptor, const V& value) + : _forward(*adaptor._digraph, value), + _backward(*adaptor._digraph, value) {} + + void set(const Arc& a, const V& value) { + if (direction(a)) { + _forward.set(a, value); + } else { + _backward.set(a, value); + } + } + + ConstReturnValue operator[](const Arc& a) const { + if (direction(a)) { + return _forward[a]; + } else { + return _backward[a]; + } + } + + ReturnValue operator[](const Arc& a) { + if (direction(a)) { + return _forward[a]; + } else { + return _backward[a]; + } + } + + protected: + + MapImpl _forward, _backward; + + }; + + public: + + template + class NodeMap : public DGR::template NodeMap { + typedef typename DGR::template NodeMap Parent; + + public: + typedef V Value; + + explicit NodeMap(const UndirectorBase& adaptor) + : Parent(*adaptor._digraph) {} + + NodeMap(const UndirectorBase& adaptor, const V& value) + : Parent(*adaptor._digraph, value) { } + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + template + class ArcMap + : public SubMapExtender, ArcMapBase > { + typedef SubMapExtender, ArcMapBase > Parent; + + public: + typedef V Value; + + explicit ArcMap(const UndirectorBase& adaptor) + : Parent(adaptor) {} + + ArcMap(const UndirectorBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class EdgeMap : public Digraph::template ArcMap { + typedef typename Digraph::template ArcMap Parent; + + public: + typedef V Value; + + explicit EdgeMap(const UndirectorBase& adaptor) + : Parent(*adaptor._digraph) {} + + EdgeMap(const UndirectorBase& adaptor, const V& value) + : Parent(*adaptor._digraph, value) {} + + private: + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); } + + typedef typename ItemSetTraits::ItemNotifier EdgeNotifier; + EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); } + + typedef EdgeNotifier ArcNotifier; + ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); } + + protected: + + UndirectorBase() : _digraph(0) {} + + DGR* _digraph; + + void initialize(DGR& digraph) { + _digraph = &digraph; + } + + }; + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for viewing a digraph as an undirected graph. + /// + /// Undirector adaptor can be used for viewing a digraph as an undirected + /// graph. All arcs of the underlying digraph are showed in the + /// adaptor as an edge (and also as a pair of arcs, of course). + /// This adaptor conforms to the \ref concepts::Graph "Graph" concept. + /// + /// The adapted digraph can also be modified through this adaptor + /// by adding or removing nodes or edges, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides item counting in the same time as the adapted + /// digraph structure. + /// + /// \tparam DGR The type of the adapted digraph. + /// It must conform to the \ref concepts::Digraph "Digraph" concept. + /// It can also be specified to be \c const. + /// + /// \note The \c Node type of this adaptor and the adapted digraph are + /// convertible to each other, moreover the \c Edge type of the adaptor + /// and the \c Arc type of the adapted digraph are also convertible to + /// each other. + /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type + /// of the adapted digraph.) + template +#ifdef DOXYGEN + class Undirector { +#else + class Undirector : + public GraphAdaptorExtender > { +#endif + typedef GraphAdaptorExtender > Parent; + public: + /// The type of the adapted digraph. + typedef DGR Digraph; + protected: + Undirector() { } + public: + + /// \brief Constructor + /// + /// Creates an undirected graph from the given digraph. + Undirector(DGR& digraph) { + initialize(digraph); + } + + /// \brief Arc map combined from two original arc maps + /// + /// This map adaptor class adapts two arc maps of the underlying + /// digraph to get an arc map of the undirected graph. + /// Its value type is inherited from the first arc map type (\c FW). + /// \tparam FW The type of the "foward" arc map. + /// \tparam BK The type of the "backward" arc map. + template + class CombinedArcMap { + public: + + /// The key type of the map + typedef typename Parent::Arc Key; + /// The value type of the map + typedef typename FW::Value Value; + + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + + typedef typename MapTraits::ReturnValue ReturnValue; + typedef typename MapTraits::ConstReturnValue ConstReturnValue; + typedef typename MapTraits::ReturnValue Reference; + typedef typename MapTraits::ConstReturnValue ConstReference; + + /// Constructor + CombinedArcMap(FW& forward, BK& backward) + : _forward(&forward), _backward(&backward) {} + + /// Sets the value associated with the given key. + void set(const Key& e, const Value& a) { + if (Parent::direction(e)) { + _forward->set(e, a); + } else { + _backward->set(e, a); + } + } + + /// Returns the value associated with the given key. + ConstReturnValue operator[](const Key& e) const { + if (Parent::direction(e)) { + return (*_forward)[e]; + } else { + return (*_backward)[e]; + } + } + + /// Returns a reference to the value associated with the given key. + ReturnValue operator[](const Key& e) { + if (Parent::direction(e)) { + return (*_forward)[e]; + } else { + return (*_backward)[e]; + } + } + + protected: + + FW* _forward; + BK* _backward; + + }; + + /// \brief Returns a combined arc map + /// + /// This function just returns a combined arc map. + template + static CombinedArcMap + combinedArcMap(FW& forward, BK& backward) { + return CombinedArcMap(forward, backward); + } + + template + static CombinedArcMap + combinedArcMap(const FW& forward, BK& backward) { + return CombinedArcMap(forward, backward); + } + + template + static CombinedArcMap + combinedArcMap(FW& forward, const BK& backward) { + return CombinedArcMap(forward, backward); + } + + template + static CombinedArcMap + combinedArcMap(const FW& forward, const BK& backward) { + return CombinedArcMap(forward, backward); + } + + }; + + /// \brief Returns a read-only Undirector adaptor + /// + /// This function just returns a read-only \ref Undirector adaptor. + /// \ingroup graph_adaptors + /// \relates Undirector + template + Undirector undirector(const DGR& digraph) { + return Undirector(digraph); + } + + + template + class OrienterBase { + public: + + typedef GR Graph; + typedef DM DirectionMap; + + typedef typename GR::Node Node; + typedef typename GR::Edge Arc; + + void reverseArc(const Arc& arc) { + _direction->set(arc, !(*_direction)[arc]); + } + + void first(Node& i) const { _graph->first(i); } + void first(Arc& i) const { _graph->first(i); } + void firstIn(Arc& i, const Node& n) const { + bool d = true; + _graph->firstInc(i, d, n); + while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d); + } + void firstOut(Arc& i, const Node& n ) const { + bool d = true; + _graph->firstInc(i, d, n); + while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d); + } + + void next(Node& i) const { _graph->next(i); } + void next(Arc& i) const { _graph->next(i); } + void nextIn(Arc& i) const { + bool d = !(*_direction)[i]; + _graph->nextInc(i, d); + while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d); + } + void nextOut(Arc& i) const { + bool d = (*_direction)[i]; + _graph->nextInc(i, d); + while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d); + } + + Node source(const Arc& e) const { + return (*_direction)[e] ? _graph->u(e) : _graph->v(e); + } + Node target(const Arc& e) const { + return (*_direction)[e] ? _graph->v(e) : _graph->u(e); + } + + typedef NodeNumTagIndicator NodeNumTag; + int nodeNum() const { return _graph->nodeNum(); } + + typedef EdgeNumTagIndicator ArcNumTag; + int arcNum() const { return _graph->edgeNum(); } + + typedef FindEdgeTagIndicator FindArcTag; + Arc findArc(const Node& u, const Node& v, + const Arc& prev = INVALID) const { + Arc arc = _graph->findEdge(u, v, prev); + while (arc != INVALID && source(arc) != u) { + arc = _graph->findEdge(u, v, arc); + } + return arc; + } + + Node addNode() { + return Node(_graph->addNode()); + } + + Arc addArc(const Node& u, const Node& v) { + Arc arc = _graph->addEdge(u, v); + _direction->set(arc, _graph->u(arc) == u); + return arc; + } + + void erase(const Node& i) { _graph->erase(i); } + void erase(const Arc& i) { _graph->erase(i); } + + void clear() { _graph->clear(); } + + int id(const Node& v) const { return _graph->id(v); } + int id(const Arc& e) const { return _graph->id(e); } + + Node nodeFromId(int idx) const { return _graph->nodeFromId(idx); } + Arc arcFromId(int idx) const { return _graph->edgeFromId(idx); } + + int maxNodeId() const { return _graph->maxNodeId(); } + int maxArcId() const { return _graph->maxEdgeId(); } + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); } + + typedef typename ItemSetTraits::ItemNotifier ArcNotifier; + ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); } + + template + class NodeMap : public GR::template NodeMap { + typedef typename GR::template NodeMap Parent; + + public: + + explicit NodeMap(const OrienterBase& adapter) + : Parent(*adapter._graph) {} + + NodeMap(const OrienterBase& adapter, const V& value) + : Parent(*adapter._graph, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + template + class ArcMap : public GR::template EdgeMap { + typedef typename Graph::template EdgeMap Parent; + + public: + + explicit ArcMap(const OrienterBase& adapter) + : Parent(*adapter._graph) { } + + ArcMap(const OrienterBase& adapter, const V& value) + : Parent(*adapter._graph, value) { } + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + + + protected: + Graph* _graph; + DM* _direction; + + void initialize(GR& graph, DM& direction) { + _graph = &graph; + _direction = &direction; + } + + }; + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for orienting the edges of a graph to get a digraph + /// + /// Orienter adaptor can be used for orienting the edges of a graph to + /// get a digraph. A \c bool edge map of the underlying graph must be + /// specified, which define the direction of the arcs in the adaptor. + /// The arcs can be easily reversed by the \c reverseArc() member function + /// of the adaptor. + /// This class conforms to the \ref concepts::Digraph "Digraph" concept. + /// + /// The adapted graph can also be modified through this adaptor + /// by adding or removing nodes or arcs, unless the \c GR template + /// parameter is set to be \c const. + /// + /// This class provides item counting in the same time as the adapted + /// graph structure. + /// + /// \tparam GR The type of the adapted graph. + /// It must conform to the \ref concepts::Graph "Graph" concept. + /// It can also be specified to be \c const. + /// \tparam DM The type of the direction map. + /// It must be a \c bool (or convertible) edge map of the + /// adapted graph. The default type is + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap". + /// + /// \note The \c Node type of this adaptor and the adapted graph are + /// convertible to each other, moreover the \c Arc type of the adaptor + /// and the \c Edge type of the adapted graph are also convertible to + /// each other. +#ifdef DOXYGEN + template + class Orienter { +#else + template > + class Orienter : + public DigraphAdaptorExtender > { +#endif + typedef DigraphAdaptorExtender > Parent; + public: + + /// The type of the adapted graph. + typedef GR Graph; + /// The type of the direction edge map. + typedef DM DirectionMap; + + typedef typename Parent::Arc Arc; + + protected: + Orienter() { } + + public: + + /// \brief Constructor + /// + /// Constructor of the adaptor. + Orienter(GR& graph, DM& direction) { + Parent::initialize(graph, direction); + } + + /// \brief Reverses the given arc + /// + /// This function reverses the given arc. + /// It is done by simply negate the assigned value of \c a + /// in the direction map. + void reverseArc(const Arc& a) { + Parent::reverseArc(a); + } + }; + + /// \brief Returns a read-only Orienter adaptor + /// + /// This function just returns a read-only \ref Orienter adaptor. + /// \ingroup graph_adaptors + /// \relates Orienter + template + Orienter + orienter(const GR& graph, DM& direction) { + return Orienter(graph, direction); + } + + template + Orienter + orienter(const GR& graph, const DM& direction) { + return Orienter(graph, direction); + } + + namespace _adaptor_bits { + + template + class ResForwardFilter { + public: + + typedef typename DGR::Arc Key; + typedef bool Value; + + private: + + const CM* _capacity; + const FM* _flow; + TL _tolerance; + + public: + + ResForwardFilter(const CM& capacity, const FM& flow, + const TL& tolerance = TL()) + : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { } + + bool operator[](const typename DGR::Arc& a) const { + return _tolerance.positive((*_capacity)[a] - (*_flow)[a]); + } + }; + + template + class ResBackwardFilter { + public: + + typedef typename DGR::Arc Key; + typedef bool Value; + + private: + + const CM* _capacity; + const FM* _flow; + TL _tolerance; + + public: + + ResBackwardFilter(const CM& capacity, const FM& flow, + const TL& tolerance = TL()) + : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { } + + bool operator[](const typename DGR::Arc& a) const { + return _tolerance.positive((*_flow)[a]); + } + }; + + } + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for composing the residual digraph for directed + /// flow and circulation problems. + /// + /// ResidualDigraph can be used for composing the \e residual digraph + /// for directed flow and circulation problems. Let \f$ G=(V, A) \f$ + /// be a directed graph and let \f$ F \f$ be a number type. + /// Let \f$ flow, cap: A\to F \f$ be functions on the arcs. + /// This adaptor implements a digraph structure with node set \f$ V \f$ + /// and arc set \f$ A_{forward}\cup A_{backward} \f$, + /// where \f$ A_{forward}=\{uv : uv\in A, flow(uv)0\} \f$, i.e. the so + /// called residual digraph. + /// When the union \f$ A_{forward}\cup A_{backward} \f$ is taken, + /// multiplicities are counted, i.e. the adaptor has exactly + /// \f$ |A_{forward}| + |A_{backward}|\f$ arcs (it may have parallel + /// arcs). + /// This class conforms to the \ref concepts::Digraph "Digraph" concept. + /// + /// This class provides only linear time counting for nodes and arcs. + /// + /// \tparam DGR The type of the adapted digraph. + /// It must conform to the \ref concepts::Digraph "Digraph" concept. + /// It is implicitly \c const. + /// \tparam CM The type of the capacity map. + /// It must be an arc map of some numerical type, which defines + /// the capacities in the flow problem. It is implicitly \c const. + /// The default type is + /// \ref concepts::Digraph::ArcMap "GR::ArcMap". + /// \tparam FM The type of the flow map. + /// It must be an arc map of some numerical type, which defines + /// the flow values in the flow problem. The default type is \c CM. + /// \tparam TL The tolerance type for handling inexact computation. + /// The default tolerance type depends on the value type of the + /// capacity map. + /// + /// \note This adaptor is implemented using Undirector and FilterArcs + /// adaptors. + /// + /// \note The \c Node type of this adaptor and the adapted digraph are + /// convertible to each other, moreover the \c Arc type of the adaptor + /// is convertible to the \c Arc type of the adapted digraph. +#ifdef DOXYGEN + template + class ResidualDigraph +#else + template, + typename FM = CM, + typename TL = Tolerance > + class ResidualDigraph + : public SubDigraph< + Undirector, + ConstMap >, + typename Undirector::template CombinedArcMap< + _adaptor_bits::ResForwardFilter, + _adaptor_bits::ResBackwardFilter > > +#endif + { + public: + + /// The type of the underlying digraph. + typedef DGR Digraph; + /// The type of the capacity map. + typedef CM CapacityMap; + /// The type of the flow map. + typedef FM FlowMap; + /// The tolerance type. + typedef TL Tolerance; + + typedef typename CapacityMap::Value Value; + typedef ResidualDigraph Adaptor; + + protected: + + typedef Undirector Undirected; + + typedef ConstMap > NodeFilter; + + typedef _adaptor_bits::ResForwardFilter ForwardFilter; + + typedef _adaptor_bits::ResBackwardFilter BackwardFilter; + + typedef typename Undirected:: + template CombinedArcMap ArcFilter; + + typedef SubDigraph Parent; + + const CapacityMap* _capacity; + FlowMap* _flow; + + Undirected _graph; + NodeFilter _node_filter; + ForwardFilter _forward_filter; + BackwardFilter _backward_filter; + ArcFilter _arc_filter; + + public: + + /// \brief Constructor + /// + /// Constructor of the residual digraph adaptor. The parameters are the + /// digraph, the capacity map, the flow map, and a tolerance object. + ResidualDigraph(const DGR& digraph, const CM& capacity, + FM& flow, const TL& tolerance = Tolerance()) + : Parent(), _capacity(&capacity), _flow(&flow), + _graph(digraph), _node_filter(), + _forward_filter(capacity, flow, tolerance), + _backward_filter(capacity, flow, tolerance), + _arc_filter(_forward_filter, _backward_filter) + { + Parent::initialize(_graph, _node_filter, _arc_filter); + } + + typedef typename Parent::Arc Arc; + + /// \brief Returns the residual capacity of the given arc. + /// + /// Returns the residual capacity of the given arc. + Value residualCapacity(const Arc& a) const { + if (Undirected::direction(a)) { + return (*_capacity)[a] - (*_flow)[a]; + } else { + return (*_flow)[a]; + } + } + + /// \brief Augments on the given arc in the residual digraph. + /// + /// Augments on the given arc in the residual digraph. It increases + /// or decreases the flow value on the original arc according to the + /// direction of the residual arc. + void augment(const Arc& a, const Value& v) const { + if (Undirected::direction(a)) { + _flow->set(a, (*_flow)[a] + v); + } else { + _flow->set(a, (*_flow)[a] - v); + } + } + + /// \brief Returns \c true if the given residual arc is a forward arc. + /// + /// Returns \c true if the given residual arc has the same orientation + /// as the original arc, i.e. it is a so called forward arc. + static bool forward(const Arc& a) { + return Undirected::direction(a); + } + + /// \brief Returns \c true if the given residual arc is a backward arc. + /// + /// Returns \c true if the given residual arc has the opposite orientation + /// than the original arc, i.e. it is a so called backward arc. + static bool backward(const Arc& a) { + return !Undirected::direction(a); + } + + /// \brief Returns the forward oriented residual arc. + /// + /// Returns the forward oriented residual arc related to the given + /// arc of the underlying digraph. + static Arc forward(const typename Digraph::Arc& a) { + return Undirected::direct(a, true); + } + + /// \brief Returns the backward oriented residual arc. + /// + /// Returns the backward oriented residual arc related to the given + /// arc of the underlying digraph. + static Arc backward(const typename Digraph::Arc& a) { + return Undirected::direct(a, false); + } + + /// \brief Residual capacity map. + /// + /// This map adaptor class can be used for obtaining the residual + /// capacities as an arc map of the residual digraph. + /// Its value type is inherited from the capacity map. + class ResidualCapacity { + protected: + const Adaptor* _adaptor; + public: + /// The key type of the map + typedef Arc Key; + /// The value type of the map + typedef typename CapacityMap::Value Value; + + /// Constructor + ResidualCapacity(const ResidualDigraph& adaptor) + : _adaptor(&adaptor) {} + + /// Returns the value associated with the given residual arc + Value operator[](const Arc& a) const { + return _adaptor->residualCapacity(a); + } + + }; + + /// \brief Returns a residual capacity map + /// + /// This function just returns a residual capacity map. + ResidualCapacity residualCapacity() const { + return ResidualCapacity(*this); + } + + }; + + /// \brief Returns a (read-only) Residual adaptor + /// + /// This function just returns a (read-only) \ref ResidualDigraph adaptor. + /// \ingroup graph_adaptors + /// \relates ResidualDigraph + template + ResidualDigraph + residualDigraph(const DGR& digraph, const CM& capacity_map, FM& flow_map) { + return ResidualDigraph (digraph, capacity_map, flow_map); + } + + + template + class SplitNodesBase { + typedef DigraphAdaptorBase Parent; + + public: + + typedef DGR Digraph; + typedef SplitNodesBase Adaptor; + + typedef typename DGR::Node DigraphNode; + typedef typename DGR::Arc DigraphArc; + + class Node; + class Arc; + + private: + + template class NodeMapBase; + template class ArcMapBase; + + public: + + class Node : public DigraphNode { + friend class SplitNodesBase; + template friend class NodeMapBase; + private: + + bool _in; + Node(DigraphNode node, bool in) + : DigraphNode(node), _in(in) {} + + public: + + Node() {} + Node(Invalid) : DigraphNode(INVALID), _in(true) {} + + bool operator==(const Node& node) const { + return DigraphNode::operator==(node) && _in == node._in; + } + + bool operator!=(const Node& node) const { + return !(*this == node); + } + + bool operator<(const Node& node) const { + return DigraphNode::operator<(node) || + (DigraphNode::operator==(node) && _in < node._in); + } + }; + + class Arc { + friend class SplitNodesBase; + template friend class ArcMapBase; + private: + typedef BiVariant ArcImpl; + + explicit Arc(const DigraphArc& arc) : _item(arc) {} + explicit Arc(const DigraphNode& node) : _item(node) {} + + ArcImpl _item; + + public: + Arc() {} + Arc(Invalid) : _item(DigraphArc(INVALID)) {} + + bool operator==(const Arc& arc) const { + if (_item.firstState()) { + if (arc._item.firstState()) { + return _item.first() == arc._item.first(); + } + } else { + if (arc._item.secondState()) { + return _item.second() == arc._item.second(); + } + } + return false; + } + + bool operator!=(const Arc& arc) const { + return !(*this == arc); + } + + bool operator<(const Arc& arc) const { + if (_item.firstState()) { + if (arc._item.firstState()) { + return _item.first() < arc._item.first(); + } + return false; + } else { + if (arc._item.secondState()) { + return _item.second() < arc._item.second(); + } + return true; + } + } + + operator DigraphArc() const { return _item.first(); } + operator DigraphNode() const { return _item.second(); } + + }; + + void first(Node& n) const { + _digraph->first(n); + n._in = true; + } + + void next(Node& n) const { + if (n._in) { + n._in = false; + } else { + n._in = true; + _digraph->next(n); + } + } + + void first(Arc& e) const { + e._item.setSecond(); + _digraph->first(e._item.second()); + if (e._item.second() == INVALID) { + e._item.setFirst(); + _digraph->first(e._item.first()); + } + } + + void next(Arc& e) const { + if (e._item.secondState()) { + _digraph->next(e._item.second()); + if (e._item.second() == INVALID) { + e._item.setFirst(); + _digraph->first(e._item.first()); + } + } else { + _digraph->next(e._item.first()); + } + } + + void firstOut(Arc& e, const Node& n) const { + if (n._in) { + e._item.setSecond(n); + } else { + e._item.setFirst(); + _digraph->firstOut(e._item.first(), n); + } + } + + void nextOut(Arc& e) const { + if (!e._item.firstState()) { + e._item.setFirst(INVALID); + } else { + _digraph->nextOut(e._item.first()); + } + } + + void firstIn(Arc& e, const Node& n) const { + if (!n._in) { + e._item.setSecond(n); + } else { + e._item.setFirst(); + _digraph->firstIn(e._item.first(), n); + } + } + + void nextIn(Arc& e) const { + if (!e._item.firstState()) { + e._item.setFirst(INVALID); + } else { + _digraph->nextIn(e._item.first()); + } + } + + Node source(const Arc& e) const { + if (e._item.firstState()) { + return Node(_digraph->source(e._item.first()), false); + } else { + return Node(e._item.second(), true); + } + } + + Node target(const Arc& e) const { + if (e._item.firstState()) { + return Node(_digraph->target(e._item.first()), true); + } else { + return Node(e._item.second(), false); + } + } + + int id(const Node& n) const { + return (_digraph->id(n) << 1) | (n._in ? 0 : 1); + } + Node nodeFromId(int ix) const { + return Node(_digraph->nodeFromId(ix >> 1), (ix & 1) == 0); + } + int maxNodeId() const { + return 2 * _digraph->maxNodeId() + 1; + } + + int id(const Arc& e) const { + if (e._item.firstState()) { + return _digraph->id(e._item.first()) << 1; + } else { + return (_digraph->id(e._item.second()) << 1) | 1; + } + } + Arc arcFromId(int ix) const { + if ((ix & 1) == 0) { + return Arc(_digraph->arcFromId(ix >> 1)); + } else { + return Arc(_digraph->nodeFromId(ix >> 1)); + } + } + int maxArcId() const { + return std::max(_digraph->maxNodeId() << 1, + (_digraph->maxArcId() << 1) | 1); + } + + static bool inNode(const Node& n) { + return n._in; + } + + static bool outNode(const Node& n) { + return !n._in; + } + + static bool origArc(const Arc& e) { + return e._item.firstState(); + } + + static bool bindArc(const Arc& e) { + return e._item.secondState(); + } + + static Node inNode(const DigraphNode& n) { + return Node(n, true); + } + + static Node outNode(const DigraphNode& n) { + return Node(n, false); + } + + static Arc arc(const DigraphNode& n) { + return Arc(n); + } + + static Arc arc(const DigraphArc& e) { + return Arc(e); + } + + typedef True NodeNumTag; + int nodeNum() const { + return 2 * countNodes(*_digraph); + } + + typedef True ArcNumTag; + int arcNum() const { + return countArcs(*_digraph) + countNodes(*_digraph); + } + + typedef True FindArcTag; + Arc findArc(const Node& u, const Node& v, + const Arc& prev = INVALID) const { + if (inNode(u) && outNode(v)) { + if (static_cast(u) == + static_cast(v) && prev == INVALID) { + return Arc(u); + } + } + else if (outNode(u) && inNode(v)) { + return Arc(::lemon::findArc(*_digraph, u, v, prev)); + } + return INVALID; + } + + private: + + template + class NodeMapBase + : public MapTraits > { + typedef typename Parent::template NodeMap NodeImpl; + public: + typedef Node Key; + typedef V Value; + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + typedef typename MapTraits::ReturnValue ReturnValue; + typedef typename MapTraits::ConstReturnValue ConstReturnValue; + typedef typename MapTraits::ReturnValue Reference; + typedef typename MapTraits::ConstReturnValue ConstReference; + + NodeMapBase(const SplitNodesBase& adaptor) + : _in_map(*adaptor._digraph), _out_map(*adaptor._digraph) {} + NodeMapBase(const SplitNodesBase& adaptor, const V& value) + : _in_map(*adaptor._digraph, value), + _out_map(*adaptor._digraph, value) {} + + void set(const Node& key, const V& val) { + if (SplitNodesBase::inNode(key)) { _in_map.set(key, val); } + else {_out_map.set(key, val); } + } + + ReturnValue operator[](const Node& key) { + if (SplitNodesBase::inNode(key)) { return _in_map[key]; } + else { return _out_map[key]; } + } + + ConstReturnValue operator[](const Node& key) const { + if (Adaptor::inNode(key)) { return _in_map[key]; } + else { return _out_map[key]; } + } + + private: + NodeImpl _in_map, _out_map; + }; + + template + class ArcMapBase + : public MapTraits > { + typedef typename Parent::template ArcMap ArcImpl; + typedef typename Parent::template NodeMap NodeImpl; + public: + typedef Arc Key; + typedef V Value; + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + typedef typename MapTraits::ReturnValue ReturnValue; + typedef typename MapTraits::ConstReturnValue ConstReturnValue; + typedef typename MapTraits::ReturnValue Reference; + typedef typename MapTraits::ConstReturnValue ConstReference; + + ArcMapBase(const SplitNodesBase& adaptor) + : _arc_map(*adaptor._digraph), _node_map(*adaptor._digraph) {} + ArcMapBase(const SplitNodesBase& adaptor, const V& value) + : _arc_map(*adaptor._digraph, value), + _node_map(*adaptor._digraph, value) {} + + void set(const Arc& key, const V& val) { + if (SplitNodesBase::origArc(key)) { + _arc_map.set(static_cast(key), val); + } else { + _node_map.set(static_cast(key), val); + } + } + + ReturnValue operator[](const Arc& key) { + if (SplitNodesBase::origArc(key)) { + return _arc_map[static_cast(key)]; + } else { + return _node_map[static_cast(key)]; + } + } + + ConstReturnValue operator[](const Arc& key) const { + if (SplitNodesBase::origArc(key)) { + return _arc_map[static_cast(key)]; + } else { + return _node_map[static_cast(key)]; + } + } + + private: + ArcImpl _arc_map; + NodeImpl _node_map; + }; + + public: + + template + class NodeMap + : public SubMapExtender, NodeMapBase > { + typedef SubMapExtender, NodeMapBase > Parent; + + public: + typedef V Value; + + NodeMap(const SplitNodesBase& adaptor) + : Parent(adaptor) {} + + NodeMap(const SplitNodesBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + template + class ArcMap + : public SubMapExtender, ArcMapBase > { + typedef SubMapExtender, ArcMapBase > Parent; + + public: + typedef V Value; + + ArcMap(const SplitNodesBase& adaptor) + : Parent(adaptor) {} + + ArcMap(const SplitNodesBase& adaptor, const V& value) + : Parent(adaptor, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + protected: + + SplitNodesBase() : _digraph(0) {} + + DGR* _digraph; + + void initialize(Digraph& digraph) { + _digraph = &digraph; + } + + }; + + /// \ingroup graph_adaptors + /// + /// \brief Adaptor class for splitting the nodes of a digraph. + /// + /// SplitNodes adaptor can be used for splitting each node into an + /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor + /// replaces each node \f$ u \f$ in the digraph with two nodes, + /// namely node \f$ u_{in} \f$ and node \f$ u_{out} \f$. + /// If there is a \f$ (v, u) \f$ arc in the original digraph, then the + /// new target of the arc will be \f$ u_{in} \f$ and similarly the + /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$. + /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$ + /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph. + /// + /// The aim of this class is running an algorithm with respect to node + /// costs or capacities if the algorithm considers only arc costs or + /// capacities directly. + /// In this case you can use \c SplitNodes adaptor, and set the node + /// costs/capacities of the original digraph to the \e bind \e arcs + /// in the adaptor. + /// + /// This class provides item counting in the same time as the adapted + /// digraph structure. + /// + /// \tparam DGR The type of the adapted digraph. + /// It must conform to the \ref concepts::Digraph "Digraph" concept. + /// It is implicitly \c const. + /// + /// \note The \c Node type of this adaptor is converible to the \c Node + /// type of the adapted digraph. + template +#ifdef DOXYGEN + class SplitNodes { +#else + class SplitNodes + : public DigraphAdaptorExtender > { +#endif + typedef DigraphAdaptorExtender > Parent; + + public: + typedef DGR Digraph; + + typedef typename DGR::Node DigraphNode; + typedef typename DGR::Arc DigraphArc; + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + /// \brief Constructor + /// + /// Constructor of the adaptor. + SplitNodes(const DGR& g) { + Parent::initialize(g); + } + + /// \brief Returns \c true if the given node is an in-node. + /// + /// Returns \c true if the given node is an in-node. + static bool inNode(const Node& n) { + return Parent::inNode(n); + } + + /// \brief Returns \c true if the given node is an out-node. + /// + /// Returns \c true if the given node is an out-node. + static bool outNode(const Node& n) { + return Parent::outNode(n); + } + + /// \brief Returns \c true if the given arc is an original arc. + /// + /// Returns \c true if the given arc is one of the arcs in the + /// original digraph. + static bool origArc(const Arc& a) { + return Parent::origArc(a); + } + + /// \brief Returns \c true if the given arc is a bind arc. + /// + /// Returns \c true if the given arc is a bind arc, i.e. it connects + /// an in-node and an out-node. + static bool bindArc(const Arc& a) { + return Parent::bindArc(a); + } + + /// \brief Returns the in-node created from the given original node. + /// + /// Returns the in-node created from the given original node. + static Node inNode(const DigraphNode& n) { + return Parent::inNode(n); + } + + /// \brief Returns the out-node created from the given original node. + /// + /// Returns the out-node created from the given original node. + static Node outNode(const DigraphNode& n) { + return Parent::outNode(n); + } + + /// \brief Returns the bind arc that corresponds to the given + /// original node. + /// + /// Returns the bind arc in the adaptor that corresponds to the given + /// original node, i.e. the arc connecting the in-node and out-node + /// of \c n. + static Arc arc(const DigraphNode& n) { + return Parent::arc(n); + } + + /// \brief Returns the arc that corresponds to the given original arc. + /// + /// Returns the arc in the adaptor that corresponds to the given + /// original arc. + static Arc arc(const DigraphArc& a) { + return Parent::arc(a); + } + + /// \brief Node map combined from two original node maps + /// + /// This map adaptor class adapts two node maps of the original digraph + /// to get a node map of the split digraph. + /// Its value type is inherited from the first node map type (\c IN). + /// \tparam IN The type of the node map for the in-nodes. + /// \tparam OUT The type of the node map for the out-nodes. + template + class CombinedNodeMap { + public: + + /// The key type of the map + typedef Node Key; + /// The value type of the map + typedef typename IN::Value Value; + + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + typedef typename MapTraits::ReturnValue ReturnValue; + typedef typename MapTraits::ConstReturnValue ConstReturnValue; + typedef typename MapTraits::ReturnValue Reference; + typedef typename MapTraits::ConstReturnValue ConstReference; + + /// Constructor + CombinedNodeMap(IN& in_map, OUT& out_map) + : _in_map(in_map), _out_map(out_map) {} + + /// Returns the value associated with the given key. + Value operator[](const Key& key) const { + if (SplitNodesBase::inNode(key)) { + return _in_map[key]; + } else { + return _out_map[key]; + } + } + + /// Returns a reference to the value associated with the given key. + Value& operator[](const Key& key) { + if (SplitNodesBase::inNode(key)) { + return _in_map[key]; + } else { + return _out_map[key]; + } + } + + /// Sets the value associated with the given key. + void set(const Key& key, const Value& value) { + if (SplitNodesBase::inNode(key)) { + _in_map.set(key, value); + } else { + _out_map.set(key, value); + } + } + + private: + + IN& _in_map; + OUT& _out_map; + + }; + + + /// \brief Returns a combined node map + /// + /// This function just returns a combined node map. + template + static CombinedNodeMap + combinedNodeMap(IN& in_map, OUT& out_map) { + return CombinedNodeMap(in_map, out_map); + } + + template + static CombinedNodeMap + combinedNodeMap(const IN& in_map, OUT& out_map) { + return CombinedNodeMap(in_map, out_map); + } + + template + static CombinedNodeMap + combinedNodeMap(IN& in_map, const OUT& out_map) { + return CombinedNodeMap(in_map, out_map); + } + + template + static CombinedNodeMap + combinedNodeMap(const IN& in_map, const OUT& out_map) { + return CombinedNodeMap(in_map, out_map); + } + + /// \brief Arc map combined from an arc map and a node map of the + /// original digraph. + /// + /// This map adaptor class adapts an arc map and a node map of the + /// original digraph to get an arc map of the split digraph. + /// Its value type is inherited from the original arc map type (\c AM). + /// \tparam AM The type of the arc map. + /// \tparam NM the type of the node map. + template + class CombinedArcMap { + public: + + /// The key type of the map + typedef Arc Key; + /// The value type of the map + typedef typename AM::Value Value; + + typedef typename MapTraits::ReferenceMapTag ReferenceMapTag; + typedef typename MapTraits::ReturnValue ReturnValue; + typedef typename MapTraits::ConstReturnValue ConstReturnValue; + typedef typename MapTraits::ReturnValue Reference; + typedef typename MapTraits::ConstReturnValue ConstReference; + + /// Constructor + CombinedArcMap(AM& arc_map, NM& node_map) + : _arc_map(arc_map), _node_map(node_map) {} + + /// Returns the value associated with the given key. + Value operator[](const Key& arc) const { + if (SplitNodesBase::origArc(arc)) { + return _arc_map[arc]; + } else { + return _node_map[arc]; + } + } + + /// Returns a reference to the value associated with the given key. + Value& operator[](const Key& arc) { + if (SplitNodesBase::origArc(arc)) { + return _arc_map[arc]; + } else { + return _node_map[arc]; + } + } + + /// Sets the value associated with the given key. + void set(const Arc& arc, const Value& val) { + if (SplitNodesBase::origArc(arc)) { + _arc_map.set(arc, val); + } else { + _node_map.set(arc, val); + } + } + + private: + + AM& _arc_map; + NM& _node_map; + + }; + + /// \brief Returns a combined arc map + /// + /// This function just returns a combined arc map. + template + static CombinedArcMap + combinedArcMap(ArcMap& arc_map, NodeMap& node_map) { + return CombinedArcMap(arc_map, node_map); + } + + template + static CombinedArcMap + combinedArcMap(const ArcMap& arc_map, NodeMap& node_map) { + return CombinedArcMap(arc_map, node_map); + } + + template + static CombinedArcMap + combinedArcMap(ArcMap& arc_map, const NodeMap& node_map) { + return CombinedArcMap(arc_map, node_map); + } + + template + static CombinedArcMap + combinedArcMap(const ArcMap& arc_map, const NodeMap& node_map) { + return CombinedArcMap(arc_map, node_map); + } + + }; + + /// \brief Returns a (read-only) SplitNodes adaptor + /// + /// This function just returns a (read-only) \ref SplitNodes adaptor. + /// \ingroup graph_adaptors + /// \relates SplitNodes + template + SplitNodes + splitNodes(const DGR& digraph) { + return SplitNodes(digraph); + } + +#undef LEMON_SCOPE_FIX + +} //namespace lemon + +#endif //LEMON_ADAPTORS_H diff --git a/lemon/lemon/arg_parser.cc b/lemon/lemon/arg_parser.cc new file mode 100644 index 0000000..35a73d9 --- /dev/null +++ b/lemon/lemon/arg_parser.cc @@ -0,0 +1,474 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +namespace lemon { + + void ArgParser::_terminate(ArgParserException::Reason reason) const + { + if(_exit_on_problems) + exit(1); + else throw(ArgParserException(reason)); + } + + + void ArgParser::_showHelp(void *p) + { + (static_cast(p))->showHelp(); + (static_cast(p))->_terminate(ArgParserException::HELP); + } + + ArgParser::ArgParser(int argc, const char * const *argv) + :_argc(argc), _argv(argv), _command_name(argv[0]), + _exit_on_problems(true) { + funcOption("-help","Print a short help message",_showHelp,this); + synonym("help","-help"); + synonym("h","-help"); + } + + ArgParser::~ArgParser() + { + for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) + if(i->second.self_delete) + switch(i->second.type) { + case BOOL: + delete i->second.bool_p; + break; + case STRING: + delete i->second.string_p; + break; + case DOUBLE: + delete i->second.double_p; + break; + case INTEGER: + delete i->second.int_p; + break; + case UNKNOWN: + break; + case FUNC: + break; + } + } + + + ArgParser &ArgParser::intOption(const std::string &name, + const std::string &help, + int value, bool obl) + { + ParData p; + p.int_p=new int(value); + p.self_delete=true; + p.help=help; + p.type=INTEGER; + p.mandatory=obl; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::doubleOption(const std::string &name, + const std::string &help, + double value, bool obl) + { + ParData p; + p.double_p=new double(value); + p.self_delete=true; + p.help=help; + p.type=DOUBLE; + p.mandatory=obl; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::boolOption(const std::string &name, + const std::string &help, + bool value, bool obl) + { + ParData p; + p.bool_p=new bool(value); + p.self_delete=true; + p.help=help; + p.type=BOOL; + p.mandatory=obl; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::stringOption(const std::string &name, + const std::string &help, + std::string value, bool obl) + { + ParData p; + p.string_p=new std::string(value); + p.self_delete=true; + p.help=help; + p.type=STRING; + p.mandatory=obl; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::refOption(const std::string &name, + const std::string &help, + int &ref, bool obl) + { + ParData p; + p.int_p=&ref; + p.self_delete=false; + p.help=help; + p.type=INTEGER; + p.mandatory=obl; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::refOption(const std::string &name, + const std::string &help, + double &ref, bool obl) + { + ParData p; + p.double_p=&ref; + p.self_delete=false; + p.help=help; + p.type=DOUBLE; + p.mandatory=obl; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::refOption(const std::string &name, + const std::string &help, + bool &ref, bool obl) + { + ParData p; + p.bool_p=&ref; + p.self_delete=false; + p.help=help; + p.type=BOOL; + p.mandatory=obl; + _opts[name]=p; + + ref = false; + + return *this; + } + + ArgParser &ArgParser::refOption(const std::string &name, + const std::string &help, + std::string &ref, bool obl) + { + ParData p; + p.string_p=&ref; + p.self_delete=false; + p.help=help; + p.type=STRING; + p.mandatory=obl; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::funcOption(const std::string &name, + const std::string &help, + void (*func)(void *),void *data) + { + ParData p; + p.func_p.p=func; + p.func_p.data=data; + p.self_delete=false; + p.help=help; + p.type=FUNC; + p.mandatory=false; + _opts[name]=p; + return *this; + } + + ArgParser &ArgParser::optionGroup(const std::string &group, + const std::string &opt) + { + Opts::iterator i = _opts.find(opt); + LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'"); + LEMON_ASSERT(!(i->second.ingroup), + "Option already in option group: '"+opt+"'"); + GroupData &g=_groups[group]; + g.opts.push_back(opt); + i->second.ingroup=true; + return *this; + } + + ArgParser &ArgParser::onlyOneGroup(const std::string &group) + { + GroupData &g=_groups[group]; + g.only_one=true; + return *this; + } + + ArgParser &ArgParser::synonym(const std::string &syn, + const std::string &opt) + { + Opts::iterator o = _opts.find(opt); + Opts::iterator s = _opts.find(syn); + LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'"); + LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'"); + ParData p; + p.help=opt; + p.mandatory=false; + p.syn=true; + _opts[syn]=p; + o->second.has_syn=true; + return *this; + } + + ArgParser &ArgParser::mandatoryGroup(const std::string &group) + { + GroupData &g=_groups[group]; + g.mandatory=true; + return *this; + } + + ArgParser &ArgParser::other(const std::string &name, + const std::string &help) + { + _others_help.push_back(OtherArg(name,help)); + return *this; + } + + void ArgParser::show(std::ostream &os,Opts::const_iterator i) const + { + os << "-" << i->first; + if(i->second.has_syn) + for(Opts::const_iterator j=_opts.begin();j!=_opts.end();++j) + if(j->second.syn&&j->second.help==i->first) + os << "|-" << j->first; + switch(i->second.type) { + case STRING: + os << " str"; + break; + case INTEGER: + os << " int"; + break; + case DOUBLE: + os << " num"; + break; + default: + break; + } + } + + void ArgParser::show(std::ostream &os,Groups::const_iterator i) const + { + GroupData::Opts::const_iterator o=i->second.opts.begin(); + while(o!=i->second.opts.end()) { + show(os,_opts.find(*o)); + ++o; + if(o!=i->second.opts.end()) os<<'|'; + } + } + + void ArgParser::showHelp(Opts::const_iterator i) const + { + if(i->second.help.size()==0||i->second.syn) return; + std::cerr << " "; + show(std::cerr,i); + std::cerr << std::endl; + std::cerr << " " << i->second.help << std::endl; + } + void ArgParser::showHelp(std::vector::const_iterator i) + const + { + if(i->help.size()==0) return; + std::cerr << " " << i->name << std::endl + << " " << i->help << std::endl; + } + + void ArgParser::shortHelp() const + { + const unsigned int LINE_LEN=77; + const std::string indent(" "); + std::cerr << "Usage:\n " << _command_name; + int pos=_command_name.size()+2; + for(Groups::const_iterator g=_groups.begin();g!=_groups.end();++g) { + std::ostringstream cstr; + cstr << ' '; + if(!g->second.mandatory) cstr << '['; + show(cstr,g); + if(!g->second.mandatory) cstr << ']'; + if(pos+cstr.str().size()>LINE_LEN) { + std::cerr << std::endl << indent; + pos=indent.size(); + } + std::cerr << cstr.str(); + pos+=cstr.str().size(); + } + for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) + if(!i->second.ingroup&&!i->second.syn) { + std::ostringstream cstr; + cstr << ' '; + if(!i->second.mandatory) cstr << '['; + show(cstr,i); + if(!i->second.mandatory) cstr << ']'; + if(pos+cstr.str().size()>LINE_LEN) { + std::cerr << std::endl << indent; + pos=indent.size(); + } + std::cerr << cstr.str(); + pos+=cstr.str().size(); + } + for(std::vector::const_iterator i=_others_help.begin(); + i!=_others_help.end();++i) + { + std::ostringstream cstr; + cstr << ' ' << i->name; + + if(pos+cstr.str().size()>LINE_LEN) { + std::cerr << std::endl << indent; + pos=indent.size(); + } + std::cerr << cstr.str(); + pos+=cstr.str().size(); + } + std::cerr << std::endl; + } + + void ArgParser::showHelp() const + { + shortHelp(); + std::cerr << "Where:\n"; + for(std::vector::const_iterator i=_others_help.begin(); + i!=_others_help.end();++i) showHelp(i); + for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i); + _terminate(ArgParserException::HELP); + } + + + void ArgParser::unknownOpt(std::string arg) const + { + std::cerr << "\nUnknown option: " << arg << "\n"; + std::cerr << "\nType '" << _command_name << + " --help' to obtain a short summary on the usage.\n\n"; + _terminate(ArgParserException::UNKNOWN_OPT); + } + + void ArgParser::requiresValue(std::string arg, OptType t) const + { + std::cerr << "Argument '" << arg << "' requires a"; + switch(t) { + case STRING: + std::cerr << " string"; + break; + case INTEGER: + std::cerr << "n integer"; + break; + case DOUBLE: + std::cerr << " floating point"; + break; + default: + break; + } + std::cerr << " value\n\n"; + showHelp(); + } + + + void ArgParser::checkMandatories() const + { + bool ok=true; + for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) + if(i->second.mandatory&&!i->second.set) + { + if(ok) + std::cerr << _command_name + << ": The following mandatory arguments are missing.\n"; + ok=false; + showHelp(i); + } + for(Groups::const_iterator i=_groups.begin();i!=_groups.end();++i) + if(i->second.mandatory||i->second.only_one) + { + int set=0; + for(GroupData::Opts::const_iterator o=i->second.opts.begin(); + o!=i->second.opts.end();++o) + if(_opts.find(*o)->second.set) ++set; + if(i->second.mandatory&&!set) { + std::cerr << _command_name << + ": At least one of the following arguments is mandatory.\n"; + ok=false; + for(GroupData::Opts::const_iterator o=i->second.opts.begin(); + o!=i->second.opts.end();++o) + showHelp(_opts.find(*o)); + } + if(i->second.only_one&&set>1) { + std::cerr << _command_name << + ": At most one of the following arguments can be given.\n"; + ok=false; + for(GroupData::Opts::const_iterator o=i->second.opts.begin(); + o!=i->second.opts.end();++o) + showHelp(_opts.find(*o)); + } + } + if(!ok) { + std::cerr << "\nType '" << _command_name << + " --help' to obtain a short summary on the usage.\n\n"; + _terminate(ArgParserException::INVALID_OPT); + } + } + + ArgParser &ArgParser::parse() + { + for(int ar=1; ar<_argc; ++ar) { + std::string arg(_argv[ar]); + if (arg[0] != '-' || arg.size() == 1) { + _file_args.push_back(arg); + } + else { + Opts::iterator i = _opts.find(arg.substr(1)); + if(i==_opts.end()) unknownOpt(arg); + else { + if(i->second.syn) i=_opts.find(i->second.help); + ParData &p(i->second); + if (p.type==BOOL) *p.bool_p=true; + else if (p.type==FUNC) p.func_p.p(p.func_p.data); + else if(++ar==_argc) requiresValue(arg, p.type); + else { + std::string val(_argv[ar]); + std::istringstream vals(val); + switch(p.type) { + case STRING: + *p.string_p=val; + break; + case INTEGER: + vals >> *p.int_p; + break; + case DOUBLE: + vals >> *p.double_p; + break; + default: + break; + } + if(p.type!=STRING&&(!vals||!vals.eof())) + requiresValue(arg, p.type); + } + p.set = true; + } + } + } + checkMandatories(); + + return *this; + } + +} diff --git a/lemon/lemon/arg_parser.h b/lemon/lemon/arg_parser.h new file mode 100644 index 0000000..3fbe75c --- /dev/null +++ b/lemon/lemon/arg_parser.h @@ -0,0 +1,440 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_ARG_PARSER_H +#define LEMON_ARG_PARSER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +///\ingroup misc +///\file +///\brief A tool to parse command line arguments. + +namespace lemon { + + ///Exception used by ArgParser + + ///Exception used by ArgParser. + /// + class ArgParserException : public Exception { + public: + /// Reasons for failure + + /// Reasons for failure. + /// + enum Reason { + HELP, ///< --help option was given. + UNKNOWN_OPT, ///< Unknown option was given. + INVALID_OPT ///< Invalid combination of options. + }; + + private: + Reason _reason; + + public: + ///Constructor + ArgParserException(Reason r) throw() : _reason(r) {} + ///Virtual destructor + virtual ~ArgParserException() throw() {} + ///A short description of the exception + virtual const char* what() const throw() { + switch(_reason) + { + case HELP: + return "lemon::ArgParseException: ask for help"; + break; + case UNKNOWN_OPT: + return "lemon::ArgParseException: unknown option"; + break; + case INVALID_OPT: + return "lemon::ArgParseException: invalid combination of options"; + break; + } + return ""; + } + ///Return the reason for the failure + Reason reason() const {return _reason; } + }; + + + ///Command line arguments parser + + ///\ingroup misc + ///Command line arguments parser. + /// + ///For a complete example see the \ref arg_parser_demo.cc demo file. + class ArgParser { + + static void _showHelp(void *p); + protected: + + int _argc; + const char * const *_argv; + + enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 }; + + class ParData { + public: + union { + bool *bool_p; + int *int_p; + double *double_p; + std::string *string_p; + struct { + void (*p)(void *); + void *data; + } func_p; + + }; + std::string help; + bool mandatory; + OptType type; + bool set; + bool ingroup; + bool has_syn; + bool syn; + bool self_delete; + ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false), + has_syn(false), syn(false), self_delete(false) {} + }; + + typedef std::map Opts; + Opts _opts; + + class GroupData + { + public: + typedef std::list Opts; + Opts opts; + bool only_one; + bool mandatory; + GroupData() :only_one(false), mandatory(false) {} + }; + + typedef std::map Groups; + Groups _groups; + + struct OtherArg + { + std::string name; + std::string help; + OtherArg(std::string n, std::string h) :name(n), help(h) {} + + }; + + std::vector _others_help; + std::vector _file_args; + std::string _command_name; + + + private: + //Bind a function to an option. + + //\param name The name of the option. The leading '-' must be omitted. + //\param help A help string. + //\retval func The function to be called when the option is given. It + // must be of type "void f(void *)" + //\param data Data to be passed to \c func + ArgParser &funcOption(const std::string &name, + const std::string &help, + void (*func)(void *),void *data); + + bool _exit_on_problems; + + void _terminate(ArgParserException::Reason reason) const; + + public: + + ///Constructor + ArgParser(int argc, const char * const *argv); + + ~ArgParser(); + + ///\name Options + /// + + ///@{ + + ///Add a new integer type option + + ///Add a new integer type option. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param value A default value for the option. + ///\param obl Indicate if the option is mandatory. + ArgParser &intOption(const std::string &name, + const std::string &help, + int value=0, bool obl=false); + + ///Add a new floating point type option + + ///Add a new floating point type option. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param value A default value for the option. + ///\param obl Indicate if the option is mandatory. + ArgParser &doubleOption(const std::string &name, + const std::string &help, + double value=0, bool obl=false); + + ///Add a new bool type option + + ///Add a new bool type option. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param value A default value for the option. + ///\param obl Indicate if the option is mandatory. + ///\note A mandatory bool obtion is of very little use. + ArgParser &boolOption(const std::string &name, + const std::string &help, + bool value=false, bool obl=false); + + ///Add a new string type option + + ///Add a new string type option. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param value A default value for the option. + ///\param obl Indicate if the option is mandatory. + ArgParser &stringOption(const std::string &name, + const std::string &help, + std::string value="", bool obl=false); + + ///Give help string for non-parsed arguments. + + ///With this function you can give help string for non-parsed arguments. + ///The parameter \c name will be printed in the short usage line, while + ///\c help gives a more detailed description. + ArgParser &other(const std::string &name, + const std::string &help=""); + + ///@} + + ///\name Options with External Storage + ///Using this functions, the value of the option will be directly written + ///into a variable once the option appears in the command line. + + ///@{ + + ///Add a new integer type option with a storage reference + + ///Add a new integer type option with a storage reference. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param obl Indicate if the option is mandatory. + ///\retval ref The value of the argument will be written to this variable. + ArgParser &refOption(const std::string &name, + const std::string &help, + int &ref, bool obl=false); + + ///Add a new floating type option with a storage reference + + ///Add a new floating type option with a storage reference. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param obl Indicate if the option is mandatory. + ///\retval ref The value of the argument will be written to this variable. + ArgParser &refOption(const std::string &name, + const std::string &help, + double &ref, bool obl=false); + + ///Add a new bool type option with a storage reference + + ///Add a new bool type option with a storage reference. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param obl Indicate if the option is mandatory. + ///\retval ref The value of the argument will be written to this variable. + ///\note A mandatory bool obtion is of very little use. + ArgParser &refOption(const std::string &name, + const std::string &help, + bool &ref, bool obl=false); + + ///Add a new string type option with a storage reference + + ///Add a new string type option with a storage reference. + ///\param name The name of the option. The leading '-' must be omitted. + ///\param help A help string. + ///\param obl Indicate if the option is mandatory. + ///\retval ref The value of the argument will be written to this variable. + ArgParser &refOption(const std::string &name, + const std::string &help, + std::string &ref, bool obl=false); + + ///@} + + ///\name Option Groups and Synonyms + /// + + ///@{ + + ///Bundle some options into a group + + /// You can group some option by calling this function repeatedly for each + /// option to be grouped with the same groupname. + ///\param group The group name. + ///\param opt The option name. + ArgParser &optionGroup(const std::string &group, + const std::string &opt); + + ///Make the members of a group exclusive + + ///If you call this function for a group, than at most one of them can be + ///given at the same time. + ArgParser &onlyOneGroup(const std::string &group); + + ///Make a group mandatory + + ///Using this function, at least one of the members of \c group + ///must be given. + ArgParser &mandatoryGroup(const std::string &group); + + ///Create synonym to an option + + ///With this function you can create a synonym \c syn of the + ///option \c opt. + ArgParser &synonym(const std::string &syn, + const std::string &opt); + + ///@} + + private: + void show(std::ostream &os,Opts::const_iterator i) const; + void show(std::ostream &os,Groups::const_iterator i) const; + void showHelp(Opts::const_iterator i) const; + void showHelp(std::vector::const_iterator i) const; + + void unknownOpt(std::string arg) const; + + void requiresValue(std::string arg, OptType t) const; + void checkMandatories() const; + + void shortHelp() const; + void showHelp() const; + public: + + ///Start the parsing process + ArgParser &parse(); + + /// Synonym for parse() + ArgParser &run() + { + return parse(); + } + + ///Give back the command name (the 0th argument) + const std::string &commandName() const { return _command_name; } + + ///Check if an opion has been given to the command. + bool given(std::string op) const + { + Opts::const_iterator i = _opts.find(op); + return i!=_opts.end()?i->second.set:false; + } + + + ///Magic type for operator[] + + ///This is the type of the return value of ArgParser::operator[](). + ///It automatically converts to \c int, \c double, \c bool or + ///\c std::string if the type of the option matches, which is checked + ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime + ///type checking). + class RefType + { + const ArgParser &_parser; + std::string _name; + public: + ///\e + RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {} + ///\e + operator bool() + { + Opts::const_iterator i = _parser._opts.find(_name); + LEMON_ASSERT(i!=_parser._opts.end(), + std::string()+"Unkown option: '"+_name+"'"); + LEMON_ASSERT(i->second.type==ArgParser::BOOL, + std::string()+"'"+_name+"' is a bool option"); + return *(i->second.bool_p); + } + ///\e + operator std::string() + { + Opts::const_iterator i = _parser._opts.find(_name); + LEMON_ASSERT(i!=_parser._opts.end(), + std::string()+"Unkown option: '"+_name+"'"); + LEMON_ASSERT(i->second.type==ArgParser::STRING, + std::string()+"'"+_name+"' is a string option"); + return *(i->second.string_p); + } + ///\e + operator double() + { + Opts::const_iterator i = _parser._opts.find(_name); + LEMON_ASSERT(i!=_parser._opts.end(), + std::string()+"Unkown option: '"+_name+"'"); + LEMON_ASSERT(i->second.type==ArgParser::DOUBLE || + i->second.type==ArgParser::INTEGER, + std::string()+"'"+_name+"' is a floating point option"); + return i->second.type==ArgParser::DOUBLE ? + *(i->second.double_p) : *(i->second.int_p); + } + ///\e + operator int() + { + Opts::const_iterator i = _parser._opts.find(_name); + LEMON_ASSERT(i!=_parser._opts.end(), + std::string()+"Unkown option: '"+_name+"'"); + LEMON_ASSERT(i->second.type==ArgParser::INTEGER, + std::string()+"'"+_name+"' is an integer option"); + return *(i->second.int_p); + } + + }; + + ///Give back the value of an option + + ///Give back the value of an option. + ///\sa RefType + RefType operator[](const std::string &n) const + { + return RefType(*this, n); + } + + ///Give back the non-option type arguments. + + ///Give back a reference to a vector consisting of the program arguments + ///not starting with a '-' character. + const std::vector &files() const { return _file_args; } + + ///Throw instead of exit in case of problems + void throwOnProblems() + { + _exit_on_problems=false; + } + }; +} + +#endif // LEMON_ARG_PARSER_H diff --git a/lemon/lemon/assert.h b/lemon/lemon/assert.h new file mode 100644 index 0000000..b4fa8bc --- /dev/null +++ b/lemon/lemon/assert.h @@ -0,0 +1,214 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_ASSERT_H +#define LEMON_ASSERT_H + +/// \ingroup exceptions +/// \file +/// \brief Extended assertion handling + +#include + +namespace lemon { + + inline void assert_fail_abort(const char *file, int line, + const char *function, const char* message, + const char *assertion) + { + std::cerr << file << ":" << line << ": "; + if (function) + std::cerr << function << ": "; + std::cerr << message; + if (assertion) + std::cerr << " (assertion '" << assertion << "' failed)"; + std::cerr << std::endl; + std::abort(); + } + + namespace _assert_bits { + + + inline const char* cstringify(const std::string& str) { + return str.c_str(); + } + + inline const char* cstringify(const char* str) { + return str; + } + } +} + +#endif // LEMON_ASSERT_H + +#undef LEMON_ASSERT +#undef LEMON_DEBUG + +#if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ + (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 +#error "LEMON assertion system is not set properly" +#endif + +#if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ + (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ + defined(LEMON_ENABLE_ASSERTS)) && \ + (defined(LEMON_DISABLE_ASSERTS) || \ + defined(NDEBUG)) +#error "LEMON assertion system is not set properly" +#endif + + +#if defined LEMON_ASSERT_ABORT +# undef LEMON_ASSERT_HANDLER +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort +#elif defined LEMON_ASSERT_CUSTOM +# undef LEMON_ASSERT_HANDLER +# ifndef LEMON_CUSTOM_ASSERT_HANDLER +# error "LEMON_CUSTOM_ASSERT_HANDLER is not set" +# endif +# define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER +#elif defined LEMON_DISABLE_ASSERTS +# undef LEMON_ASSERT_HANDLER +#elif defined NDEBUG +# undef LEMON_ASSERT_HANDLER +#else +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort +#endif + +#ifndef LEMON_FUNCTION_NAME +# if defined __GNUC__ +# define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__) +# elif defined _MSC_VER +# define LEMON_FUNCTION_NAME (__FUNCSIG__) +# elif __STDC_VERSION__ >= 199901L +# define LEMON_FUNCTION_NAME (__func__) +# else +# define LEMON_FUNCTION_NAME ("") +# endif +#endif + +#ifdef DOXYGEN + +/// \ingroup exceptions +/// +/// \brief Macro for assertion with customizable message +/// +/// Macro for assertion with customizable message. +/// \param exp An expression that must be convertible to \c bool. If it is \c +/// false, then an assertion is raised. The concrete behaviour depends on the +/// settings of the assertion system. +/// \param msg A const char* parameter, which can be used to provide +/// information about the circumstances of the failed assertion. +/// +/// The assertions are enabled in the default behaviour. +/// You can disable them with the following code: +/// \code +/// #define LEMON_DISABLE_ASSERTS +/// \endcode +/// or with compilation parameters: +/// \code +/// g++ -DLEMON_DISABLE_ASSERTS +/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS' +/// \endcode +/// The checking is also disabled when the standard macro \c NDEBUG is defined. +/// +/// As a default behaviour the failed assertion prints a short log message to +/// the standard error and aborts the execution. +/// +/// However, the following modes can be used in the assertion system: +/// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to +/// the standard error and aborts the program. It is the default behaviour. +/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler +/// function. +/// \code +/// void custom_assert_handler(const char* file, int line, +/// const char* function, const char* message, +/// const char* assertion); +/// \endcode +/// The name of the function should be defined as the \c +/// LEMON_CUSTOM_ASSERT_HANDLER macro name. +/// \code +/// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler +/// \endcode +/// Whenever an assertion is occured, the custom assertion +/// handler is called with appropiate parameters. +/// +/// The assertion mode can also be changed within one compilation unit. +/// If the macros are redefined with other settings and the +/// \ref lemon/assert.h "assert.h" file is reincluded, then the +/// behaviour is changed appropiately to the new settings. +# define LEMON_ASSERT(exp, msg) \ + (static_cast (!!(exp) ? 0 : ( \ + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ + LEMON_FUNCTION_NAME, \ + ::lemon::_assert_bits::cstringify(msg), #exp), 0))) + +/// \ingroup exceptions +/// +/// \brief Macro for internal assertions +/// +/// Macro for internal assertions, it is used in the library to check +/// the consistency of results of algorithms, several pre- and +/// postconditions and invariants. The checking is disabled by +/// default, but it can be turned on with the macro \c +/// LEMON_ENABLE_DEBUG. +/// \code +/// #define LEMON_ENABLE_DEBUG +/// \endcode +/// or with compilation parameters: +/// \code +/// g++ -DLEMON_ENABLE_DEBUG +/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG' +/// \endcode +/// +/// This macro works like the \c LEMON_ASSERT macro, therefore the +/// current behaviour depends on the settings of \c LEMON_ASSERT +/// macro. +/// +/// \see LEMON_ASSERT +# define LEMON_DEBUG(exp, msg) \ + (static_cast (!!(exp) ? 0 : ( \ + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ + LEMON_FUNCTION_NAME, \ + ::lemon::_assert_bits::cstringify(msg), #exp), 0))) + +#else + +# ifndef LEMON_ASSERT_HANDLER +# define LEMON_ASSERT(exp, msg) (static_cast(0)) +# define LEMON_DEBUG(exp, msg) (static_cast(0)) +# else +# define LEMON_ASSERT(exp, msg) \ + (static_cast (!!(exp) ? 0 : ( \ + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ + LEMON_FUNCTION_NAME, \ + ::lemon::_assert_bits::cstringify(msg), \ + #exp), 0))) +# if LEMON_ENABLE_DEBUG +# define LEMON_DEBUG(exp, msg) \ + (static_cast (!!(exp) ? 0 : ( \ + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ + LEMON_FUNCTION_NAME, \ + ::lemon::_assert_bits::cstringify(msg), \ + #exp), 0))) +# else +# define LEMON_DEBUG(exp, msg) (static_cast(0)) +# endif +# endif + +#endif diff --git a/lemon/lemon/base.cc b/lemon/lemon/base.cc new file mode 100644 index 0000000..80af373 --- /dev/null +++ b/lemon/lemon/base.cc @@ -0,0 +1,34 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Some basic non-inline functions and static global data. + +#include +#include +namespace lemon { + + float Tolerance::def_epsilon = static_cast(1e-4); + double Tolerance::def_epsilon = 1e-10; + long double Tolerance::def_epsilon = 1e-14; + +#ifndef LEMON_ONLY_TEMPLATES + const Invalid INVALID = Invalid(); +#endif + +} //namespace lemon diff --git a/lemon/lemon/bellman_ford.h b/lemon/lemon/bellman_ford.h new file mode 100644 index 0000000..142823b --- /dev/null +++ b/lemon/lemon/bellman_ford.h @@ -0,0 +1,1115 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BELLMAN_FORD_H +#define LEMON_BELLMAN_FORD_H + +/// \ingroup shortest_path +/// \file +/// \brief Bellman-Ford algorithm. + +#include +#include +#include +#include +#include +#include + +#include + +namespace lemon { + + /// \brief Default OperationTraits for the BellmanFord algorithm class. + /// + /// This operation traits class defines all computational operations + /// and constants that are used in the Bellman-Ford algorithm. + /// The default implementation is based on the \c numeric_limits class. + /// If the numeric type does not have infinity value, then the maximum + /// value is used as extremal infinity value. + template < + typename V, + bool has_inf = std::numeric_limits::has_infinity> + struct BellmanFordDefaultOperationTraits { + /// \e + typedef V Value; + /// \brief Gives back the zero value of the type. + static Value zero() { + return static_cast(0); + } + /// \brief Gives back the positive infinity value of the type. + static Value infinity() { + return std::numeric_limits::infinity(); + } + /// \brief Gives back the sum of the given two elements. + static Value plus(const Value& left, const Value& right) { + return left + right; + } + /// \brief Gives back \c true only if the first value is less than + /// the second. + static bool less(const Value& left, const Value& right) { + return left < right; + } + }; + + template + struct BellmanFordDefaultOperationTraits { + typedef V Value; + static Value zero() { + return static_cast(0); + } + static Value infinity() { + return std::numeric_limits::max(); + } + static Value plus(const Value& left, const Value& right) { + if (left == infinity() || right == infinity()) return infinity(); + return left + right; + } + static bool less(const Value& left, const Value& right) { + return left < right; + } + }; + + /// \brief Default traits class of BellmanFord class. + /// + /// Default traits class of BellmanFord class. + /// \param GR The type of the digraph. + /// \param LEN The type of the length map. + template + struct BellmanFordDefaultTraits { + /// The type of the digraph the algorithm runs on. + typedef GR Digraph; + + /// \brief The type of the map that stores the arc lengths. + /// + /// The type of the map that stores the arc lengths. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. + typedef LEN LengthMap; + + /// The type of the arc lengths. + typedef typename LEN::Value Value; + + /// \brief Operation traits for Bellman-Ford algorithm. + /// + /// It defines the used operations and the infinity value for the + /// given \c Value type. + /// \see BellmanFordDefaultOperationTraits + typedef BellmanFordDefaultOperationTraits OperationTraits; + + /// \brief The type of the map that stores the last arcs of the + /// shortest paths. + /// + /// The type of the map that stores the last + /// arcs of the shortest paths. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename GR::template NodeMap PredMap; + + /// \brief Instantiates a \c PredMap. + /// + /// This function instantiates a \ref PredMap. + /// \param g is the digraph to which we would like to define the + /// \ref PredMap. + static PredMap *createPredMap(const GR& g) { + return new PredMap(g); + } + + /// \brief The type of the map that stores the distances of the nodes. + /// + /// The type of the map that stores the distances of the nodes. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename GR::template NodeMap DistMap; + + /// \brief Instantiates a \c DistMap. + /// + /// This function instantiates a \ref DistMap. + /// \param g is the digraph to which we would like to define the + /// \ref DistMap. + static DistMap *createDistMap(const GR& g) { + return new DistMap(g); + } + + }; + + /// \brief %BellmanFord algorithm class. + /// + /// \ingroup shortest_path + /// This class provides an efficient implementation of the Bellman-Ford + /// algorithm. The maximum time complexity of the algorithm is + /// O(ne). + /// + /// The Bellman-Ford algorithm solves the single-source shortest path + /// problem when the arcs can have negative lengths, but the digraph + /// should not contain directed cycles with negative total length. + /// If all arc costs are non-negative, consider to use the Dijkstra + /// algorithm instead, since it is more efficient. + /// + /// The arc lengths are passed to the algorithm using a + /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any + /// kind of length. The type of the length values is determined by the + /// \ref concepts::ReadMap::Value "Value" type of the length map. + /// + /// There is also a \ref bellmanFord() "function-type interface" for the + /// Bellman-Ford algorithm, which is convenient in the simplier cases and + /// it can be used easier. + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// The default type is \ref ListDigraph. + /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies + /// the lengths of the arcs. The default map type is + /// \ref concepts::Digraph::ArcMap "GR::ArcMap". + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref BellmanFordDefaultTraits + /// "BellmanFordDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template , + typename TR=BellmanFordDefaultTraits > +#endif + class BellmanFord { + public: + + ///The type of the underlying digraph. + typedef typename TR::Digraph Digraph; + + /// \brief The type of the arc lengths. + typedef typename TR::LengthMap::Value Value; + /// \brief The type of the map that stores the arc lengths. + typedef typename TR::LengthMap LengthMap; + /// \brief The type of the map that stores the last + /// arcs of the shortest paths. + typedef typename TR::PredMap PredMap; + /// \brief The type of the map that stores the distances of the nodes. + typedef typename TR::DistMap DistMap; + /// The type of the paths. + typedef PredMapPath Path; + ///\brief The \ref BellmanFordDefaultOperationTraits + /// "operation traits class" of the algorithm. + typedef typename TR::OperationTraits OperationTraits; + + ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm. + typedef TR Traits; + + private: + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + // Pointer to the underlying digraph. + const Digraph *_gr; + // Pointer to the length map + const LengthMap *_length; + // Pointer to the map of predecessors arcs. + PredMap *_pred; + // Indicates if _pred is locally allocated (true) or not. + bool _local_pred; + // Pointer to the map of distances. + DistMap *_dist; + // Indicates if _dist is locally allocated (true) or not. + bool _local_dist; + + typedef typename Digraph::template NodeMap MaskMap; + MaskMap *_mask; + + std::vector _process; + + // Creates the maps if necessary. + void create_maps() { + if(!_pred) { + _local_pred = true; + _pred = Traits::createPredMap(*_gr); + } + if(!_dist) { + _local_dist = true; + _dist = Traits::createDistMap(*_gr); + } + if(!_mask) { + _mask = new MaskMap(*_gr); + } + } + + public : + + typedef BellmanFord Create; + + /// \name Named Template Parameters + + ///@{ + + template + struct SetPredMapTraits : public Traits { + typedef T PredMap; + static PredMap *createPredMap(const Digraph&) { + LEMON_ASSERT(false, "PredMap is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c PredMap type. + /// + /// \ref named-templ-param "Named parameter" for setting + /// \c PredMap type. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetPredMap + : public BellmanFord< Digraph, LengthMap, SetPredMapTraits > { + typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits > Create; + }; + + template + struct SetDistMapTraits : public Traits { + typedef T DistMap; + static DistMap *createDistMap(const Digraph&) { + LEMON_ASSERT(false, "DistMap is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c DistMap type. + /// + /// \ref named-templ-param "Named parameter" for setting + /// \c DistMap type. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetDistMap + : public BellmanFord< Digraph, LengthMap, SetDistMapTraits > { + typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits > Create; + }; + + template + struct SetOperationTraitsTraits : public Traits { + typedef T OperationTraits; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c OperationTraits type. + /// + /// \ref named-templ-param "Named parameter" for setting + /// \c OperationTraits type. + /// For more information, see \ref BellmanFordDefaultOperationTraits. + template + struct SetOperationTraits + : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits > { + typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits > + Create; + }; + + ///@} + + protected: + + BellmanFord() {} + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// \param g The digraph the algorithm runs on. + /// \param length The length map used by the algorithm. + BellmanFord(const Digraph& g, const LengthMap& length) : + _gr(&g), _length(&length), + _pred(0), _local_pred(false), + _dist(0), _local_dist(false), _mask(0) {} + + ///Destructor. + ~BellmanFord() { + if(_local_pred) delete _pred; + if(_local_dist) delete _dist; + if(_mask) delete _mask; + } + + /// \brief Sets the length map. + /// + /// Sets the length map. + /// \return (*this) + BellmanFord &lengthMap(const LengthMap &map) { + _length = ↦ + return *this; + } + + /// \brief Sets the map that stores the predecessor arcs. + /// + /// Sets the map that stores the predecessor arcs. + /// If you don't use this function before calling \ref run() + /// or \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated map, + /// of course. + /// \return (*this) + BellmanFord &predMap(PredMap &map) { + if(_local_pred) { + delete _pred; + _local_pred=false; + } + _pred = ↦ + return *this; + } + + /// \brief Sets the map that stores the distances of the nodes. + /// + /// Sets the map that stores the distances of the nodes calculated + /// by the algorithm. + /// If you don't use this function before calling \ref run() + /// or \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated map, + /// of course. + /// \return (*this) + BellmanFord &distMap(DistMap &map) { + if(_local_dist) { + delete _dist; + _local_dist=false; + } + _dist = ↦ + return *this; + } + + /// \name Execution Control + /// The simplest way to execute the Bellman-Ford algorithm is to use + /// one of the member functions called \ref run().\n + /// If you need better control on the execution, you have to call + /// \ref init() first, then you can add several source nodes + /// with \ref addSource(). Finally the actual path computation can be + /// performed with \ref start(), \ref checkedStart() or + /// \ref limitedStart(). + + ///@{ + + /// \brief Initializes the internal data structures. + /// + /// Initializes the internal data structures. The optional parameter + /// is the initial distance of each node. + void init(const Value value = OperationTraits::infinity()) { + create_maps(); + for (NodeIt it(*_gr); it != INVALID; ++it) { + _pred->set(it, INVALID); + _dist->set(it, value); + } + _process.clear(); + if (OperationTraits::less(value, OperationTraits::infinity())) { + for (NodeIt it(*_gr); it != INVALID; ++it) { + _process.push_back(it); + _mask->set(it, true); + } + } else { + for (NodeIt it(*_gr); it != INVALID; ++it) { + _mask->set(it, false); + } + } + } + + /// \brief Adds a new source node. + /// + /// This function adds a new source node. The optional second parameter + /// is the initial distance of the node. + void addSource(Node source, Value dst = OperationTraits::zero()) { + _dist->set(source, dst); + if (!(*_mask)[source]) { + _process.push_back(source); + _mask->set(source, true); + } + } + + /// \brief Executes one round from the Bellman-Ford algorithm. + /// + /// If the algoritm calculated the distances in the previous round + /// exactly for the paths of at most \c k arcs, then this function + /// will calculate the distances exactly for the paths of at most + /// k+1 arcs. Performing \c k iterations using this function + /// calculates the shortest path distances exactly for the paths + /// consisting of at most \c k arcs. + /// + /// \warning The paths with limited arc number cannot be retrieved + /// easily with \ref path() or \ref predArc() functions. If you also + /// need the shortest paths and not only the distances, you should + /// store the \ref predMap() "predecessor map" after each iteration + /// and build the path manually. + /// + /// \return \c true when the algorithm have not found more shorter + /// paths. + /// + /// \see ActiveIt + bool processNextRound() { + for (int i = 0; i < int(_process.size()); ++i) { + _mask->set(_process[i], false); + } + std::vector nextProcess; + std::vector values(_process.size()); + for (int i = 0; i < int(_process.size()); ++i) { + values[i] = (*_dist)[_process[i]]; + } + for (int i = 0; i < int(_process.size()); ++i) { + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) { + Node target = _gr->target(it); + Value relaxed = OperationTraits::plus(values[i], (*_length)[it]); + if (OperationTraits::less(relaxed, (*_dist)[target])) { + _pred->set(target, it); + _dist->set(target, relaxed); + if (!(*_mask)[target]) { + _mask->set(target, true); + nextProcess.push_back(target); + } + } + } + } + _process.swap(nextProcess); + return _process.empty(); + } + + /// \brief Executes one weak round from the Bellman-Ford algorithm. + /// + /// If the algorithm calculated the distances in the previous round + /// at least for the paths of at most \c k arcs, then this function + /// will calculate the distances at least for the paths of at most + /// k+1 arcs. + /// This function does not make it possible to calculate the shortest + /// path distances exactly for paths consisting of at most \c k arcs, + /// this is why it is called weak round. + /// + /// \return \c true when the algorithm have not found more shorter + /// paths. + /// + /// \see ActiveIt + bool processNextWeakRound() { + for (int i = 0; i < int(_process.size()); ++i) { + _mask->set(_process[i], false); + } + std::vector nextProcess; + for (int i = 0; i < int(_process.size()); ++i) { + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) { + Node target = _gr->target(it); + Value relaxed = + OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]); + if (OperationTraits::less(relaxed, (*_dist)[target])) { + _pred->set(target, it); + _dist->set(target, relaxed); + if (!(*_mask)[target]) { + _mask->set(target, true); + nextProcess.push_back(target); + } + } + } + } + _process.swap(nextProcess); + return _process.empty(); + } + + /// \brief Executes the algorithm. + /// + /// Executes the algorithm. + /// + /// This method runs the Bellman-Ford algorithm from the root node(s) + /// in order to compute the shortest path to each node. + /// + /// The algorithm computes + /// - the shortest path tree (forest), + /// - the distance of each node from the root(s). + /// + /// \pre init() must be called and at least one root node should be + /// added with addSource() before using this function. + void start() { + int num = countNodes(*_gr) - 1; + for (int i = 0; i < num; ++i) { + if (processNextWeakRound()) break; + } + } + + /// \brief Executes the algorithm and checks the negative cycles. + /// + /// Executes the algorithm and checks the negative cycles. + /// + /// This method runs the Bellman-Ford algorithm from the root node(s) + /// in order to compute the shortest path to each node and also checks + /// if the digraph contains cycles with negative total length. + /// + /// The algorithm computes + /// - the shortest path tree (forest), + /// - the distance of each node from the root(s). + /// + /// \return \c false if there is a negative cycle in the digraph. + /// + /// \pre init() must be called and at least one root node should be + /// added with addSource() before using this function. + bool checkedStart() { + int num = countNodes(*_gr); + for (int i = 0; i < num; ++i) { + if (processNextWeakRound()) return true; + } + return _process.empty(); + } + + /// \brief Executes the algorithm with arc number limit. + /// + /// Executes the algorithm with arc number limit. + /// + /// This method runs the Bellman-Ford algorithm from the root node(s) + /// in order to compute the shortest path distance for each node + /// using only the paths consisting of at most \c num arcs. + /// + /// The algorithm computes + /// - the limited distance of each node from the root(s), + /// - the predecessor arc for each node. + /// + /// \warning The paths with limited arc number cannot be retrieved + /// easily with \ref path() or \ref predArc() functions. If you also + /// need the shortest paths and not only the distances, you should + /// store the \ref predMap() "predecessor map" after each iteration + /// and build the path manually. + /// + /// \pre init() must be called and at least one root node should be + /// added with addSource() before using this function. + void limitedStart(int num) { + for (int i = 0; i < num; ++i) { + if (processNextRound()) break; + } + } + + /// \brief Runs the algorithm from the given root node. + /// + /// This method runs the Bellman-Ford algorithm from the given root + /// node \c s in order to compute the shortest path to each node. + /// + /// The algorithm computes + /// - the shortest path tree (forest), + /// - the distance of each node from the root(s). + /// + /// \note bf.run(s) is just a shortcut of the following code. + /// \code + /// bf.init(); + /// bf.addSource(s); + /// bf.start(); + /// \endcode + void run(Node s) { + init(); + addSource(s); + start(); + } + + /// \brief Runs the algorithm from the given root node with arc + /// number limit. + /// + /// This method runs the Bellman-Ford algorithm from the given root + /// node \c s in order to compute the shortest path distance for each + /// node using only the paths consisting of at most \c num arcs. + /// + /// The algorithm computes + /// - the limited distance of each node from the root(s), + /// - the predecessor arc for each node. + /// + /// \warning The paths with limited arc number cannot be retrieved + /// easily with \ref path() or \ref predArc() functions. If you also + /// need the shortest paths and not only the distances, you should + /// store the \ref predMap() "predecessor map" after each iteration + /// and build the path manually. + /// + /// \note bf.run(s, num) is just a shortcut of the following code. + /// \code + /// bf.init(); + /// bf.addSource(s); + /// bf.limitedStart(num); + /// \endcode + void run(Node s, int num) { + init(); + addSource(s); + limitedStart(num); + } + + ///@} + + /// \brief LEMON iterator for getting the active nodes. + /// + /// This class provides a common style LEMON iterator that traverses + /// the active nodes of the Bellman-Ford algorithm after the last + /// phase. These nodes should be checked in the next phase to + /// find augmenting arcs outgoing from them. + class ActiveIt { + public: + + /// \brief Constructor. + /// + /// Constructor for getting the active nodes of the given BellmanFord + /// instance. + ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm) + { + _index = _algorithm->_process.size() - 1; + } + + /// \brief Invalid constructor. + /// + /// Invalid constructor. + ActiveIt(Invalid) : _algorithm(0), _index(-1) {} + + /// \brief Conversion to \c Node. + /// + /// Conversion to \c Node. + operator Node() const { + return _index >= 0 ? _algorithm->_process[_index] : INVALID; + } + + /// \brief Increment operator. + /// + /// Increment operator. + ActiveIt& operator++() { + --_index; + return *this; + } + + bool operator==(const ActiveIt& it) const { + return static_cast(*this) == static_cast(it); + } + bool operator!=(const ActiveIt& it) const { + return static_cast(*this) != static_cast(it); + } + bool operator<(const ActiveIt& it) const { + return static_cast(*this) < static_cast(it); + } + + private: + const BellmanFord* _algorithm; + int _index; + }; + + /// \name Query Functions + /// The result of the Bellman-Ford algorithm can be obtained using these + /// functions.\n + /// Either \ref run() or \ref init() should be called before using them. + + ///@{ + + /// \brief The shortest path to the given node. + /// + /// Gives back the shortest path to the given node from the root(s). + /// + /// \warning \c t should be reached from the root(s). + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + Path path(Node t) const + { + return Path(*_gr, *_pred, t); + } + + /// \brief The distance of the given node from the root(s). + /// + /// Returns the distance of the given node from the root(s). + /// + /// \warning If node \c v is not reached from the root(s), then + /// the return value of this function is undefined. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + Value dist(Node v) const { return (*_dist)[v]; } + + /// \brief Returns the 'previous arc' of the shortest path tree for + /// the given node. + /// + /// This function returns the 'previous arc' of the shortest path + /// tree for node \c v, i.e. it returns the last arc of a + /// shortest path from a root to \c v. It is \c INVALID if \c v + /// is not reached from the root(s) or if \c v is a root. + /// + /// The shortest path tree used here is equal to the shortest path + /// tree used in \ref predNode() and \ref predMap(). + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + Arc predArc(Node v) const { return (*_pred)[v]; } + + /// \brief Returns the 'previous node' of the shortest path tree for + /// the given node. + /// + /// This function returns the 'previous node' of the shortest path + /// tree for node \c v, i.e. it returns the last but one node of + /// a shortest path from a root to \c v. It is \c INVALID if \c v + /// is not reached from the root(s) or if \c v is a root. + /// + /// The shortest path tree used here is equal to the shortest path + /// tree used in \ref predArc() and \ref predMap(). + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + Node predNode(Node v) const { + return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]); + } + + /// \brief Returns a const reference to the node map that stores the + /// distances of the nodes. + /// + /// Returns a const reference to the node map that stores the distances + /// of the nodes calculated by the algorithm. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const DistMap &distMap() const { return *_dist;} + + /// \brief Returns a const reference to the node map that stores the + /// predecessor arcs. + /// + /// Returns a const reference to the node map that stores the predecessor + /// arcs, which form the shortest path tree (forest). + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const PredMap &predMap() const { return *_pred; } + + /// \brief Checks if a node is reached from the root(s). + /// + /// Returns \c true if \c v is reached from the root(s). + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + bool reached(Node v) const { + return (*_dist)[v] != OperationTraits::infinity(); + } + + /// \brief Gives back a negative cycle. + /// + /// This function gives back a directed cycle with negative total + /// length if the algorithm has already found one. + /// Otherwise it gives back an empty path. + lemon::Path negativeCycle() const { + typename Digraph::template NodeMap state(*_gr, -1); + lemon::Path cycle; + for (int i = 0; i < int(_process.size()); ++i) { + if (state[_process[i]] != -1) continue; + for (Node v = _process[i]; (*_pred)[v] != INVALID; + v = _gr->source((*_pred)[v])) { + if (state[v] == i) { + cycle.addFront((*_pred)[v]); + for (Node u = _gr->source((*_pred)[v]); u != v; + u = _gr->source((*_pred)[u])) { + cycle.addFront((*_pred)[u]); + } + return cycle; + } + else if (state[v] >= 0) { + break; + } + state[v] = i; + } + } + return cycle; + } + + ///@} + }; + + /// \brief Default traits class of bellmanFord() function. + /// + /// Default traits class of bellmanFord() function. + /// \tparam GR The type of the digraph. + /// \tparam LEN The type of the length map. + template + struct BellmanFordWizardDefaultTraits { + /// The type of the digraph the algorithm runs on. + typedef GR Digraph; + + /// \brief The type of the map that stores the arc lengths. + /// + /// The type of the map that stores the arc lengths. + /// It must meet the \ref concepts::ReadMap "ReadMap" concept. + typedef LEN LengthMap; + + /// The type of the arc lengths. + typedef typename LEN::Value Value; + + /// \brief Operation traits for Bellman-Ford algorithm. + /// + /// It defines the used operations and the infinity value for the + /// given \c Value type. + /// \see BellmanFordDefaultOperationTraits + typedef BellmanFordDefaultOperationTraits OperationTraits; + + /// \brief The type of the map that stores the last + /// arcs of the shortest paths. + /// + /// The type of the map that stores the last arcs of the shortest paths. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename GR::template NodeMap PredMap; + + /// \brief Instantiates a \c PredMap. + /// + /// This function instantiates a \ref PredMap. + /// \param g is the digraph to which we would like to define the + /// \ref PredMap. + static PredMap *createPredMap(const GR &g) { + return new PredMap(g); + } + + /// \brief The type of the map that stores the distances of the nodes. + /// + /// The type of the map that stores the distances of the nodes. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename GR::template NodeMap DistMap; + + /// \brief Instantiates a \c DistMap. + /// + /// This function instantiates a \ref DistMap. + /// \param g is the digraph to which we would like to define the + /// \ref DistMap. + static DistMap *createDistMap(const GR &g) { + return new DistMap(g); + } + + ///The type of the shortest paths. + + ///The type of the shortest paths. + ///It must meet the \ref concepts::Path "Path" concept. + typedef lemon::Path Path; + }; + + /// \brief Default traits class used by BellmanFordWizard. + /// + /// Default traits class used by BellmanFordWizard. + /// \tparam GR The type of the digraph. + /// \tparam LEN The type of the length map. + template + class BellmanFordWizardBase + : public BellmanFordWizardDefaultTraits { + + typedef BellmanFordWizardDefaultTraits Base; + protected: + // Type of the nodes in the digraph. + typedef typename Base::Digraph::Node Node; + + // Pointer to the underlying digraph. + void *_graph; + // Pointer to the length map + void *_length; + // Pointer to the map of predecessors arcs. + void *_pred; + // Pointer to the map of distances. + void *_dist; + //Pointer to the shortest path to the target node. + void *_path; + //Pointer to the distance of the target node. + void *_di; + + public: + /// Constructor. + + /// This constructor does not require parameters, it initiates + /// all of the attributes to default values \c 0. + BellmanFordWizardBase() : + _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {} + + /// Constructor. + + /// This constructor requires two parameters, + /// others are initiated to \c 0. + /// \param gr The digraph the algorithm runs on. + /// \param len The length map. + BellmanFordWizardBase(const GR& gr, + const LEN& len) : + _graph(reinterpret_cast(const_cast(&gr))), + _length(reinterpret_cast(const_cast(&len))), + _pred(0), _dist(0), _path(0), _di(0) {} + + }; + + /// \brief Auxiliary class for the function-type interface of the + /// \ref BellmanFord "Bellman-Ford" algorithm. + /// + /// This auxiliary class is created to implement the + /// \ref bellmanFord() "function-type interface" of the + /// \ref BellmanFord "Bellman-Ford" algorithm. + /// It does not have own \ref run() method, it uses the + /// functions and features of the plain \ref BellmanFord. + /// + /// This class should only be used through the \ref bellmanFord() + /// function, which makes it easier to use the algorithm. + /// + /// \tparam TR The traits class that defines various types used by the + /// algorithm. + template + class BellmanFordWizard : public TR { + typedef TR Base; + + typedef typename TR::Digraph Digraph; + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt ArcIt; + + typedef typename TR::LengthMap LengthMap; + typedef typename LengthMap::Value Value; + typedef typename TR::PredMap PredMap; + typedef typename TR::DistMap DistMap; + typedef typename TR::Path Path; + + public: + /// Constructor. + BellmanFordWizard() : TR() {} + + /// \brief Constructor that requires parameters. + /// + /// Constructor that requires parameters. + /// These parameters will be the default values for the traits class. + /// \param gr The digraph the algorithm runs on. + /// \param len The length map. + BellmanFordWizard(const Digraph& gr, const LengthMap& len) + : TR(gr, len) {} + + /// \brief Copy constructor + BellmanFordWizard(const TR &b) : TR(b) {} + + ~BellmanFordWizard() {} + + /// \brief Runs the Bellman-Ford algorithm from the given source node. + /// + /// This method runs the Bellman-Ford algorithm from the given source + /// node in order to compute the shortest path to each node. + void run(Node s) { + BellmanFord + bf(*reinterpret_cast(Base::_graph), + *reinterpret_cast(Base::_length)); + if (Base::_pred) bf.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) bf.distMap(*reinterpret_cast(Base::_dist)); + bf.run(s); + } + + /// \brief Runs the Bellman-Ford algorithm to find the shortest path + /// between \c s and \c t. + /// + /// This method runs the Bellman-Ford algorithm from node \c s + /// in order to compute the shortest path to node \c t. + /// Actually, it computes the shortest path to each node, but using + /// this function you can retrieve the distance and the shortest path + /// for a single target node easier. + /// + /// \return \c true if \c t is reachable form \c s. + bool run(Node s, Node t) { + BellmanFord + bf(*reinterpret_cast(Base::_graph), + *reinterpret_cast(Base::_length)); + if (Base::_pred) bf.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) bf.distMap(*reinterpret_cast(Base::_dist)); + bf.run(s); + if (Base::_path) *reinterpret_cast(Base::_path) = bf.path(t); + if (Base::_di) *reinterpret_cast(Base::_di) = bf.dist(t); + return bf.reached(t); + } + + template + struct SetPredMapBase : public Base { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) { return 0; }; + SetPredMapBase(const TR &b) : TR(b) {} + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// the predecessor map. + /// + /// \ref named-templ-param "Named parameter" for setting + /// the map that stores the predecessor arcs of the nodes. + template + BellmanFordWizard > predMap(const T &t) { + Base::_pred=reinterpret_cast(const_cast(&t)); + return BellmanFordWizard >(*this); + } + + template + struct SetDistMapBase : public Base { + typedef T DistMap; + static DistMap *createDistMap(const Digraph &) { return 0; }; + SetDistMapBase(const TR &b) : TR(b) {} + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// the distance map. + /// + /// \ref named-templ-param "Named parameter" for setting + /// the map that stores the distances of the nodes calculated + /// by the algorithm. + template + BellmanFordWizard > distMap(const T &t) { + Base::_dist=reinterpret_cast(const_cast(&t)); + return BellmanFordWizard >(*this); + } + + template + struct SetPathBase : public Base { + typedef T Path; + SetPathBase(const TR &b) : TR(b) {} + }; + + /// \brief \ref named-func-param "Named parameter" for getting + /// the shortest path to the target node. + /// + /// \ref named-func-param "Named parameter" for getting + /// the shortest path to the target node. + template + BellmanFordWizard > path(const T &t) + { + Base::_path=reinterpret_cast(const_cast(&t)); + return BellmanFordWizard >(*this); + } + + /// \brief \ref named-func-param "Named parameter" for getting + /// the distance of the target node. + /// + /// \ref named-func-param "Named parameter" for getting + /// the distance of the target node. + BellmanFordWizard dist(const Value &d) + { + Base::_di=reinterpret_cast(const_cast(&d)); + return *this; + } + + }; + + /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford" + /// algorithm. + /// + /// \ingroup shortest_path + /// Function type interface for the \ref BellmanFord "Bellman-Ford" + /// algorithm. + /// + /// This function also has several \ref named-templ-func-param + /// "named parameters", they are declared as the members of class + /// \ref BellmanFordWizard. + /// The following examples show how to use these parameters. + /// \code + /// // Compute shortest path from node s to each node + /// bellmanFord(g,length).predMap(preds).distMap(dists).run(s); + /// + /// // Compute shortest path from s to t + /// bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t); + /// \endcode + /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()" + /// to the end of the parameter list. + /// \sa BellmanFordWizard + /// \sa BellmanFord + template + BellmanFordWizard > + bellmanFord(const GR& digraph, + const LEN& length) + { + return BellmanFordWizard >(digraph, length); + } + +} //END OF NAMESPACE LEMON + +#endif + diff --git a/lemon/lemon/bfs.h b/lemon/lemon/bfs.h new file mode 100644 index 0000000..12276b7 --- /dev/null +++ b/lemon/lemon/bfs.h @@ -0,0 +1,1753 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BFS_H +#define LEMON_BFS_H + +///\ingroup search +///\file +///\brief BFS algorithm. + +#include +#include +#include +#include +#include +#include + +namespace lemon { + + ///Default traits class of Bfs class. + + ///Default traits class of Bfs class. + ///\tparam GR Digraph type. + template + struct BfsDefaultTraits + { + ///The type of the digraph the algorithm runs on. + typedef GR Digraph; + + ///\brief The type of the map that stores the predecessor + ///arcs of the shortest paths. + /// + ///The type of the map that stores the predecessor + ///arcs of the shortest paths. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap PredMap; + ///Instantiates a \c PredMap. + + ///This function instantiates a \ref PredMap. + ///\param g is the digraph, to which we would like to define the + ///\ref PredMap. + static PredMap *createPredMap(const Digraph &g) + { + return new PredMap(g); + } + + ///The type of the map that indicates which nodes are processed. + + ///The type of the map that indicates which nodes are processed. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + ///By default, it is a NullMap. + typedef NullMap ProcessedMap; + ///Instantiates a \c ProcessedMap. + + ///This function instantiates a \ref ProcessedMap. + ///\param g is the digraph, to which + ///we would like to define the \ref ProcessedMap +#ifdef DOXYGEN + static ProcessedMap *createProcessedMap(const Digraph &g) +#else + static ProcessedMap *createProcessedMap(const Digraph &) +#endif + { + return new ProcessedMap(); + } + + ///The type of the map that indicates which nodes are reached. + + ///The type of the map that indicates which nodes are reached. + ///It must conform to + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + typedef typename Digraph::template NodeMap ReachedMap; + ///Instantiates a \c ReachedMap. + + ///This function instantiates a \ref ReachedMap. + ///\param g is the digraph, to which + ///we would like to define the \ref ReachedMap. + static ReachedMap *createReachedMap(const Digraph &g) + { + return new ReachedMap(g); + } + + ///The type of the map that stores the distances of the nodes. + + ///The type of the map that stores the distances of the nodes. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap DistMap; + ///Instantiates a \c DistMap. + + ///This function instantiates a \ref DistMap. + ///\param g is the digraph, to which we would like to define the + ///\ref DistMap. + static DistMap *createDistMap(const Digraph &g) + { + return new DistMap(g); + } + }; + + ///%BFS algorithm class. + + ///\ingroup search + ///This class provides an efficient implementation of the %BFS algorithm. + /// + ///There is also a \ref bfs() "function-type interface" for the BFS + ///algorithm, which is convenient in the simplier cases and it can be + ///used easier. + /// + ///\tparam GR The type of the digraph the algorithm runs on. + ///The default type is \ref ListDigraph. + ///\tparam TR The traits class that defines various types used by the + ///algorithm. By default, it is \ref BfsDefaultTraits + ///"BfsDefaultTraits". + ///In most cases, this parameter should not be set directly, + ///consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template > +#endif + class Bfs { + public: + + ///The type of the digraph the algorithm runs on. + typedef typename TR::Digraph Digraph; + + ///\brief The type of the map that stores the predecessor arcs of the + ///shortest paths. + typedef typename TR::PredMap PredMap; + ///The type of the map that stores the distances of the nodes. + typedef typename TR::DistMap DistMap; + ///The type of the map that indicates which nodes are reached. + typedef typename TR::ReachedMap ReachedMap; + ///The type of the map that indicates which nodes are processed. + typedef typename TR::ProcessedMap ProcessedMap; + ///The type of the paths. + typedef PredMapPath Path; + + ///The \ref BfsDefaultTraits "traits class" of the algorithm. + typedef TR Traits; + + private: + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + //Pointer to the underlying digraph. + const Digraph *G; + //Pointer to the map of predecessor arcs. + PredMap *_pred; + //Indicates if _pred is locally allocated (true) or not. + bool local_pred; + //Pointer to the map of distances. + DistMap *_dist; + //Indicates if _dist is locally allocated (true) or not. + bool local_dist; + //Pointer to the map of reached status of the nodes. + ReachedMap *_reached; + //Indicates if _reached is locally allocated (true) or not. + bool local_reached; + //Pointer to the map of processed status of the nodes. + ProcessedMap *_processed; + //Indicates if _processed is locally allocated (true) or not. + bool local_processed; + + std::vector _queue; + int _queue_head,_queue_tail,_queue_next_dist; + int _curr_dist; + + //Creates the maps if necessary. + void create_maps() + { + if(!_pred) { + local_pred = true; + _pred = Traits::createPredMap(*G); + } + if(!_dist) { + local_dist = true; + _dist = Traits::createDistMap(*G); + } + if(!_reached) { + local_reached = true; + _reached = Traits::createReachedMap(*G); + } + if(!_processed) { + local_processed = true; + _processed = Traits::createProcessedMap(*G); + } + } + + protected: + + Bfs() {} + + public: + + typedef Bfs Create; + + ///\name Named Template Parameters + + ///@{ + + template + struct SetPredMapTraits : public Traits { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) + { + LEMON_ASSERT(false, "PredMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c PredMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c PredMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetPredMap : public Bfs< Digraph, SetPredMapTraits > { + typedef Bfs< Digraph, SetPredMapTraits > Create; + }; + + template + struct SetDistMapTraits : public Traits { + typedef T DistMap; + static DistMap *createDistMap(const Digraph &) + { + LEMON_ASSERT(false, "DistMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c DistMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c DistMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetDistMap : public Bfs< Digraph, SetDistMapTraits > { + typedef Bfs< Digraph, SetDistMapTraits > Create; + }; + + template + struct SetReachedMapTraits : public Traits { + typedef T ReachedMap; + static ReachedMap *createReachedMap(const Digraph &) + { + LEMON_ASSERT(false, "ReachedMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ReachedMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ReachedMap type. + ///It must conform to + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + template + struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits > { + typedef Bfs< Digraph, SetReachedMapTraits > Create; + }; + + template + struct SetProcessedMapTraits : public Traits { + typedef T ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &) + { + LEMON_ASSERT(false, "ProcessedMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits > { + typedef Bfs< Digraph, SetProcessedMapTraits > Create; + }; + + struct SetStandardProcessedMapTraits : public Traits { + typedef typename Digraph::template NodeMap ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &g) + { + return new ProcessedMap(g); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type to be Digraph::NodeMap. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type to be Digraph::NodeMap. + ///If you don't set it explicitly, it will be automatically allocated. + struct SetStandardProcessedMap : + public Bfs< Digraph, SetStandardProcessedMapTraits > { + typedef Bfs< Digraph, SetStandardProcessedMapTraits > Create; + }; + + ///@} + + public: + + ///Constructor. + + ///Constructor. + ///\param g The digraph the algorithm runs on. + Bfs(const Digraph &g) : + G(&g), + _pred(NULL), local_pred(false), + _dist(NULL), local_dist(false), + _reached(NULL), local_reached(false), + _processed(NULL), local_processed(false) + { } + + ///Destructor. + ~Bfs() + { + if(local_pred) delete _pred; + if(local_dist) delete _dist; + if(local_reached) delete _reached; + if(local_processed) delete _processed; + } + + ///Sets the map that stores the predecessor arcs. + + ///Sets the map that stores the predecessor arcs. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Bfs &predMap(PredMap &m) + { + if(local_pred) { + delete _pred; + local_pred=false; + } + _pred = &m; + return *this; + } + + ///Sets the map that indicates which nodes are reached. + + ///Sets the map that indicates which nodes are reached. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Bfs &reachedMap(ReachedMap &m) + { + if(local_reached) { + delete _reached; + local_reached=false; + } + _reached = &m; + return *this; + } + + ///Sets the map that indicates which nodes are processed. + + ///Sets the map that indicates which nodes are processed. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Bfs &processedMap(ProcessedMap &m) + { + if(local_processed) { + delete _processed; + local_processed=false; + } + _processed = &m; + return *this; + } + + ///Sets the map that stores the distances of the nodes. + + ///Sets the map that stores the distances of the nodes calculated by + ///the algorithm. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Bfs &distMap(DistMap &m) + { + if(local_dist) { + delete _dist; + local_dist=false; + } + _dist = &m; + return *this; + } + + public: + + ///\name Execution Control + ///The simplest way to execute the BFS algorithm is to use one of the + ///member functions called \ref run(Node) "run()".\n + ///If you need better control on the execution, you have to call + ///\ref init() first, then you can add several source nodes with + ///\ref addSource(). Finally the actual path computation can be + ///performed with one of the \ref start() functions. + + ///@{ + + ///\brief Initializes the internal data structures. + /// + ///Initializes the internal data structures. + void init() + { + create_maps(); + _queue.resize(countNodes(*G)); + _queue_head=_queue_tail=0; + _curr_dist=1; + for ( NodeIt u(*G) ; u!=INVALID ; ++u ) { + _pred->set(u,INVALID); + _reached->set(u,false); + _processed->set(u,false); + } + } + + ///Adds a new source node. + + ///Adds a new source node to the set of nodes to be processed. + /// + void addSource(Node s) + { + if(!(*_reached)[s]) + { + _reached->set(s,true); + _pred->set(s,INVALID); + _dist->set(s,0); + _queue[_queue_head++]=s; + _queue_next_dist=_queue_head; + } + } + + ///Processes the next node. + + ///Processes the next node. + /// + ///\return The processed node. + /// + ///\pre The queue must not be empty. + Node processNextNode() + { + if(_queue_tail==_queue_next_dist) { + _curr_dist++; + _queue_next_dist=_queue_head; + } + Node n=_queue[_queue_tail++]; + _processed->set(n,true); + Node m; + for(OutArcIt e(*G,n);e!=INVALID;++e) + if(!(*_reached)[m=G->target(e)]) { + _queue[_queue_head++]=m; + _reached->set(m,true); + _pred->set(m,e); + _dist->set(m,_curr_dist); + } + return n; + } + + ///Processes the next node. + + ///Processes the next node and checks if the given target node + ///is reached. If the target node is reachable from the processed + ///node, then the \c reach parameter will be set to \c true. + /// + ///\param target The target node. + ///\retval reach Indicates if the target node is reached. + ///It should be initially \c false. + /// + ///\return The processed node. + /// + ///\pre The queue must not be empty. + Node processNextNode(Node target, bool& reach) + { + if(_queue_tail==_queue_next_dist) { + _curr_dist++; + _queue_next_dist=_queue_head; + } + Node n=_queue[_queue_tail++]; + _processed->set(n,true); + Node m; + for(OutArcIt e(*G,n);e!=INVALID;++e) + if(!(*_reached)[m=G->target(e)]) { + _queue[_queue_head++]=m; + _reached->set(m,true); + _pred->set(m,e); + _dist->set(m,_curr_dist); + reach = reach || (target == m); + } + return n; + } + + ///Processes the next node. + + ///Processes the next node and checks if at least one of reached + ///nodes has \c true value in the \c nm node map. If one node + ///with \c true value is reachable from the processed node, then the + ///\c rnode parameter will be set to the first of such nodes. + /// + ///\param nm A \c bool (or convertible) node map that indicates the + ///possible targets. + ///\retval rnode The reached target node. + ///It should be initially \c INVALID. + /// + ///\return The processed node. + /// + ///\pre The queue must not be empty. + template + Node processNextNode(const NM& nm, Node& rnode) + { + if(_queue_tail==_queue_next_dist) { + _curr_dist++; + _queue_next_dist=_queue_head; + } + Node n=_queue[_queue_tail++]; + _processed->set(n,true); + Node m; + for(OutArcIt e(*G,n);e!=INVALID;++e) + if(!(*_reached)[m=G->target(e)]) { + _queue[_queue_head++]=m; + _reached->set(m,true); + _pred->set(m,e); + _dist->set(m,_curr_dist); + if (nm[m] && rnode == INVALID) rnode = m; + } + return n; + } + + ///The next node to be processed. + + ///Returns the next node to be processed or \c INVALID if the queue + ///is empty. + Node nextNode() const + { + return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID; + } + + ///Returns \c false if there are nodes to be processed. + + ///Returns \c false if there are nodes to be processed + ///in the queue. + bool emptyQueue() const { return _queue_tail==_queue_head; } + + ///Returns the number of the nodes to be processed. + + ///Returns the number of the nodes to be processed + ///in the queue. + int queueSize() const { return _queue_head-_queue_tail; } + + ///Executes the algorithm. + + ///Executes the algorithm. + /// + ///This method runs the %BFS algorithm from the root node(s) + ///in order to compute the shortest path to each node. + /// + ///The algorithm computes + ///- the shortest path tree (forest), + ///- the distance of each node from the root(s). + /// + ///\pre init() must be called and at least one root node should be + ///added with addSource() before using this function. + /// + ///\note b.start() is just a shortcut of the following code. + ///\code + /// while ( !b.emptyQueue() ) { + /// b.processNextNode(); + /// } + ///\endcode + void start() + { + while ( !emptyQueue() ) processNextNode(); + } + + ///Executes the algorithm until the given target node is reached. + + ///Executes the algorithm until the given target node is reached. + /// + ///This method runs the %BFS algorithm from the root node(s) + ///in order to compute the shortest path to \c t. + /// + ///The algorithm computes + ///- the shortest path to \c t, + ///- the distance of \c t from the root(s). + /// + ///\pre init() must be called and at least one root node should be + ///added with addSource() before using this function. + /// + ///\note b.start(t) is just a shortcut of the following code. + ///\code + /// bool reach = false; + /// while ( !b.emptyQueue() && !reach ) { + /// b.processNextNode(t, reach); + /// } + ///\endcode + void start(Node t) + { + bool reach = false; + while ( !emptyQueue() && !reach ) processNextNode(t, reach); + } + + ///Executes the algorithm until a condition is met. + + ///Executes the algorithm until a condition is met. + /// + ///This method runs the %BFS algorithm from the root node(s) in + ///order to compute the shortest path to a node \c v with + /// nm[v] true, if such a node can be found. + /// + ///\param nm A \c bool (or convertible) node map. The algorithm + ///will stop when it reaches a node \c v with nm[v] true. + /// + ///\return The reached node \c v with nm[v] true or + ///\c INVALID if no such node was found. + /// + ///\pre init() must be called and at least one root node should be + ///added with addSource() before using this function. + /// + ///\note b.start(nm) is just a shortcut of the following code. + ///\code + /// Node rnode = INVALID; + /// while ( !b.emptyQueue() && rnode == INVALID ) { + /// b.processNextNode(nm, rnode); + /// } + /// return rnode; + ///\endcode + template + Node start(const NodeBoolMap &nm) + { + Node rnode = INVALID; + while ( !emptyQueue() && rnode == INVALID ) { + processNextNode(nm, rnode); + } + return rnode; + } + + ///Runs the algorithm from the given source node. + + ///This method runs the %BFS algorithm from node \c s + ///in order to compute the shortest path to each node. + /// + ///The algorithm computes + ///- the shortest path tree, + ///- the distance of each node from the root. + /// + ///\note b.run(s) is just a shortcut of the following code. + ///\code + /// b.init(); + /// b.addSource(s); + /// b.start(); + ///\endcode + void run(Node s) { + init(); + addSource(s); + start(); + } + + ///Finds the shortest path between \c s and \c t. + + ///This method runs the %BFS algorithm from node \c s + ///in order to compute the shortest path to node \c t + ///(it stops searching when \c t is processed). + /// + ///\return \c true if \c t is reachable form \c s. + /// + ///\note Apart from the return value, b.run(s,t) is just a + ///shortcut of the following code. + ///\code + /// b.init(); + /// b.addSource(s); + /// b.start(t); + ///\endcode + bool run(Node s,Node t) { + init(); + addSource(s); + start(t); + return reached(t); + } + + ///Runs the algorithm to visit all nodes in the digraph. + + ///This method runs the %BFS algorithm in order to visit all nodes + ///in the digraph. + /// + ///\note b.run(s) is just a shortcut of the following code. + ///\code + /// b.init(); + /// for (NodeIt n(gr); n != INVALID; ++n) { + /// if (!b.reached(n)) { + /// b.addSource(n); + /// b.start(); + /// } + /// } + ///\endcode + void run() { + init(); + for (NodeIt n(*G); n != INVALID; ++n) { + if (!reached(n)) { + addSource(n); + start(); + } + } + } + + ///@} + + ///\name Query Functions + ///The results of the BFS algorithm can be obtained using these + ///functions.\n + ///Either \ref run(Node) "run()" or \ref start() should be called + ///before using them. + + ///@{ + + ///The shortest path to the given node. + + ///Returns the shortest path to the given node from the root(s). + /// + ///\warning \c t should be reached from the root(s). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Path path(Node t) const { return Path(*G, *_pred, t); } + + ///The distance of the given node from the root(s). + + ///Returns the distance of the given node from the root(s). + /// + ///\warning If node \c v is not reached from the root(s), then + ///the return value of this function is undefined. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + int dist(Node v) const { return (*_dist)[v]; } + + ///\brief Returns the 'previous arc' of the shortest path tree for + ///the given node. + /// + ///This function returns the 'previous arc' of the shortest path + ///tree for the node \c v, i.e. it returns the last arc of a + ///shortest path from a root to \c v. It is \c INVALID if \c v + ///is not reached from the root(s) or if \c v is a root. + /// + ///The shortest path tree used here is equal to the shortest path + ///tree used in \ref predNode() and \ref predMap(). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Arc predArc(Node v) const { return (*_pred)[v];} + + ///\brief Returns the 'previous node' of the shortest path tree for + ///the given node. + /// + ///This function returns the 'previous node' of the shortest path + ///tree for the node \c v, i.e. it returns the last but one node + ///of a shortest path from a root to \c v. It is \c INVALID + ///if \c v is not reached from the root(s) or if \c v is a root. + /// + ///The shortest path tree used here is equal to the shortest path + ///tree used in \ref predArc() and \ref predMap(). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID: + G->source((*_pred)[v]); } + + ///\brief Returns a const reference to the node map that stores the + /// distances of the nodes. + /// + ///Returns a const reference to the node map that stores the distances + ///of the nodes calculated by the algorithm. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + const DistMap &distMap() const { return *_dist;} + + ///\brief Returns a const reference to the node map that stores the + ///predecessor arcs. + /// + ///Returns a const reference to the node map that stores the predecessor + ///arcs, which form the shortest path tree (forest). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + const PredMap &predMap() const { return *_pred;} + + ///Checks if the given node is reached from the root(s). + + ///Returns \c true if \c v is reached from the root(s). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + bool reached(Node v) const { return (*_reached)[v]; } + + ///@} + }; + + ///Default traits class of bfs() function. + + ///Default traits class of bfs() function. + ///\tparam GR Digraph type. + template + struct BfsWizardDefaultTraits + { + ///The type of the digraph the algorithm runs on. + typedef GR Digraph; + + ///\brief The type of the map that stores the predecessor + ///arcs of the shortest paths. + /// + ///The type of the map that stores the predecessor + ///arcs of the shortest paths. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap PredMap; + ///Instantiates a PredMap. + + ///This function instantiates a PredMap. + ///\param g is the digraph, to which we would like to define the + ///PredMap. + static PredMap *createPredMap(const Digraph &g) + { + return new PredMap(g); + } + + ///The type of the map that indicates which nodes are processed. + + ///The type of the map that indicates which nodes are processed. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + ///By default, it is a NullMap. + typedef NullMap ProcessedMap; + ///Instantiates a ProcessedMap. + + ///This function instantiates a ProcessedMap. + ///\param g is the digraph, to which + ///we would like to define the ProcessedMap. +#ifdef DOXYGEN + static ProcessedMap *createProcessedMap(const Digraph &g) +#else + static ProcessedMap *createProcessedMap(const Digraph &) +#endif + { + return new ProcessedMap(); + } + + ///The type of the map that indicates which nodes are reached. + + ///The type of the map that indicates which nodes are reached. + ///It must conform to + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + typedef typename Digraph::template NodeMap ReachedMap; + ///Instantiates a ReachedMap. + + ///This function instantiates a ReachedMap. + ///\param g is the digraph, to which + ///we would like to define the ReachedMap. + static ReachedMap *createReachedMap(const Digraph &g) + { + return new ReachedMap(g); + } + + ///The type of the map that stores the distances of the nodes. + + ///The type of the map that stores the distances of the nodes. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap DistMap; + ///Instantiates a DistMap. + + ///This function instantiates a DistMap. + ///\param g is the digraph, to which we would like to define + ///the DistMap + static DistMap *createDistMap(const Digraph &g) + { + return new DistMap(g); + } + + ///The type of the shortest paths. + + ///The type of the shortest paths. + ///It must conform to the \ref concepts::Path "Path" concept. + typedef lemon::Path Path; + }; + + /// Default traits class used by BfsWizard + + /// Default traits class used by BfsWizard. + /// \tparam GR The type of the digraph. + template + class BfsWizardBase : public BfsWizardDefaultTraits + { + + typedef BfsWizardDefaultTraits Base; + protected: + //The type of the nodes in the digraph. + typedef typename Base::Digraph::Node Node; + + //Pointer to the digraph the algorithm runs on. + void *_g; + //Pointer to the map of reached nodes. + void *_reached; + //Pointer to the map of processed nodes. + void *_processed; + //Pointer to the map of predecessors arcs. + void *_pred; + //Pointer to the map of distances. + void *_dist; + //Pointer to the shortest path to the target node. + void *_path; + //Pointer to the distance of the target node. + int *_di; + + public: + /// Constructor. + + /// This constructor does not require parameters, it initiates + /// all of the attributes to \c 0. + BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0), + _dist(0), _path(0), _di(0) {} + + /// Constructor. + + /// This constructor requires one parameter, + /// others are initiated to \c 0. + /// \param g The digraph the algorithm runs on. + BfsWizardBase(const GR &g) : + _g(reinterpret_cast(const_cast(&g))), + _reached(0), _processed(0), _pred(0), _dist(0), _path(0), _di(0) {} + + }; + + /// Auxiliary class for the function-type interface of BFS algorithm. + + /// This auxiliary class is created to implement the + /// \ref bfs() "function-type interface" of \ref Bfs algorithm. + /// It does not have own \ref run(Node) "run()" method, it uses the + /// functions and features of the plain \ref Bfs. + /// + /// This class should only be used through the \ref bfs() function, + /// which makes it easier to use the algorithm. + /// + /// \tparam TR The traits class that defines various types used by the + /// algorithm. + template + class BfsWizard : public TR + { + typedef TR Base; + + typedef typename TR::Digraph Digraph; + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + typedef typename TR::PredMap PredMap; + typedef typename TR::DistMap DistMap; + typedef typename TR::ReachedMap ReachedMap; + typedef typename TR::ProcessedMap ProcessedMap; + typedef typename TR::Path Path; + + public: + + /// Constructor. + BfsWizard() : TR() {} + + /// Constructor that requires parameters. + + /// Constructor that requires parameters. + /// These parameters will be the default values for the traits class. + /// \param g The digraph the algorithm runs on. + BfsWizard(const Digraph &g) : + TR(g) {} + + ///Copy constructor + BfsWizard(const TR &b) : TR(b) {} + + ~BfsWizard() {} + + ///Runs BFS algorithm from the given source node. + + ///This method runs BFS algorithm from node \c s + ///in order to compute the shortest path to each node. + void run(Node s) + { + Bfs alg(*reinterpret_cast(Base::_g)); + if (Base::_pred) + alg.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) + alg.distMap(*reinterpret_cast(Base::_dist)); + if (Base::_reached) + alg.reachedMap(*reinterpret_cast(Base::_reached)); + if (Base::_processed) + alg.processedMap(*reinterpret_cast(Base::_processed)); + if (s!=INVALID) + alg.run(s); + else + alg.run(); + } + + ///Finds the shortest path between \c s and \c t. + + ///This method runs BFS algorithm from node \c s + ///in order to compute the shortest path to node \c t + ///(it stops searching when \c t is processed). + /// + ///\return \c true if \c t is reachable form \c s. + bool run(Node s, Node t) + { + Bfs alg(*reinterpret_cast(Base::_g)); + if (Base::_pred) + alg.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) + alg.distMap(*reinterpret_cast(Base::_dist)); + if (Base::_reached) + alg.reachedMap(*reinterpret_cast(Base::_reached)); + if (Base::_processed) + alg.processedMap(*reinterpret_cast(Base::_processed)); + alg.run(s,t); + if (Base::_path) + *reinterpret_cast(Base::_path) = alg.path(t); + if (Base::_di) + *Base::_di = alg.dist(t); + return alg.reached(t); + } + + ///Runs BFS algorithm to visit all nodes in the digraph. + + ///This method runs BFS algorithm in order to visit all nodes + ///in the digraph. + void run() + { + run(INVALID); + } + + template + struct SetPredMapBase : public Base { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) { return 0; }; + SetPredMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the predecessor map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that stores the predecessor arcs of the nodes. + template + BfsWizard > predMap(const T &t) + { + Base::_pred=reinterpret_cast(const_cast(&t)); + return BfsWizard >(*this); + } + + template + struct SetReachedMapBase : public Base { + typedef T ReachedMap; + static ReachedMap *createReachedMap(const Digraph &) { return 0; }; + SetReachedMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the reached map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that indicates which nodes are reached. + template + BfsWizard > reachedMap(const T &t) + { + Base::_reached=reinterpret_cast(const_cast(&t)); + return BfsWizard >(*this); + } + + template + struct SetDistMapBase : public Base { + typedef T DistMap; + static DistMap *createDistMap(const Digraph &) { return 0; }; + SetDistMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the distance map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that stores the distances of the nodes calculated + ///by the algorithm. + template + BfsWizard > distMap(const T &t) + { + Base::_dist=reinterpret_cast(const_cast(&t)); + return BfsWizard >(*this); + } + + template + struct SetProcessedMapBase : public Base { + typedef T ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &) { return 0; }; + SetProcessedMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-func-param "Named parameter" for setting + ///the processed map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that indicates which nodes are processed. + template + BfsWizard > processedMap(const T &t) + { + Base::_processed=reinterpret_cast(const_cast(&t)); + return BfsWizard >(*this); + } + + template + struct SetPathBase : public Base { + typedef T Path; + SetPathBase(const TR &b) : TR(b) {} + }; + ///\brief \ref named-func-param "Named parameter" + ///for getting the shortest path to the target node. + /// + ///\ref named-func-param "Named parameter" + ///for getting the shortest path to the target node. + template + BfsWizard > path(const T &t) + { + Base::_path=reinterpret_cast(const_cast(&t)); + return BfsWizard >(*this); + } + + ///\brief \ref named-func-param "Named parameter" + ///for getting the distance of the target node. + /// + ///\ref named-func-param "Named parameter" + ///for getting the distance of the target node. + BfsWizard dist(const int &d) + { + Base::_di=const_cast(&d); + return *this; + } + + }; + + ///Function-type interface for BFS algorithm. + + /// \ingroup search + ///Function-type interface for BFS algorithm. + /// + ///This function also has several \ref named-func-param "named parameters", + ///they are declared as the members of class \ref BfsWizard. + ///The following examples show how to use these parameters. + ///\code + /// // Compute shortest path from node s to each node + /// bfs(g).predMap(preds).distMap(dists).run(s); + /// + /// // Compute shortest path from s to t + /// bool reached = bfs(g).path(p).dist(d).run(s,t); + ///\endcode + ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()" + ///to the end of the parameter list. + ///\sa BfsWizard + ///\sa Bfs + template + BfsWizard > + bfs(const GR &digraph) + { + return BfsWizard >(digraph); + } + +#ifdef DOXYGEN + /// \brief Visitor class for BFS. + /// + /// This class defines the interface of the BfsVisit events, and + /// it could be the base of a real visitor class. + template + struct BfsVisitor { + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Node Node; + /// \brief Called for the source node(s) of the BFS. + /// + /// This function is called for the source node(s) of the BFS. + void start(const Node& node) {} + /// \brief Called when a node is reached first time. + /// + /// This function is called when a node is reached first time. + void reach(const Node& node) {} + /// \brief Called when a node is processed. + /// + /// This function is called when a node is processed. + void process(const Node& node) {} + /// \brief Called when an arc reaches a new node. + /// + /// This function is called when the BFS finds an arc whose target node + /// is not reached yet. + void discover(const Arc& arc) {} + /// \brief Called when an arc is examined but its target node is + /// already discovered. + /// + /// This function is called when an arc is examined but its target node is + /// already discovered. + void examine(const Arc& arc) {} + }; +#else + template + struct BfsVisitor { + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Node Node; + void start(const Node&) {} + void reach(const Node&) {} + void process(const Node&) {} + void discover(const Arc&) {} + void examine(const Arc&) {} + + template + struct Constraints { + void constraints() { + Arc arc; + Node node; + visitor.start(node); + visitor.reach(node); + visitor.process(node); + visitor.discover(arc); + visitor.examine(arc); + } + _Visitor& visitor; + }; + }; +#endif + + /// \brief Default traits class of BfsVisit class. + /// + /// Default traits class of BfsVisit class. + /// \tparam GR The type of the digraph the algorithm runs on. + template + struct BfsVisitDefaultTraits { + + /// \brief The type of the digraph the algorithm runs on. + typedef GR Digraph; + + /// \brief The type of the map that indicates which nodes are reached. + /// + /// The type of the map that indicates which nodes are reached. + /// It must conform to + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + typedef typename Digraph::template NodeMap ReachedMap; + + /// \brief Instantiates a ReachedMap. + /// + /// This function instantiates a ReachedMap. + /// \param digraph is the digraph, to which + /// we would like to define the ReachedMap. + static ReachedMap *createReachedMap(const Digraph &digraph) { + return new ReachedMap(digraph); + } + + }; + + /// \ingroup search + /// + /// \brief BFS algorithm class with visitor interface. + /// + /// This class provides an efficient implementation of the BFS algorithm + /// with visitor interface. + /// + /// The BfsVisit class provides an alternative interface to the Bfs + /// class. It works with callback mechanism, the BfsVisit object calls + /// the member functions of the \c Visitor class on every BFS event. + /// + /// This interface of the BFS algorithm should be used in special cases + /// when extra actions have to be performed in connection with certain + /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs() + /// instead. + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// The default type is \ref ListDigraph. + /// The value of GR is not used directly by \ref BfsVisit, + /// it is only passed to \ref BfsVisitDefaultTraits. + /// \tparam VS The Visitor type that is used by the algorithm. + /// \ref BfsVisitor "BfsVisitor" is an empty visitor, which + /// does not observe the BFS events. If you want to observe the BFS + /// events, you should implement your own visitor class. + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref BfsVisitDefaultTraits + /// "BfsVisitDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template , + typename TR = BfsVisitDefaultTraits > +#endif + class BfsVisit { + public: + + ///The traits class. + typedef TR Traits; + + ///The type of the digraph the algorithm runs on. + typedef typename Traits::Digraph Digraph; + + ///The visitor type used by the algorithm. + typedef VS Visitor; + + ///The type of the map that indicates which nodes are reached. + typedef typename Traits::ReachedMap ReachedMap; + + private: + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + //Pointer to the underlying digraph. + const Digraph *_digraph; + //Pointer to the visitor object. + Visitor *_visitor; + //Pointer to the map of reached status of the nodes. + ReachedMap *_reached; + //Indicates if _reached is locally allocated (true) or not. + bool local_reached; + + std::vector _list; + int _list_front, _list_back; + + //Creates the maps if necessary. + void create_maps() { + if(!_reached) { + local_reached = true; + _reached = Traits::createReachedMap(*_digraph); + } + } + + protected: + + BfsVisit() {} + + public: + + typedef BfsVisit Create; + + /// \name Named Template Parameters + + ///@{ + template + struct SetReachedMapTraits : public Traits { + typedef T ReachedMap; + static ReachedMap *createReachedMap(const Digraph &digraph) { + LEMON_ASSERT(false, "ReachedMap is not initialized"); + return 0; // ignore warnings + } + }; + /// \brief \ref named-templ-param "Named parameter" for setting + /// ReachedMap type. + /// + /// \ref named-templ-param "Named parameter" for setting ReachedMap type. + template + struct SetReachedMap : public BfsVisit< Digraph, Visitor, + SetReachedMapTraits > { + typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits > Create; + }; + ///@} + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// + /// \param digraph The digraph the algorithm runs on. + /// \param visitor The visitor object of the algorithm. + BfsVisit(const Digraph& digraph, Visitor& visitor) + : _digraph(&digraph), _visitor(&visitor), + _reached(0), local_reached(false) {} + + /// \brief Destructor. + ~BfsVisit() { + if(local_reached) delete _reached; + } + + /// \brief Sets the map that indicates which nodes are reached. + /// + /// Sets the map that indicates which nodes are reached. + /// If you don't use this function before calling \ref run(Node) "run()" + /// or \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated map, + /// of course. + /// \return (*this) + BfsVisit &reachedMap(ReachedMap &m) { + if(local_reached) { + delete _reached; + local_reached = false; + } + _reached = &m; + return *this; + } + + public: + + /// \name Execution Control + /// The simplest way to execute the BFS algorithm is to use one of the + /// member functions called \ref run(Node) "run()".\n + /// If you need better control on the execution, you have to call + /// \ref init() first, then you can add several source nodes with + /// \ref addSource(). Finally the actual path computation can be + /// performed with one of the \ref start() functions. + + /// @{ + + /// \brief Initializes the internal data structures. + /// + /// Initializes the internal data structures. + void init() { + create_maps(); + _list.resize(countNodes(*_digraph)); + _list_front = _list_back = -1; + for (NodeIt u(*_digraph) ; u != INVALID ; ++u) { + _reached->set(u, false); + } + } + + /// \brief Adds a new source node. + /// + /// Adds a new source node to the set of nodes to be processed. + void addSource(Node s) { + if(!(*_reached)[s]) { + _reached->set(s,true); + _visitor->start(s); + _visitor->reach(s); + _list[++_list_back] = s; + } + } + + /// \brief Processes the next node. + /// + /// Processes the next node. + /// + /// \return The processed node. + /// + /// \pre The queue must not be empty. + Node processNextNode() { + Node n = _list[++_list_front]; + _visitor->process(n); + Arc e; + for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) { + Node m = _digraph->target(e); + if (!(*_reached)[m]) { + _visitor->discover(e); + _visitor->reach(m); + _reached->set(m, true); + _list[++_list_back] = m; + } else { + _visitor->examine(e); + } + } + return n; + } + + /// \brief Processes the next node. + /// + /// Processes the next node and checks if the given target node + /// is reached. If the target node is reachable from the processed + /// node, then the \c reach parameter will be set to \c true. + /// + /// \param target The target node. + /// \retval reach Indicates if the target node is reached. + /// It should be initially \c false. + /// + /// \return The processed node. + /// + /// \pre The queue must not be empty. + Node processNextNode(Node target, bool& reach) { + Node n = _list[++_list_front]; + _visitor->process(n); + Arc e; + for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) { + Node m = _digraph->target(e); + if (!(*_reached)[m]) { + _visitor->discover(e); + _visitor->reach(m); + _reached->set(m, true); + _list[++_list_back] = m; + reach = reach || (target == m); + } else { + _visitor->examine(e); + } + } + return n; + } + + /// \brief Processes the next node. + /// + /// Processes the next node and checks if at least one of reached + /// nodes has \c true value in the \c nm node map. If one node + /// with \c true value is reachable from the processed node, then the + /// \c rnode parameter will be set to the first of such nodes. + /// + /// \param nm A \c bool (or convertible) node map that indicates the + /// possible targets. + /// \retval rnode The reached target node. + /// It should be initially \c INVALID. + /// + /// \return The processed node. + /// + /// \pre The queue must not be empty. + template + Node processNextNode(const NM& nm, Node& rnode) { + Node n = _list[++_list_front]; + _visitor->process(n); + Arc e; + for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) { + Node m = _digraph->target(e); + if (!(*_reached)[m]) { + _visitor->discover(e); + _visitor->reach(m); + _reached->set(m, true); + _list[++_list_back] = m; + if (nm[m] && rnode == INVALID) rnode = m; + } else { + _visitor->examine(e); + } + } + return n; + } + + /// \brief The next node to be processed. + /// + /// Returns the next node to be processed or \c INVALID if the queue + /// is empty. + Node nextNode() const { + return _list_front != _list_back ? _list[_list_front + 1] : INVALID; + } + + /// \brief Returns \c false if there are nodes + /// to be processed. + /// + /// Returns \c false if there are nodes + /// to be processed in the queue. + bool emptyQueue() const { return _list_front == _list_back; } + + /// \brief Returns the number of the nodes to be processed. + /// + /// Returns the number of the nodes to be processed in the queue. + int queueSize() const { return _list_back - _list_front; } + + /// \brief Executes the algorithm. + /// + /// Executes the algorithm. + /// + /// This method runs the %BFS algorithm from the root node(s) + /// in order to compute the shortest path to each node. + /// + /// The algorithm computes + /// - the shortest path tree (forest), + /// - the distance of each node from the root(s). + /// + /// \pre init() must be called and at least one root node should be added + /// with addSource() before using this function. + /// + /// \note b.start() is just a shortcut of the following code. + /// \code + /// while ( !b.emptyQueue() ) { + /// b.processNextNode(); + /// } + /// \endcode + void start() { + while ( !emptyQueue() ) processNextNode(); + } + + /// \brief Executes the algorithm until the given target node is reached. + /// + /// Executes the algorithm until the given target node is reached. + /// + /// This method runs the %BFS algorithm from the root node(s) + /// in order to compute the shortest path to \c t. + /// + /// The algorithm computes + /// - the shortest path to \c t, + /// - the distance of \c t from the root(s). + /// + /// \pre init() must be called and at least one root node should be + /// added with addSource() before using this function. + /// + /// \note b.start(t) is just a shortcut of the following code. + /// \code + /// bool reach = false; + /// while ( !b.emptyQueue() && !reach ) { + /// b.processNextNode(t, reach); + /// } + /// \endcode + void start(Node t) { + bool reach = false; + while ( !emptyQueue() && !reach ) processNextNode(t, reach); + } + + /// \brief Executes the algorithm until a condition is met. + /// + /// Executes the algorithm until a condition is met. + /// + /// This method runs the %BFS algorithm from the root node(s) in + /// order to compute the shortest path to a node \c v with + /// nm[v] true, if such a node can be found. + /// + /// \param nm must be a bool (or convertible) node map. The + /// algorithm will stop when it reaches a node \c v with + /// nm[v] true. + /// + /// \return The reached node \c v with nm[v] true or + /// \c INVALID if no such node was found. + /// + /// \pre init() must be called and at least one root node should be + /// added with addSource() before using this function. + /// + /// \note b.start(nm) is just a shortcut of the following code. + /// \code + /// Node rnode = INVALID; + /// while ( !b.emptyQueue() && rnode == INVALID ) { + /// b.processNextNode(nm, rnode); + /// } + /// return rnode; + /// \endcode + template + Node start(const NM &nm) { + Node rnode = INVALID; + while ( !emptyQueue() && rnode == INVALID ) { + processNextNode(nm, rnode); + } + return rnode; + } + + /// \brief Runs the algorithm from the given source node. + /// + /// This method runs the %BFS algorithm from node \c s + /// in order to compute the shortest path to each node. + /// + /// The algorithm computes + /// - the shortest path tree, + /// - the distance of each node from the root. + /// + /// \note b.run(s) is just a shortcut of the following code. + ///\code + /// b.init(); + /// b.addSource(s); + /// b.start(); + ///\endcode + void run(Node s) { + init(); + addSource(s); + start(); + } + + /// \brief Finds the shortest path between \c s and \c t. + /// + /// This method runs the %BFS algorithm from node \c s + /// in order to compute the shortest path to node \c t + /// (it stops searching when \c t is processed). + /// + /// \return \c true if \c t is reachable form \c s. + /// + /// \note Apart from the return value, b.run(s,t) is just a + /// shortcut of the following code. + ///\code + /// b.init(); + /// b.addSource(s); + /// b.start(t); + ///\endcode + bool run(Node s,Node t) { + init(); + addSource(s); + start(t); + return reached(t); + } + + /// \brief Runs the algorithm to visit all nodes in the digraph. + /// + /// This method runs the %BFS algorithm in order to visit all nodes + /// in the digraph. + /// + /// \note b.run(s) is just a shortcut of the following code. + ///\code + /// b.init(); + /// for (NodeIt n(gr); n != INVALID; ++n) { + /// if (!b.reached(n)) { + /// b.addSource(n); + /// b.start(); + /// } + /// } + ///\endcode + void run() { + init(); + for (NodeIt it(*_digraph); it != INVALID; ++it) { + if (!reached(it)) { + addSource(it); + start(); + } + } + } + + ///@} + + /// \name Query Functions + /// The results of the BFS algorithm can be obtained using these + /// functions.\n + /// Either \ref run(Node) "run()" or \ref start() should be called + /// before using them. + + ///@{ + + /// \brief Checks if the given node is reached from the root(s). + /// + /// Returns \c true if \c v is reached from the root(s). + /// + /// \pre Either \ref run(Node) "run()" or \ref init() + /// must be called before using this function. + bool reached(Node v) const { return (*_reached)[v]; } + + ///@} + + }; + +} //END OF NAMESPACE LEMON + +#endif diff --git a/lemon/lemon/bin_heap.h b/lemon/lemon/bin_heap.h new file mode 100644 index 0000000..d46f3fe --- /dev/null +++ b/lemon/lemon/bin_heap.h @@ -0,0 +1,347 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BIN_HEAP_H +#define LEMON_BIN_HEAP_H + +///\ingroup heaps +///\file +///\brief Binary heap implementation. + +#include +#include +#include + +namespace lemon { + + /// \ingroup heaps + /// + /// \brief Binary heap data structure. + /// + /// This class implements the \e binary \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. +#ifdef DOXYGEN + template +#else + template > +#endif + class BinHeap { + public: + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + /// Functor type for comparing the priorities. + typedef CMP Compare; + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + private: + std::vector _data; + Compare _comp; + ItemIntMap &_iim; + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit BinHeap(ItemIntMap &map) : _iim(map) {} + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + BinHeap(ItemIntMap &map, const Compare &comp) + : _iim(map), _comp(comp) {} + + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { + _data.clear(); + } + + private: + static int parent(int i) { return (i-1)/2; } + + static int secondChild(int i) { return 2*i+2; } + bool less(const Pair &p1, const Pair &p2) const { + return _comp(p1.second, p2.second); + } + + int bubbleUp(int hole, Pair p) { + int par = parent(hole); + while( hole>0 && less(p,_data[par]) ) { + move(_data[par],hole); + hole = par; + par = parent(hole); + } + move(p, hole); + return hole; + } + + int bubbleDown(int hole, Pair p, int length) { + int child = secondChild(hole); + while(child < length) { + if( less(_data[child-1], _data[child]) ) { + --child; + } + if( !less(_data[child], p) ) + goto ok; + move(_data[child], hole); + hole = child; + child = secondChild(hole); + } + child--; + if( child 0) { + bubbleDown(0, _data[n], n); + } + _data.pop_back(); + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. + void erase(const Item &i) { + int h = _iim[i]; + int n = _data.size()-1; + _iim.set(_data[h].first, POST_HEAP); + if( h < n ) { + if ( bubbleUp(h, _data[n]) == h) { + bubbleDown(h, _data[n], n); + } + } + _data.pop_back(); + } + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param i The item. + /// \pre \e i must be in the heap. + Prio operator[](const Item &i) const { + int idx = _iim[i]; + return _data[idx].second; + } + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// \param i The item. + /// \param p The priority. + void set(const Item &i, const Prio &p) { + int idx = _iim[i]; + if( idx < 0 ) { + push(i,p); + } + else if( _comp(p, _data[idx].second) ) { + bubbleUp(idx, Pair(i,p)); + } + else { + bubbleDown(idx, Pair(i,p), _data.size()); + } + } + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at least \e p. + void decrease(const Item &i, const Prio &p) { + int idx = _iim[i]; + bubbleUp(idx, Pair(i,p)); + } + + /// \brief Increase the priority of an item to the given value. + /// + /// This function increases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at most \e p. + void increase(const Item &i, const Prio &p) { + int idx = _iim[i]; + bubbleDown(idx, Pair(i,p), _data.size()); + } + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param i The item. + State state(const Item &i) const { + int s = _iim[i]; + if( s>=0 ) + s=0; + return State(s); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) { + erase(i); + } + _iim[i] = st; + break; + case IN_HEAP: + break; + } + } + + /// \brief Replace an item in the heap. + /// + /// This function replaces item \c i with item \c j. + /// Item \c i must be in the heap, while \c j must be out of the heap. + /// After calling this method, item \c i will be out of the + /// heap and \c j will be in the heap with the same prioriority + /// as item \c i had before. + void replace(const Item& i, const Item& j) { + int idx = _iim[i]; + _iim.set(i, _iim[j]); + _iim.set(j, idx); + _data[idx].first = j; + } + + }; // class BinHeap + +} // namespace lemon + +#endif // LEMON_BIN_HEAP_H diff --git a/lemon/lemon/binomial_heap.h b/lemon/lemon/binomial_heap.h new file mode 100644 index 0000000..5bc1378 --- /dev/null +++ b/lemon/lemon/binomial_heap.h @@ -0,0 +1,445 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BINOMIAL_HEAP_H +#define LEMON_BINOMIAL_HEAP_H + +///\file +///\ingroup heaps +///\brief Binomial Heap implementation. + +#include +#include +#include +#include +#include + +namespace lemon { + + /// \ingroup heaps + /// + ///\brief Binomial heap data structure. + /// + /// This class implements the \e binomial \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". + /// + /// The methods \ref increase() and \ref erase() are not efficient + /// in a binomial heap. In case of many calls of these operations, + /// it is better to use other heap structure, e.g. \ref BinHeap + /// "binary heap". + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. +#ifdef DOXYGEN + template +#else + template > +#endif + class BinomialHeap { + public: + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Functor type for comparing the priorities. + typedef CMP Compare; + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + private: + class Store; + + std::vector _data; + int _min, _head; + ItemIntMap &_iim; + Compare _comp; + int _num_items; + + public: + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit BinomialHeap(ItemIntMap &map) + : _min(0), _head(-1), _iim(map), _num_items(0) {} + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + BinomialHeap(ItemIntMap &map, const Compare &comp) + : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {} + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _num_items; } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _num_items==0; } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { + _data.clear(); _min=0; _num_items=0; _head=-1; + } + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// \param item The item. + /// \param value The priority. + void set (const Item& item, const Prio& value) { + int i=_iim[item]; + if ( i >= 0 && _data[i].in ) { + if ( _comp(value, _data[i].prio) ) decrease(item, value); + if ( _comp(_data[i].prio, value) ) increase(item, value); + } else push(item, value); + } + + /// \brief Insert an item into the heap with the given priority. + /// + /// This function inserts the given item into the heap with the + /// given priority. + /// \param item The item to insert. + /// \param value The priority of the item. + /// \pre \e item must not be stored in the heap. + void push (const Item& item, const Prio& value) { + int i=_iim[item]; + if ( i<0 ) { + int s=_data.size(); + _iim.set( item,s ); + Store st; + st.name=item; + st.prio=value; + _data.push_back(st); + i=s; + } + else { + _data[i].parent=_data[i].right_neighbor=_data[i].child=-1; + _data[i].degree=0; + _data[i].in=true; + _data[i].prio=value; + } + + if( 0==_num_items ) { + _head=i; + _min=i; + } else { + merge(i); + if( _comp(_data[i].prio, _data[_min].prio) ) _min=i; + } + ++_num_items; + } + + /// \brief Return the item having minimum priority. + /// + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { return _data[_min].name; } + + /// \brief The minimum priority. + /// + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { return _data[_min].prio; } + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param item The item. + /// \pre \e item must be in the heap. + const Prio& operator[](const Item& item) const { + return _data[_iim[item]].prio; + } + + /// \brief Remove the item having minimum priority. + /// + /// This function removes the item having minimum priority. + /// \pre The heap must be non-empty. + void pop() { + _data[_min].in=false; + + int head_child=-1; + if ( _data[_min].child!=-1 ) { + int child=_data[_min].child; + int neighb; + while( child!=-1 ) { + neighb=_data[child].right_neighbor; + _data[child].parent=-1; + _data[child].right_neighbor=head_child; + head_child=child; + child=neighb; + } + } + + if ( _data[_head].right_neighbor==-1 ) { + // there was only one root + _head=head_child; + } + else { + // there were more roots + if( _head!=_min ) { unlace(_min); } + else { _head=_data[_head].right_neighbor; } + merge(head_child); + } + _min=findMin(); + --_num_items; + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param item The item to delete. + /// \pre \e item must be in the heap. + void erase (const Item& item) { + int i=_iim[item]; + if ( i >= 0 && _data[i].in ) { + decrease( item, _data[_min].prio-1 ); + pop(); + } + } + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param item The item. + /// \param value The priority. + /// \pre \e item must be stored in the heap with priority at least \e value. + void decrease (Item item, const Prio& value) { + int i=_iim[item]; + int p=_data[i].parent; + _data[i].prio=value; + + while( p!=-1 && _comp(value, _data[p].prio) ) { + _data[i].name=_data[p].name; + _data[i].prio=_data[p].prio; + _data[p].name=item; + _data[p].prio=value; + _iim[_data[i].name]=i; + i=p; + p=_data[p].parent; + } + _iim[item]=i; + if ( _comp(value, _data[_min].prio) ) _min=i; + } + + /// \brief Increase the priority of an item to the given value. + /// + /// This function increases the priority of an item to the given value. + /// \param item The item. + /// \param value The priority. + /// \pre \e item must be stored in the heap with priority at most \e value. + void increase (Item item, const Prio& value) { + erase(item); + push(item, value); + } + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param item The item. + State state(const Item &item) const { + int i=_iim[item]; + if( i>=0 ) { + if ( _data[i].in ) i=0; + else i=-2; + } + return State(i); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) { + erase(i); + } + _iim[i] = st; + break; + case IN_HEAP: + break; + } + } + + private: + + // Find the minimum of the roots + int findMin() { + if( _head!=-1 ) { + int min_loc=_head, min_val=_data[_head].prio; + for( int x=_data[_head].right_neighbor; x!=-1; + x=_data[x].right_neighbor ) { + if( _comp( _data[x].prio,min_val ) ) { + min_val=_data[x].prio; + min_loc=x; + } + } + return min_loc; + } + else return -1; + } + + // Merge the heap with another heap starting at the given position + void merge(int a) { + if( _head==-1 || a==-1 ) return; + if( _data[a].right_neighbor==-1 && + _data[a].degree<=_data[_head].degree ) { + _data[a].right_neighbor=_head; + _head=a; + } else { + interleave(a); + } + if( _data[_head].right_neighbor==-1 ) return; + + int x=_head; + int x_prev=-1, x_next=_data[x].right_neighbor; + while( x_next!=-1 ) { + if( _data[x].degree!=_data[x_next].degree || + ( _data[x_next].right_neighbor!=-1 && + _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) { + x_prev=x; + x=x_next; + } + else { + if( _comp(_data[x_next].prio,_data[x].prio) ) { + if( x_prev==-1 ) { + _head=x_next; + } else { + _data[x_prev].right_neighbor=x_next; + } + fuse(x,x_next); + x=x_next; + } + else { + _data[x].right_neighbor=_data[x_next].right_neighbor; + fuse(x_next,x); + } + } + x_next=_data[x].right_neighbor; + } + } + + // Interleave the elements of the given list into the list of the roots + void interleave(int a) { + int p=_head, q=a; + int curr=_data.size(); + _data.push_back(Store()); + + while( p!=-1 || q!=-1 ) { + if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) { + _data[curr].right_neighbor=p; + curr=p; + p=_data[p].right_neighbor; + } + else { + _data[curr].right_neighbor=q; + curr=q; + q=_data[q].right_neighbor; + } + } + + _head=_data.back().right_neighbor; + _data.pop_back(); + } + + // Lace node a under node b + void fuse(int a, int b) { + _data[a].parent=b; + _data[a].right_neighbor=_data[b].child; + _data[b].child=a; + + ++_data[b].degree; + } + + // Unlace node a (if it has siblings) + void unlace(int a) { + int neighb=_data[a].right_neighbor; + int other=_head; + + while( _data[other].right_neighbor!=a ) + other=_data[other].right_neighbor; + _data[other].right_neighbor=neighb; + } + + private: + + class Store { + friend class BinomialHeap; + + Item name; + int parent; + int right_neighbor; + int child; + int degree; + bool in; + Prio prio; + + Store() : parent(-1), right_neighbor(-1), child(-1), degree(0), + in(true) {} + }; + }; + +} //namespace lemon + +#endif //LEMON_BINOMIAL_HEAP_H + diff --git a/lemon/lemon/bits/.deps/.dirstamp b/lemon/lemon/bits/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/lemon/lemon/bits/.deps/lemon_libemon_la-windows.Plo b/lemon/lemon/bits/.deps/lemon_libemon_la-windows.Plo new file mode 100644 index 0000000..e6884b4 --- /dev/null +++ b/lemon/lemon/bits/.deps/lemon_libemon_la-windows.Plo @@ -0,0 +1,316 @@ +lemon/bits/lemon_libemon_la-windows.lo: lemon/bits/windows.cc \ + lemon/bits/windows.h /usr/include/c++/4.7/string \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/postypes.h \ + /usr/include/c++/4.7/cwchar /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/xlocale.h /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/iosfwd \ + /usr/include/c++/4.7/cctype /usr/include/ctype.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/basic_string.tcc /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/include/c++/4.7/ctime /usr/include/x86_64-linux-gnu/sys/times.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h /usr/include/c++/4.7/cmath \ + /usr/include/math.h /usr/include/x86_64-linux-gnu/bits/huge_val.h \ + /usr/include/x86_64-linux-gnu/bits/huge_valf.h \ + /usr/include/x86_64-linux-gnu/bits/huge_vall.h \ + /usr/include/x86_64-linux-gnu/bits/inf.h \ + /usr/include/x86_64-linux-gnu/bits/nan.h \ + /usr/include/x86_64-linux-gnu/bits/mathdef.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mathinline.h \ + /usr/include/c++/4.7/sstream /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/ios /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/bits/locale_classes.h \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc /usr/include/c++/4.7/ostream \ + /usr/include/c++/4.7/bits/ostream.tcc \ + /usr/include/c++/4.7/bits/istream.tcc \ + /usr/include/c++/4.7/bits/sstream.tcc + +lemon/bits/windows.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/xlocale.h: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/include/c++/4.7/ctime: + +/usr/include/x86_64-linux-gnu/sys/times.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/c++/4.7/cmath: + +/usr/include/math.h: + +/usr/include/x86_64-linux-gnu/bits/huge_val.h: + +/usr/include/x86_64-linux-gnu/bits/huge_valf.h: + +/usr/include/x86_64-linux-gnu/bits/huge_vall.h: + +/usr/include/x86_64-linux-gnu/bits/inf.h: + +/usr/include/x86_64-linux-gnu/bits/nan.h: + +/usr/include/x86_64-linux-gnu/bits/mathdef.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathinline.h: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/bits/sstream.tcc: diff --git a/lemon/lemon/bits/.dirstamp b/lemon/lemon/bits/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/lemon/lemon/bits/alteration_notifier.h b/lemon/lemon/bits/alteration_notifier.h new file mode 100644 index 0000000..50561f6 --- /dev/null +++ b/lemon/lemon/bits/alteration_notifier.h @@ -0,0 +1,467 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_ALTERATION_NOTIFIER_H +#define LEMON_BITS_ALTERATION_NOTIFIER_H + +#include +#include + +#include + +//\ingroup graphbits +//\file +//\brief Observer notifier for graph alteration observers. + +namespace lemon { + + // \ingroup graphbits + // + // \brief Notifier class to notify observes about alterations in + // a container. + // + // The simple graphs can be refered as two containers: a node container + // and an edge container. But they do not store values directly, they + // are just key continars for more value containers, which are the + // node and edge maps. + // + // The node and edge sets of the graphs can be changed as we add or erase + // nodes and edges in the graph. LEMON would like to handle easily + // that the node and edge maps should contain values for all nodes or + // edges. If we want to check on every indicing if the map contains + // the current indicing key that cause a drawback in the performance + // in the library. We use another solution: we notify all maps about + // an alteration in the graph, which cause only drawback on the + // alteration of the graph. + // + // This class provides an interface to a node or edge container. + // The first() and next() member functions make possible + // to iterate on the keys of the container. + // The id() function returns an integer id for each key. + // The maxId() function gives back an upper bound of the ids. + // + // For the proper functonality of this class, we should notify it + // about each alteration in the container. The alterations have four type: + // add(), erase(), build() and clear(). The add() and + // erase() signal that only one or few items added or erased to or + // from the graph. If all items are erased from the graph or if a new graph + // is built from an empty graph, then it can be signaled with the + // clear() and build() members. Important rule that if we erase items + // from graphs we should first signal the alteration and after that erase + // them from the container, on the other way on item addition we should + // first extend the container and just after that signal the alteration. + // + // The alteration can be observed with a class inherited from the + // ObserverBase nested class. The signals can be handled with + // overriding the virtual functions defined in the base class. The + // observer base can be attached to the notifier with the + // attach() member and can be detached with detach() function. The + // alteration handlers should not call any function which signals + // an other alteration in the same notifier and should not + // detach any observer from the notifier. + // + // Alteration observers try to be exception safe. If an add() or + // a clear() function throws an exception then the remaining + // observeres will not be notified and the fulfilled additions will + // be rolled back by calling the erase() or clear() functions. + // Hence erase() and clear() should not throw exception. + // Actullay, they can throw only \ref ImmediateDetach exception, + // which detach the observer from the notifier. + // + // There are some cases, when the alteration observing is not completly + // reliable. If we want to carry out the node degree in the graph + // as in the \ref InDegMap and we use the reverseArc(), then it cause + // unreliable functionality. Because the alteration observing signals + // only erasing and adding but not the reversing, it will stores bad + // degrees. Apart form that the subgraph adaptors cannot even signal + // the alterations because just a setting in the filter map can modify + // the graph and this cannot be watched in any way. + // + // \param _Container The container which is observed. + // \param _Item The item type which is obserbved. + + template + class AlterationNotifier { + public: + + typedef True Notifier; + + typedef _Container Container; + typedef _Item Item; + + // \brief Exception which can be called from clear() and + // erase(). + // + // From the clear() and erase() function only this + // exception is allowed to throw. The exception immediatly + // detaches the current observer from the notifier. Because the + // clear() and erase() should not throw other exceptions + // it can be used to invalidate the observer. + struct ImmediateDetach {}; + + // \brief ObserverBase is the base class for the observers. + // + // ObserverBase is the abstract base class for the observers. + // It will be notified about an item was inserted into or + // erased from the graph. + // + // The observer interface contains some pure virtual functions + // to override. The add() and erase() functions are + // to notify the oberver when one item is added or erased. + // + // The build() and clear() members are to notify the observer + // about the container is built from an empty container or + // is cleared to an empty container. + class ObserverBase { + protected: + typedef AlterationNotifier Notifier; + + friend class AlterationNotifier; + + // \brief Default constructor. + // + // Default constructor for ObserverBase. + ObserverBase() : _notifier(0) {} + + // \brief Constructor which attach the observer into notifier. + // + // Constructor which attach the observer into notifier. + ObserverBase(AlterationNotifier& nf) { + attach(nf); + } + + // \brief Constructor which attach the obserever to the same notifier. + // + // Constructor which attach the obserever to the same notifier as + // the other observer is attached to. + ObserverBase(const ObserverBase& copy) { + if (copy.attached()) { + attach(*copy.notifier()); + } + } + + // \brief Destructor + virtual ~ObserverBase() { + if (attached()) { + detach(); + } + } + + // \brief Attaches the observer into an AlterationNotifier. + // + // This member attaches the observer into an AlterationNotifier. + void attach(AlterationNotifier& nf) { + nf.attach(*this); + } + + // \brief Detaches the observer into an AlterationNotifier. + // + // This member detaches the observer from an AlterationNotifier. + void detach() { + _notifier->detach(*this); + } + + // \brief Gives back a pointer to the notifier which the map + // attached into. + // + // This function gives back a pointer to the notifier which the map + // attached into. + Notifier* notifier() const { return const_cast(_notifier); } + + // Gives back true when the observer is attached into a notifier. + bool attached() const { return _notifier != 0; } + + private: + + ObserverBase& operator=(const ObserverBase& copy); + + protected: + + Notifier* _notifier; + typename std::list::iterator _index; + + // \brief The member function to notificate the observer about an + // item is added to the container. + // + // The add() member function notificates the observer about an item + // is added to the container. It have to be overrided in the + // subclasses. + virtual void add(const Item&) = 0; + + // \brief The member function to notificate the observer about + // more item is added to the container. + // + // The add() member function notificates the observer about more item + // is added to the container. It have to be overrided in the + // subclasses. + virtual void add(const std::vector& items) = 0; + + // \brief The member function to notificate the observer about an + // item is erased from the container. + // + // The erase() member function notificates the observer about an + // item is erased from the container. It have to be overrided in + // the subclasses. + virtual void erase(const Item&) = 0; + + // \brief The member function to notificate the observer about + // more item is erased from the container. + // + // The erase() member function notificates the observer about more item + // is erased from the container. It have to be overrided in the + // subclasses. + virtual void erase(const std::vector& items) = 0; + + // \brief The member function to notificate the observer about the + // container is built. + // + // The build() member function notificates the observer about the + // container is built from an empty container. It have to be + // overrided in the subclasses. + virtual void build() = 0; + + // \brief The member function to notificate the observer about all + // items are erased from the container. + // + // The clear() member function notificates the observer about all + // items are erased from the container. It have to be overrided in + // the subclasses. + virtual void clear() = 0; + + }; + + protected: + + const Container* container; + + typedef std::list Observers; + Observers _observers; + + + public: + + // \brief Default constructor. + // + // The default constructor of the AlterationNotifier. + // It creates an empty notifier. + AlterationNotifier() + : container(0) {} + + // \brief Constructor. + // + // Constructor with the observed container parameter. + AlterationNotifier(const Container& _container) + : container(&_container) {} + + // \brief Copy Constructor of the AlterationNotifier. + // + // Copy constructor of the AlterationNotifier. + // It creates only an empty notifier because the copiable + // notifier's observers have to be registered still into that notifier. + AlterationNotifier(const AlterationNotifier& _notifier) + : container(_notifier.container) {} + + // \brief Destructor. + // + // Destructor of the AlterationNotifier. + ~AlterationNotifier() { + typename Observers::iterator it; + for (it = _observers.begin(); it != _observers.end(); ++it) { + (*it)->_notifier = 0; + } + } + + // \brief Sets the container. + // + // Sets the container. + void setContainer(const Container& _container) { + container = &_container; + } + + protected: + + AlterationNotifier& operator=(const AlterationNotifier&); + + public: + + // \brief First item in the container. + // + // Returns the first item in the container. It is + // for start the iteration on the container. + void first(Item& item) const { + container->first(item); + } + + // \brief Next item in the container. + // + // Returns the next item in the container. It is + // for iterate on the container. + void next(Item& item) const { + container->next(item); + } + + // \brief Returns the id of the item. + // + // Returns the id of the item provided by the container. + int id(const Item& item) const { + return container->id(item); + } + + // \brief Returns the maximum id of the container. + // + // Returns the maximum id of the container. + int maxId() const { + return container->maxId(Item()); + } + + protected: + + void attach(ObserverBase& observer) { + observer._index = _observers.insert(_observers.begin(), &observer); + observer._notifier = this; + } + + void detach(ObserverBase& observer) { + _observers.erase(observer._index); + observer._index = _observers.end(); + observer._notifier = 0; + } + + public: + + // \brief Notifies all the registed observers about an item added to + // the container. + // + // It notifies all the registed observers about an item added to + // the container. + void add(const Item& item) { + typename Observers::reverse_iterator it; + try { + for (it = _observers.rbegin(); it != _observers.rend(); ++it) { + (*it)->add(item); + } + } catch (...) { + typename Observers::iterator jt; + for (jt = it.base(); jt != _observers.end(); ++jt) { + (*jt)->erase(item); + } + throw; + } + } + + // \brief Notifies all the registed observers about more item added to + // the container. + // + // It notifies all the registed observers about more item added to + // the container. + void add(const std::vector& items) { + typename Observers::reverse_iterator it; + try { + for (it = _observers.rbegin(); it != _observers.rend(); ++it) { + (*it)->add(items); + } + } catch (...) { + typename Observers::iterator jt; + for (jt = it.base(); jt != _observers.end(); ++jt) { + (*jt)->erase(items); + } + throw; + } + } + + // \brief Notifies all the registed observers about an item erased from + // the container. + // + // It notifies all the registed observers about an item erased from + // the container. + void erase(const Item& item) throw() { + typename Observers::iterator it = _observers.begin(); + while (it != _observers.end()) { + try { + (*it)->erase(item); + ++it; + } catch (const ImmediateDetach&) { + (*it)->_index = _observers.end(); + (*it)->_notifier = 0; + it = _observers.erase(it); + } + } + } + + // \brief Notifies all the registed observers about more item erased + // from the container. + // + // It notifies all the registed observers about more item erased from + // the container. + void erase(const std::vector& items) { + typename Observers::iterator it = _observers.begin(); + while (it != _observers.end()) { + try { + (*it)->erase(items); + ++it; + } catch (const ImmediateDetach&) { + (*it)->_index = _observers.end(); + (*it)->_notifier = 0; + it = _observers.erase(it); + } + } + } + + // \brief Notifies all the registed observers about the container is + // built. + // + // Notifies all the registed observers about the container is built + // from an empty container. + void build() { + typename Observers::reverse_iterator it; + try { + for (it = _observers.rbegin(); it != _observers.rend(); ++it) { + (*it)->build(); + } + } catch (...) { + typename Observers::iterator jt; + for (jt = it.base(); jt != _observers.end(); ++jt) { + (*jt)->clear(); + } + throw; + } + } + + // \brief Notifies all the registed observers about all items are + // erased. + // + // Notifies all the registed observers about all items are erased + // from the container. + void clear() { + typename Observers::iterator it = _observers.begin(); + while (it != _observers.end()) { + try { + (*it)->clear(); + ++it; + } catch (const ImmediateDetach&) { + (*it)->_index = _observers.end(); + (*it)->_notifier = 0; + it = _observers.erase(it); + } + } + } + }; + +} + +#endif diff --git a/lemon/lemon/bits/array_map.h b/lemon/lemon/bits/array_map.h new file mode 100644 index 0000000..34bdda9 --- /dev/null +++ b/lemon/lemon/bits/array_map.h @@ -0,0 +1,351 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_ARRAY_MAP_H +#define LEMON_BITS_ARRAY_MAP_H + +#include + +#include +#include +#include +#include + +// \ingroup graphbits +// \file +// \brief Graph map based on the array storage. + +namespace lemon { + + // \ingroup graphbits + // + // \brief Graph map based on the array storage. + // + // The ArrayMap template class is graph map structure that automatically + // updates the map when a key is added to or erased from the graph. + // This map uses the allocators to implement the container functionality. + // + // The template parameters are the Graph, the current Item type and + // the Value type of the map. + template + class ArrayMap + : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { + public: + // The graph type. + typedef _Graph GraphType; + // The item type. + typedef _Item Item; + // The reference map tag. + typedef True ReferenceMapTag; + + // The key type of the map. + typedef _Item Key; + // The value type of the map. + typedef _Value Value; + + // The const reference type of the map. + typedef const _Value& ConstReference; + // The reference type of the map. + typedef _Value& Reference; + + // The map type. + typedef ArrayMap Map; + + // The notifier type. + typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier; + + private: + + // The MapBase of the Map which imlements the core regisitry function. + typedef typename Notifier::ObserverBase Parent; + + typedef std::allocator Allocator; + + public: + + // \brief Graph initialized map constructor. + // + // Graph initialized map constructor. + explicit ArrayMap(const GraphType& graph) { + Parent::attach(graph.notifier(Item())); + allocate_memory(); + Notifier* nf = Parent::notifier(); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + int id = nf->id(it);; + allocator.construct(&(values[id]), Value()); + } + } + + // \brief Constructor to use default value to initialize the map. + // + // It constructs a map and initialize all of the the map. + ArrayMap(const GraphType& graph, const Value& value) { + Parent::attach(graph.notifier(Item())); + allocate_memory(); + Notifier* nf = Parent::notifier(); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + int id = nf->id(it);; + allocator.construct(&(values[id]), value); + } + } + + private: + // \brief Constructor to copy a map of the same map type. + // + // Constructor to copy a map of the same map type. + ArrayMap(const ArrayMap& copy) : Parent() { + if (copy.attached()) { + attach(*copy.notifier()); + } + capacity = copy.capacity; + if (capacity == 0) return; + values = allocator.allocate(capacity); + Notifier* nf = Parent::notifier(); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + int id = nf->id(it);; + allocator.construct(&(values[id]), copy.values[id]); + } + } + + // \brief Assign operator. + // + // This operator assigns for each item in the map the + // value mapped to the same item in the copied map. + // The parameter map should be indiced with the same + // itemset because this assign operator does not change + // the container of the map. + ArrayMap& operator=(const ArrayMap& cmap) { + return operator=(cmap); + } + + + // \brief Template assign operator. + // + // The given parameter should conform to the ReadMap + // concecpt and could be indiced by the current item set of + // the NodeMap. In this case the value for each item + // is assigned by the value of the given ReadMap. + template + ArrayMap& operator=(const CMap& cmap) { + checkConcept, CMap>(); + const typename Parent::Notifier* nf = Parent::notifier(); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + set(it, cmap[it]); + } + return *this; + } + + public: + // \brief The destructor of the map. + // + // The destructor of the map. + virtual ~ArrayMap() { + if (attached()) { + clear(); + detach(); + } + } + + protected: + + using Parent::attach; + using Parent::detach; + using Parent::attached; + + public: + + // \brief The subscript operator. + // + // The subscript operator. The map can be subscripted by the + // actual keys of the graph. + Value& operator[](const Key& key) { + int id = Parent::notifier()->id(key); + return values[id]; + } + + // \brief The const subscript operator. + // + // The const subscript operator. The map can be subscripted by the + // actual keys of the graph. + const Value& operator[](const Key& key) const { + int id = Parent::notifier()->id(key); + return values[id]; + } + + // \brief Setter function of the map. + // + // Setter function of the map. Equivalent with map[key] = val. + // This is a compatibility feature with the not dereferable maps. + void set(const Key& key, const Value& val) { + (*this)[key] = val; + } + + protected: + + // \brief Adds a new key to the map. + // + // It adds a new key to the map. It is called by the observer notifier + // and it overrides the add() member function of the observer base. + virtual void add(const Key& key) { + Notifier* nf = Parent::notifier(); + int id = nf->id(key); + if (id >= capacity) { + int new_capacity = (capacity == 0 ? 1 : capacity); + while (new_capacity <= id) { + new_capacity <<= 1; + } + Value* new_values = allocator.allocate(new_capacity); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + int jd = nf->id(it);; + if (id != jd) { + allocator.construct(&(new_values[jd]), values[jd]); + allocator.destroy(&(values[jd])); + } + } + if (capacity != 0) allocator.deallocate(values, capacity); + values = new_values; + capacity = new_capacity; + } + allocator.construct(&(values[id]), Value()); + } + + // \brief Adds more new keys to the map. + // + // It adds more new keys to the map. It is called by the observer notifier + // and it overrides the add() member function of the observer base. + virtual void add(const std::vector& keys) { + Notifier* nf = Parent::notifier(); + int max_id = -1; + for (int i = 0; i < int(keys.size()); ++i) { + int id = nf->id(keys[i]); + if (id > max_id) { + max_id = id; + } + } + if (max_id >= capacity) { + int new_capacity = (capacity == 0 ? 1 : capacity); + while (new_capacity <= max_id) { + new_capacity <<= 1; + } + Value* new_values = allocator.allocate(new_capacity); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + int id = nf->id(it); + bool found = false; + for (int i = 0; i < int(keys.size()); ++i) { + int jd = nf->id(keys[i]); + if (id == jd) { + found = true; + break; + } + } + if (found) continue; + allocator.construct(&(new_values[id]), values[id]); + allocator.destroy(&(values[id])); + } + if (capacity != 0) allocator.deallocate(values, capacity); + values = new_values; + capacity = new_capacity; + } + for (int i = 0; i < int(keys.size()); ++i) { + int id = nf->id(keys[i]); + allocator.construct(&(values[id]), Value()); + } + } + + // \brief Erase a key from the map. + // + // Erase a key from the map. It is called by the observer notifier + // and it overrides the erase() member function of the observer base. + virtual void erase(const Key& key) { + int id = Parent::notifier()->id(key); + allocator.destroy(&(values[id])); + } + + // \brief Erase more keys from the map. + // + // Erase more keys from the map. It is called by the observer notifier + // and it overrides the erase() member function of the observer base. + virtual void erase(const std::vector& keys) { + for (int i = 0; i < int(keys.size()); ++i) { + int id = Parent::notifier()->id(keys[i]); + allocator.destroy(&(values[id])); + } + } + + // \brief Builds the map. + // + // It builds the map. It is called by the observer notifier + // and it overrides the build() member function of the observer base. + virtual void build() { + Notifier* nf = Parent::notifier(); + allocate_memory(); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + int id = nf->id(it);; + allocator.construct(&(values[id]), Value()); + } + } + + // \brief Clear the map. + // + // It erase all items from the map. It is called by the observer notifier + // and it overrides the clear() member function of the observer base. + virtual void clear() { + Notifier* nf = Parent::notifier(); + if (capacity != 0) { + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + int id = nf->id(it); + allocator.destroy(&(values[id])); + } + allocator.deallocate(values, capacity); + capacity = 0; + } + } + + private: + + void allocate_memory() { + int max_id = Parent::notifier()->maxId(); + if (max_id == -1) { + capacity = 0; + values = 0; + return; + } + capacity = 1; + while (capacity <= max_id) { + capacity <<= 1; + } + values = allocator.allocate(capacity); + } + + int capacity; + Value* values; + Allocator allocator; + + }; + +} + +#endif diff --git a/lemon/lemon/bits/bezier.h b/lemon/lemon/bits/bezier.h new file mode 100644 index 0000000..cdec206 --- /dev/null +++ b/lemon/lemon/bits/bezier.h @@ -0,0 +1,174 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BEZIER_H +#define LEMON_BEZIER_H + +//\ingroup misc +//\file +//\brief Classes to compute with Bezier curves. +// +//Up to now this file is used internally by \ref graph_to_eps.h + +#include + +namespace lemon { + namespace dim2 { + +class BezierBase { +public: + typedef lemon::dim2::Point Point; +protected: + static Point conv(Point x,Point y,double t) {return (1-t)*x+t*y;} +}; + +class Bezier1 : public BezierBase +{ +public: + Point p1,p2; + + Bezier1() {} + Bezier1(Point _p1, Point _p2) :p1(_p1), p2(_p2) {} + + Point operator()(double t) const + { + // return conv(conv(p1,p2,t),conv(p2,p3,t),t); + return conv(p1,p2,t); + } + Bezier1 before(double t) const + { + return Bezier1(p1,conv(p1,p2,t)); + } + + Bezier1 after(double t) const + { + return Bezier1(conv(p1,p2,t),p2); + } + + Bezier1 revert() const { return Bezier1(p2,p1);} + Bezier1 operator()(double a,double b) const { return before(b).after(a/b); } + Point grad() const { return p2-p1; } + Point norm() const { return rot90(p2-p1); } + Point grad(double) const { return grad(); } + Point norm(double t) const { return rot90(grad(t)); } +}; + +class Bezier2 : public BezierBase +{ +public: + Point p1,p2,p3; + + Bezier2() {} + Bezier2(Point _p1, Point _p2, Point _p3) :p1(_p1), p2(_p2), p3(_p3) {} + Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {} + Point operator()(double t) const + { + // return conv(conv(p1,p2,t),conv(p2,p3,t),t); + return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3; + } + Bezier2 before(double t) const + { + Point q(conv(p1,p2,t)); + Point r(conv(p2,p3,t)); + return Bezier2(p1,q,conv(q,r,t)); + } + + Bezier2 after(double t) const + { + Point q(conv(p1,p2,t)); + Point r(conv(p2,p3,t)); + return Bezier2(conv(q,r,t),r,p3); + } + Bezier2 revert() const { return Bezier2(p3,p2,p1);} + Bezier2 operator()(double a,double b) const { return before(b).after(a/b); } + Bezier1 grad() const { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); } + Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); } + Point grad(double t) const { return grad()(t); } + Point norm(double t) const { return rot90(grad(t)); } +}; + +class Bezier3 : public BezierBase +{ +public: + Point p1,p2,p3,p4; + + Bezier3() {} + Bezier3(Point _p1, Point _p2, Point _p3, Point _p4) + : p1(_p1), p2(_p2), p3(_p3), p4(_p4) {} + Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)), + p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {} + Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)), + p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {} + + Point operator()(double t) const + { + // return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t); + return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+ + (3*t*t*(1-t))*p3+(t*t*t)*p4; + } + Bezier3 before(double t) const + { + Point p(conv(p1,p2,t)); + Point q(conv(p2,p3,t)); + Point r(conv(p3,p4,t)); + Point a(conv(p,q,t)); + Point b(conv(q,r,t)); + Point c(conv(a,b,t)); + return Bezier3(p1,p,a,c); + } + + Bezier3 after(double t) const + { + Point p(conv(p1,p2,t)); + Point q(conv(p2,p3,t)); + Point r(conv(p3,p4,t)); + Point a(conv(p,q,t)); + Point b(conv(q,r,t)); + Point c(conv(a,b,t)); + return Bezier3(c,b,r,p4); + } + Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);} + Bezier3 operator()(double a,double b) const { return before(b).after(a/b); } + Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); } + Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1), + 3.0*rot90(p3-p2), + 3.0*rot90(p4-p3)); } + Point grad(double t) const { return grad()(t); } + Point norm(double t) const { return rot90(grad(t)); } + + template + R recSplit(F &_f,const S &_s,D _d) const + { + const Point a=(p1+p2)/2; + const Point b=(p2+p3)/2; + const Point c=(p3+p4)/2; + const Point d=(a+b)/2; + const Point e=(b+c)/2; + const Point f=(d+e)/2; + R f1=_f(Bezier3(p1,a,d,e),_d); + R f2=_f(Bezier3(e,d,c,p4),_d); + return _s(f1,f2); + } + +}; + + +} //END OF NAMESPACE dim2 +} //END OF NAMESPACE lemon + +#endif // LEMON_BEZIER_H diff --git a/lemon/lemon/bits/default_map.h b/lemon/lemon/bits/default_map.h new file mode 100644 index 0000000..5ac4eea --- /dev/null +++ b/lemon/lemon/bits/default_map.h @@ -0,0 +1,182 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_DEFAULT_MAP_H +#define LEMON_BITS_DEFAULT_MAP_H + +#include +#include +#include +//#include + +//\ingroup graphbits +//\file +//\brief Graph maps that construct and destruct their elements dynamically. + +namespace lemon { + + + //#ifndef LEMON_USE_DEBUG_MAP + + template + struct DefaultMapSelector { + typedef ArrayMap<_Graph, _Item, _Value> Map; + }; + + // bool + template + struct DefaultMapSelector<_Graph, _Item, bool> { + typedef VectorMap<_Graph, _Item, bool> Map; + }; + + // char + template + struct DefaultMapSelector<_Graph, _Item, char> { + typedef VectorMap<_Graph, _Item, char> Map; + }; + + template + struct DefaultMapSelector<_Graph, _Item, signed char> { + typedef VectorMap<_Graph, _Item, signed char> Map; + }; + + template + struct DefaultMapSelector<_Graph, _Item, unsigned char> { + typedef VectorMap<_Graph, _Item, unsigned char> Map; + }; + + + // int + template + struct DefaultMapSelector<_Graph, _Item, signed int> { + typedef VectorMap<_Graph, _Item, signed int> Map; + }; + + template + struct DefaultMapSelector<_Graph, _Item, unsigned int> { + typedef VectorMap<_Graph, _Item, unsigned int> Map; + }; + + + // short + template + struct DefaultMapSelector<_Graph, _Item, signed short> { + typedef VectorMap<_Graph, _Item, signed short> Map; + }; + + template + struct DefaultMapSelector<_Graph, _Item, unsigned short> { + typedef VectorMap<_Graph, _Item, unsigned short> Map; + }; + + + // long + template + struct DefaultMapSelector<_Graph, _Item, signed long> { + typedef VectorMap<_Graph, _Item, signed long> Map; + }; + + template + struct DefaultMapSelector<_Graph, _Item, unsigned long> { + typedef VectorMap<_Graph, _Item, unsigned long> Map; + }; + + +#if defined LEMON_HAVE_LONG_LONG + + // long long + template + struct DefaultMapSelector<_Graph, _Item, signed long long> { + typedef VectorMap<_Graph, _Item, signed long long> Map; + }; + + template + struct DefaultMapSelector<_Graph, _Item, unsigned long long> { + typedef VectorMap<_Graph, _Item, unsigned long long> Map; + }; + +#endif + + + // float + template + struct DefaultMapSelector<_Graph, _Item, float> { + typedef VectorMap<_Graph, _Item, float> Map; + }; + + + // double + template + struct DefaultMapSelector<_Graph, _Item, double> { + typedef VectorMap<_Graph, _Item, double> Map; + }; + + + // long double + template + struct DefaultMapSelector<_Graph, _Item, long double> { + typedef VectorMap<_Graph, _Item, long double> Map; + }; + + + // pointer + template + struct DefaultMapSelector<_Graph, _Item, _Ptr*> { + typedef VectorMap<_Graph, _Item, _Ptr*> Map; + }; + +// #else + +// template +// struct DefaultMapSelector { +// typedef DebugMap<_Graph, _Item, _Value> Map; +// }; + +// #endif + + // DefaultMap class + template + class DefaultMap + : public DefaultMapSelector<_Graph, _Item, _Value>::Map { + typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent; + + public: + typedef DefaultMap<_Graph, _Item, _Value> Map; + + typedef typename Parent::GraphType GraphType; + typedef typename Parent::Value Value; + + explicit DefaultMap(const GraphType& graph) : Parent(graph) {} + DefaultMap(const GraphType& graph, const Value& value) + : Parent(graph, value) {} + + DefaultMap& operator=(const DefaultMap& cmap) { + return operator=(cmap); + } + + template + DefaultMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + +} + +#endif diff --git a/lemon/lemon/bits/edge_set_extender.h b/lemon/lemon/bits/edge_set_extender.h new file mode 100644 index 0000000..3998943 --- /dev/null +++ b/lemon/lemon/bits/edge_set_extender.h @@ -0,0 +1,627 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_EDGE_SET_EXTENDER_H +#define LEMON_BITS_EDGE_SET_EXTENDER_H + +#include +#include +#include +#include + +//\ingroup digraphbits +//\file +//\brief Extenders for the arc set types +namespace lemon { + + // \ingroup digraphbits + // + // \brief Extender for the ArcSets + template + class ArcSetExtender : public Base { + typedef Base Parent; + + public: + + typedef ArcSetExtender Digraph; + + // Base extensions + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + int maxId(Node) const { + return Parent::maxNodeId(); + } + + int maxId(Arc) const { + return Parent::maxArcId(); + } + + Node fromId(int id, Node) const { + return Parent::nodeFromId(id); + } + + Arc fromId(int id, Arc) const { + return Parent::arcFromId(id); + } + + Node oppositeNode(const Node &n, const Arc &e) const { + if (n == Parent::source(e)) + return Parent::target(e); + else if(n==Parent::target(e)) + return Parent::source(e); + else + return INVALID; + } + + + // Alteration notifier extensions + + // The arc observer registry. + typedef AlterationNotifier ArcNotifier; + + protected: + + mutable ArcNotifier arc_notifier; + + public: + + using Parent::notifier; + + // Gives back the arc alteration notifier. + ArcNotifier& notifier(Arc) const { + return arc_notifier; + } + + // Iterable extensions + + class NodeIt : public Node { + const Digraph* digraph; + public: + + NodeIt() {} + + NodeIt(Invalid i) : Node(i) { } + + explicit NodeIt(const Digraph& _graph) : digraph(&_graph) { + _graph.first(static_cast(*this)); + } + + NodeIt(const Digraph& _graph, const Node& node) + : Node(node), digraph(&_graph) {} + + NodeIt& operator++() { + digraph->next(*this); + return *this; + } + + }; + + + class ArcIt : public Arc { + const Digraph* digraph; + public: + + ArcIt() { } + + ArcIt(Invalid i) : Arc(i) { } + + explicit ArcIt(const Digraph& _graph) : digraph(&_graph) { + _graph.first(static_cast(*this)); + } + + ArcIt(const Digraph& _graph, const Arc& e) : + Arc(e), digraph(&_graph) { } + + ArcIt& operator++() { + digraph->next(*this); + return *this; + } + + }; + + + class OutArcIt : public Arc { + const Digraph* digraph; + public: + + OutArcIt() { } + + OutArcIt(Invalid i) : Arc(i) { } + + OutArcIt(const Digraph& _graph, const Node& node) + : digraph(&_graph) { + _graph.firstOut(*this, node); + } + + OutArcIt(const Digraph& _graph, const Arc& arc) + : Arc(arc), digraph(&_graph) {} + + OutArcIt& operator++() { + digraph->nextOut(*this); + return *this; + } + + }; + + + class InArcIt : public Arc { + const Digraph* digraph; + public: + + InArcIt() { } + + InArcIt(Invalid i) : Arc(i) { } + + InArcIt(const Digraph& _graph, const Node& node) + : digraph(&_graph) { + _graph.firstIn(*this, node); + } + + InArcIt(const Digraph& _graph, const Arc& arc) : + Arc(arc), digraph(&_graph) {} + + InArcIt& operator++() { + digraph->nextIn(*this); + return *this; + } + + }; + + // \brief Base node of the iterator + // + // Returns the base node (ie. the source in this case) of the iterator + Node baseNode(const OutArcIt &e) const { + return Parent::source(static_cast(e)); + } + // \brief Running node of the iterator + // + // Returns the running node (ie. the target in this case) of the + // iterator + Node runningNode(const OutArcIt &e) const { + return Parent::target(static_cast(e)); + } + + // \brief Base node of the iterator + // + // Returns the base node (ie. the target in this case) of the iterator + Node baseNode(const InArcIt &e) const { + return Parent::target(static_cast(e)); + } + // \brief Running node of the iterator + // + // Returns the running node (ie. the source in this case) of the + // iterator + Node runningNode(const InArcIt &e) const { + return Parent::source(static_cast(e)); + } + + using Parent::first; + + // Mappable extension + + template + class ArcMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit ArcMap(const Digraph& _g) + : Parent(_g) {} + ArcMap(const Digraph& _g, const _Value& _v) + : Parent(_g, _v) {} + + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + + // Alteration extension + + Arc addArc(const Node& from, const Node& to) { + Arc arc = Parent::addArc(from, to); + notifier(Arc()).add(arc); + return arc; + } + + void clear() { + notifier(Arc()).clear(); + Parent::clear(); + } + + void erase(const Arc& arc) { + notifier(Arc()).erase(arc); + Parent::erase(arc); + } + + ArcSetExtender() { + arc_notifier.setContainer(*this); + } + + ~ArcSetExtender() { + arc_notifier.clear(); + } + + }; + + + // \ingroup digraphbits + // + // \brief Extender for the EdgeSets + template + class EdgeSetExtender : public Base { + typedef Base Parent; + + public: + + typedef EdgeSetExtender Graph; + + typedef True UndirectedTag; + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + typedef typename Parent::Edge Edge; + + int maxId(Node) const { + return Parent::maxNodeId(); + } + + int maxId(Arc) const { + return Parent::maxArcId(); + } + + int maxId(Edge) const { + return Parent::maxEdgeId(); + } + + Node fromId(int id, Node) const { + return Parent::nodeFromId(id); + } + + Arc fromId(int id, Arc) const { + return Parent::arcFromId(id); + } + + Edge fromId(int id, Edge) const { + return Parent::edgeFromId(id); + } + + Node oppositeNode(const Node &n, const Edge &e) const { + if( n == Parent::u(e)) + return Parent::v(e); + else if( n == Parent::v(e)) + return Parent::u(e); + else + return INVALID; + } + + Arc oppositeArc(const Arc &e) const { + return Parent::direct(e, !Parent::direction(e)); + } + + using Parent::direct; + Arc direct(const Edge &e, const Node &s) const { + return Parent::direct(e, Parent::u(e) == s); + } + + typedef AlterationNotifier ArcNotifier; + typedef AlterationNotifier EdgeNotifier; + + + protected: + + mutable ArcNotifier arc_notifier; + mutable EdgeNotifier edge_notifier; + + public: + + using Parent::notifier; + + ArcNotifier& notifier(Arc) const { + return arc_notifier; + } + + EdgeNotifier& notifier(Edge) const { + return edge_notifier; + } + + + class NodeIt : public Node { + const Graph* graph; + public: + + NodeIt() {} + + NodeIt(Invalid i) : Node(i) { } + + explicit NodeIt(const Graph& _graph) : graph(&_graph) { + _graph.first(static_cast(*this)); + } + + NodeIt(const Graph& _graph, const Node& node) + : Node(node), graph(&_graph) {} + + NodeIt& operator++() { + graph->next(*this); + return *this; + } + + }; + + + class ArcIt : public Arc { + const Graph* graph; + public: + + ArcIt() { } + + ArcIt(Invalid i) : Arc(i) { } + + explicit ArcIt(const Graph& _graph) : graph(&_graph) { + _graph.first(static_cast(*this)); + } + + ArcIt(const Graph& _graph, const Arc& e) : + Arc(e), graph(&_graph) { } + + ArcIt& operator++() { + graph->next(*this); + return *this; + } + + }; + + + class OutArcIt : public Arc { + const Graph* graph; + public: + + OutArcIt() { } + + OutArcIt(Invalid i) : Arc(i) { } + + OutArcIt(const Graph& _graph, const Node& node) + : graph(&_graph) { + _graph.firstOut(*this, node); + } + + OutArcIt(const Graph& _graph, const Arc& arc) + : Arc(arc), graph(&_graph) {} + + OutArcIt& operator++() { + graph->nextOut(*this); + return *this; + } + + }; + + + class InArcIt : public Arc { + const Graph* graph; + public: + + InArcIt() { } + + InArcIt(Invalid i) : Arc(i) { } + + InArcIt(const Graph& _graph, const Node& node) + : graph(&_graph) { + _graph.firstIn(*this, node); + } + + InArcIt(const Graph& _graph, const Arc& arc) : + Arc(arc), graph(&_graph) {} + + InArcIt& operator++() { + graph->nextIn(*this); + return *this; + } + + }; + + + class EdgeIt : public Parent::Edge { + const Graph* graph; + public: + + EdgeIt() { } + + EdgeIt(Invalid i) : Edge(i) { } + + explicit EdgeIt(const Graph& _graph) : graph(&_graph) { + _graph.first(static_cast(*this)); + } + + EdgeIt(const Graph& _graph, const Edge& e) : + Edge(e), graph(&_graph) { } + + EdgeIt& operator++() { + graph->next(*this); + return *this; + } + + }; + + class IncEdgeIt : public Parent::Edge { + friend class EdgeSetExtender; + const Graph* graph; + bool direction; + public: + + IncEdgeIt() { } + + IncEdgeIt(Invalid i) : Edge(i), direction(false) { } + + IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { + _graph.firstInc(*this, direction, n); + } + + IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n) + : graph(&_graph), Edge(ue) { + direction = (_graph.source(ue) == n); + } + + IncEdgeIt& operator++() { + graph->nextInc(*this, direction); + return *this; + } + }; + + // \brief Base node of the iterator + // + // Returns the base node (ie. the source in this case) of the iterator + Node baseNode(const OutArcIt &e) const { + return Parent::source(static_cast(e)); + } + // \brief Running node of the iterator + // + // Returns the running node (ie. the target in this case) of the + // iterator + Node runningNode(const OutArcIt &e) const { + return Parent::target(static_cast(e)); + } + + // \brief Base node of the iterator + // + // Returns the base node (ie. the target in this case) of the iterator + Node baseNode(const InArcIt &e) const { + return Parent::target(static_cast(e)); + } + // \brief Running node of the iterator + // + // Returns the running node (ie. the source in this case) of the + // iterator + Node runningNode(const InArcIt &e) const { + return Parent::source(static_cast(e)); + } + + // Base node of the iterator + // + // Returns the base node of the iterator + Node baseNode(const IncEdgeIt &e) const { + return e.direction ? u(e) : v(e); + } + // Running node of the iterator + // + // Returns the running node of the iterator + Node runningNode(const IncEdgeIt &e) const { + return e.direction ? v(e) : u(e); + } + + + template + class ArcMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit ArcMap(const Graph& _g) + : Parent(_g) {} + ArcMap(const Graph& _g, const _Value& _v) + : Parent(_g, _v) {} + + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + + template + class EdgeMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit EdgeMap(const Graph& _g) + : Parent(_g) {} + + EdgeMap(const Graph& _g, const _Value& _v) + : Parent(_g, _v) {} + + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + + // Alteration extension + + Edge addEdge(const Node& from, const Node& to) { + Edge edge = Parent::addEdge(from, to); + notifier(Edge()).add(edge); + std::vector arcs; + arcs.push_back(Parent::direct(edge, true)); + arcs.push_back(Parent::direct(edge, false)); + notifier(Arc()).add(arcs); + return edge; + } + + void clear() { + notifier(Arc()).clear(); + notifier(Edge()).clear(); + Parent::clear(); + } + + void erase(const Edge& edge) { + std::vector arcs; + arcs.push_back(Parent::direct(edge, true)); + arcs.push_back(Parent::direct(edge, false)); + notifier(Arc()).erase(arcs); + notifier(Edge()).erase(edge); + Parent::erase(edge); + } + + + EdgeSetExtender() { + arc_notifier.setContainer(*this); + edge_notifier.setContainer(*this); + } + + ~EdgeSetExtender() { + edge_notifier.clear(); + arc_notifier.clear(); + } + + }; + +} + +#endif diff --git a/lemon/lemon/bits/enable_if.h b/lemon/lemon/bits/enable_if.h new file mode 100644 index 0000000..f0d8de4 --- /dev/null +++ b/lemon/lemon/bits/enable_if.h @@ -0,0 +1,131 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +// This file contains a modified version of the enable_if library from BOOST. +// See the appropriate copyright notice below. + +// Boost enable_if library + +// Copyright 2003 (c) The Trustees of Indiana University. + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) +// Jeremiah Willcock (jewillco at osl.iu.edu) +// Andrew Lumsdaine (lums at osl.iu.edu) + + +#ifndef LEMON_BITS_ENABLE_IF_H +#define LEMON_BITS_ENABLE_IF_H + +//\file +//\brief Miscellaneous basic utilities + +namespace lemon +{ + + // Basic type for defining "tags". A "YES" condition for \c enable_if. + + // Basic type for defining "tags". A "YES" condition for \c enable_if. + // + //\sa False + struct True { + //\e + static const bool value = true; + }; + + // Basic type for defining "tags". A "NO" condition for \c enable_if. + + // Basic type for defining "tags". A "NO" condition for \c enable_if. + // + //\sa True + struct False { + //\e + static const bool value = false; + }; + + + + template + struct Wrap { + const T &value; + Wrap(const T &t) : value(t) {} + }; + + /**************** dummy class to avoid ambiguity ****************/ + + template struct dummy { dummy(int) {} }; + + /**************** enable_if from BOOST ****************/ + + template + struct exists { + typedef T type; + }; + + + template + struct enable_if_c { + typedef T type; + }; + + template + struct enable_if_c {}; + + template + struct enable_if : public enable_if_c {}; + + template + struct lazy_enable_if_c { + typedef typename T::type type; + }; + + template + struct lazy_enable_if_c {}; + + template + struct lazy_enable_if : public lazy_enable_if_c {}; + + + template + struct disable_if_c { + typedef T type; + }; + + template + struct disable_if_c {}; + + template + struct disable_if : public disable_if_c {}; + + template + struct lazy_disable_if_c { + typedef typename T::type type; + }; + + template + struct lazy_disable_if_c {}; + + template + struct lazy_disable_if : public lazy_disable_if_c {}; + +} // namespace lemon + +#endif diff --git a/lemon/lemon/bits/graph_adaptor_extender.h b/lemon/lemon/bits/graph_adaptor_extender.h new file mode 100644 index 0000000..f8c952a --- /dev/null +++ b/lemon/lemon/bits/graph_adaptor_extender.h @@ -0,0 +1,401 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H +#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H + +#include +#include + +namespace lemon { + + template + class DigraphAdaptorExtender : public _Digraph { + typedef _Digraph Parent; + + public: + + typedef _Digraph Digraph; + typedef DigraphAdaptorExtender Adaptor; + + // Base extensions + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + int maxId(Node) const { + return Parent::maxNodeId(); + } + + int maxId(Arc) const { + return Parent::maxArcId(); + } + + Node fromId(int id, Node) const { + return Parent::nodeFromId(id); + } + + Arc fromId(int id, Arc) const { + return Parent::arcFromId(id); + } + + Node oppositeNode(const Node &n, const Arc &e) const { + if (n == Parent::source(e)) + return Parent::target(e); + else if(n==Parent::target(e)) + return Parent::source(e); + else + return INVALID; + } + + class NodeIt : public Node { + const Adaptor* _adaptor; + public: + + NodeIt() {} + + NodeIt(Invalid i) : Node(i) { } + + explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) { + _adaptor->first(static_cast(*this)); + } + + NodeIt(const Adaptor& adaptor, const Node& node) + : Node(node), _adaptor(&adaptor) {} + + NodeIt& operator++() { + _adaptor->next(*this); + return *this; + } + + }; + + + class ArcIt : public Arc { + const Adaptor* _adaptor; + public: + + ArcIt() { } + + ArcIt(Invalid i) : Arc(i) { } + + explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) { + _adaptor->first(static_cast(*this)); + } + + ArcIt(const Adaptor& adaptor, const Arc& e) : + Arc(e), _adaptor(&adaptor) { } + + ArcIt& operator++() { + _adaptor->next(*this); + return *this; + } + + }; + + + class OutArcIt : public Arc { + const Adaptor* _adaptor; + public: + + OutArcIt() { } + + OutArcIt(Invalid i) : Arc(i) { } + + OutArcIt(const Adaptor& adaptor, const Node& node) + : _adaptor(&adaptor) { + _adaptor->firstOut(*this, node); + } + + OutArcIt(const Adaptor& adaptor, const Arc& arc) + : Arc(arc), _adaptor(&adaptor) {} + + OutArcIt& operator++() { + _adaptor->nextOut(*this); + return *this; + } + + }; + + + class InArcIt : public Arc { + const Adaptor* _adaptor; + public: + + InArcIt() { } + + InArcIt(Invalid i) : Arc(i) { } + + InArcIt(const Adaptor& adaptor, const Node& node) + : _adaptor(&adaptor) { + _adaptor->firstIn(*this, node); + } + + InArcIt(const Adaptor& adaptor, const Arc& arc) : + Arc(arc), _adaptor(&adaptor) {} + + InArcIt& operator++() { + _adaptor->nextIn(*this); + return *this; + } + + }; + + Node baseNode(const OutArcIt &e) const { + return Parent::source(e); + } + Node runningNode(const OutArcIt &e) const { + return Parent::target(e); + } + + Node baseNode(const InArcIt &e) const { + return Parent::target(e); + } + Node runningNode(const InArcIt &e) const { + return Parent::source(e); + } + + }; + + template + class GraphAdaptorExtender : public _Graph { + typedef _Graph Parent; + + public: + + typedef _Graph Graph; + typedef GraphAdaptorExtender Adaptor; + + typedef True UndirectedTag; + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + typedef typename Parent::Edge Edge; + + // Graph extension + + int maxId(Node) const { + return Parent::maxNodeId(); + } + + int maxId(Arc) const { + return Parent::maxArcId(); + } + + int maxId(Edge) const { + return Parent::maxEdgeId(); + } + + Node fromId(int id, Node) const { + return Parent::nodeFromId(id); + } + + Arc fromId(int id, Arc) const { + return Parent::arcFromId(id); + } + + Edge fromId(int id, Edge) const { + return Parent::edgeFromId(id); + } + + Node oppositeNode(const Node &n, const Edge &e) const { + if( n == Parent::u(e)) + return Parent::v(e); + else if( n == Parent::v(e)) + return Parent::u(e); + else + return INVALID; + } + + Arc oppositeArc(const Arc &a) const { + return Parent::direct(a, !Parent::direction(a)); + } + + using Parent::direct; + Arc direct(const Edge &e, const Node &s) const { + return Parent::direct(e, Parent::u(e) == s); + } + + + class NodeIt : public Node { + const Adaptor* _adaptor; + public: + + NodeIt() {} + + NodeIt(Invalid i) : Node(i) { } + + explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) { + _adaptor->first(static_cast(*this)); + } + + NodeIt(const Adaptor& adaptor, const Node& node) + : Node(node), _adaptor(&adaptor) {} + + NodeIt& operator++() { + _adaptor->next(*this); + return *this; + } + + }; + + + class ArcIt : public Arc { + const Adaptor* _adaptor; + public: + + ArcIt() { } + + ArcIt(Invalid i) : Arc(i) { } + + explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) { + _adaptor->first(static_cast(*this)); + } + + ArcIt(const Adaptor& adaptor, const Arc& e) : + Arc(e), _adaptor(&adaptor) { } + + ArcIt& operator++() { + _adaptor->next(*this); + return *this; + } + + }; + + + class OutArcIt : public Arc { + const Adaptor* _adaptor; + public: + + OutArcIt() { } + + OutArcIt(Invalid i) : Arc(i) { } + + OutArcIt(const Adaptor& adaptor, const Node& node) + : _adaptor(&adaptor) { + _adaptor->firstOut(*this, node); + } + + OutArcIt(const Adaptor& adaptor, const Arc& arc) + : Arc(arc), _adaptor(&adaptor) {} + + OutArcIt& operator++() { + _adaptor->nextOut(*this); + return *this; + } + + }; + + + class InArcIt : public Arc { + const Adaptor* _adaptor; + public: + + InArcIt() { } + + InArcIt(Invalid i) : Arc(i) { } + + InArcIt(const Adaptor& adaptor, const Node& node) + : _adaptor(&adaptor) { + _adaptor->firstIn(*this, node); + } + + InArcIt(const Adaptor& adaptor, const Arc& arc) : + Arc(arc), _adaptor(&adaptor) {} + + InArcIt& operator++() { + _adaptor->nextIn(*this); + return *this; + } + + }; + + class EdgeIt : public Parent::Edge { + const Adaptor* _adaptor; + public: + + EdgeIt() { } + + EdgeIt(Invalid i) : Edge(i) { } + + explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) { + _adaptor->first(static_cast(*this)); + } + + EdgeIt(const Adaptor& adaptor, const Edge& e) : + Edge(e), _adaptor(&adaptor) { } + + EdgeIt& operator++() { + _adaptor->next(*this); + return *this; + } + + }; + + class IncEdgeIt : public Edge { + friend class GraphAdaptorExtender; + const Adaptor* _adaptor; + bool direction; + public: + + IncEdgeIt() { } + + IncEdgeIt(Invalid i) : Edge(i), direction(false) { } + + IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) { + _adaptor->firstInc(static_cast(*this), direction, n); + } + + IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n) + : _adaptor(&adaptor), Edge(e) { + direction = (_adaptor->u(e) == n); + } + + IncEdgeIt& operator++() { + _adaptor->nextInc(*this, direction); + return *this; + } + }; + + Node baseNode(const OutArcIt &a) const { + return Parent::source(a); + } + Node runningNode(const OutArcIt &a) const { + return Parent::target(a); + } + + Node baseNode(const InArcIt &a) const { + return Parent::target(a); + } + Node runningNode(const InArcIt &a) const { + return Parent::source(a); + } + + Node baseNode(const IncEdgeIt &e) const { + return e.direction ? Parent::u(e) : Parent::v(e); + } + Node runningNode(const IncEdgeIt &e) const { + return e.direction ? Parent::v(e) : Parent::u(e); + } + + }; + +} + + +#endif diff --git a/lemon/lemon/bits/graph_extender.h b/lemon/lemon/bits/graph_extender.h new file mode 100644 index 0000000..3b89b08 --- /dev/null +++ b/lemon/lemon/bits/graph_extender.h @@ -0,0 +1,751 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_GRAPH_EXTENDER_H +#define LEMON_BITS_GRAPH_EXTENDER_H + +#include + +#include +#include + +#include +#include + +//\ingroup graphbits +//\file +//\brief Extenders for the graph types +namespace lemon { + + // \ingroup graphbits + // + // \brief Extender for the digraph implementations + template + class DigraphExtender : public Base { + typedef Base Parent; + + public: + + typedef DigraphExtender Digraph; + + // Base extensions + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + int maxId(Node) const { + return Parent::maxNodeId(); + } + + int maxId(Arc) const { + return Parent::maxArcId(); + } + + static Node fromId(int id, Node) { + return Parent::nodeFromId(id); + } + + static Arc fromId(int id, Arc) { + return Parent::arcFromId(id); + } + + Node oppositeNode(const Node &node, const Arc &arc) const { + if (node == Parent::source(arc)) + return Parent::target(arc); + else if(node == Parent::target(arc)) + return Parent::source(arc); + else + return INVALID; + } + + // Alterable extension + + typedef AlterationNotifier NodeNotifier; + typedef AlterationNotifier ArcNotifier; + + + protected: + + mutable NodeNotifier node_notifier; + mutable ArcNotifier arc_notifier; + + public: + + NodeNotifier& notifier(Node) const { + return node_notifier; + } + + ArcNotifier& notifier(Arc) const { + return arc_notifier; + } + + class NodeIt : public Node { + const Digraph* _digraph; + public: + + NodeIt() {} + + NodeIt(Invalid i) : Node(i) { } + + explicit NodeIt(const Digraph& digraph) : _digraph(&digraph) { + _digraph->first(static_cast(*this)); + } + + NodeIt(const Digraph& digraph, const Node& node) + : Node(node), _digraph(&digraph) {} + + NodeIt& operator++() { + _digraph->next(*this); + return *this; + } + + }; + + + class ArcIt : public Arc { + const Digraph* _digraph; + public: + + ArcIt() { } + + ArcIt(Invalid i) : Arc(i) { } + + explicit ArcIt(const Digraph& digraph) : _digraph(&digraph) { + _digraph->first(static_cast(*this)); + } + + ArcIt(const Digraph& digraph, const Arc& arc) : + Arc(arc), _digraph(&digraph) { } + + ArcIt& operator++() { + _digraph->next(*this); + return *this; + } + + }; + + + class OutArcIt : public Arc { + const Digraph* _digraph; + public: + + OutArcIt() { } + + OutArcIt(Invalid i) : Arc(i) { } + + OutArcIt(const Digraph& digraph, const Node& node) + : _digraph(&digraph) { + _digraph->firstOut(*this, node); + } + + OutArcIt(const Digraph& digraph, const Arc& arc) + : Arc(arc), _digraph(&digraph) {} + + OutArcIt& operator++() { + _digraph->nextOut(*this); + return *this; + } + + }; + + + class InArcIt : public Arc { + const Digraph* _digraph; + public: + + InArcIt() { } + + InArcIt(Invalid i) : Arc(i) { } + + InArcIt(const Digraph& digraph, const Node& node) + : _digraph(&digraph) { + _digraph->firstIn(*this, node); + } + + InArcIt(const Digraph& digraph, const Arc& arc) : + Arc(arc), _digraph(&digraph) {} + + InArcIt& operator++() { + _digraph->nextIn(*this); + return *this; + } + + }; + + // \brief Base node of the iterator + // + // Returns the base node (i.e. the source in this case) of the iterator + Node baseNode(const OutArcIt &arc) const { + return Parent::source(arc); + } + // \brief Running node of the iterator + // + // Returns the running node (i.e. the target in this case) of the + // iterator + Node runningNode(const OutArcIt &arc) const { + return Parent::target(arc); + } + + // \brief Base node of the iterator + // + // Returns the base node (i.e. the target in this case) of the iterator + Node baseNode(const InArcIt &arc) const { + return Parent::target(arc); + } + // \brief Running node of the iterator + // + // Returns the running node (i.e. the source in this case) of the + // iterator + Node runningNode(const InArcIt &arc) const { + return Parent::source(arc); + } + + + template + class NodeMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit NodeMap(const Digraph& digraph) + : Parent(digraph) {} + NodeMap(const Digraph& digraph, const _Value& value) + : Parent(digraph, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + template + class ArcMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit ArcMap(const Digraph& digraph) + : Parent(digraph) {} + ArcMap(const Digraph& digraph, const _Value& value) + : Parent(digraph, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + + Node addNode() { + Node node = Parent::addNode(); + notifier(Node()).add(node); + return node; + } + + Arc addArc(const Node& from, const Node& to) { + Arc arc = Parent::addArc(from, to); + notifier(Arc()).add(arc); + return arc; + } + + void clear() { + notifier(Arc()).clear(); + notifier(Node()).clear(); + Parent::clear(); + } + + template + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { + Parent::build(digraph, nodeRef, arcRef); + notifier(Node()).build(); + notifier(Arc()).build(); + } + + void erase(const Node& node) { + Arc arc; + Parent::firstOut(arc, node); + while (arc != INVALID ) { + erase(arc); + Parent::firstOut(arc, node); + } + + Parent::firstIn(arc, node); + while (arc != INVALID ) { + erase(arc); + Parent::firstIn(arc, node); + } + + notifier(Node()).erase(node); + Parent::erase(node); + } + + void erase(const Arc& arc) { + notifier(Arc()).erase(arc); + Parent::erase(arc); + } + + DigraphExtender() { + node_notifier.setContainer(*this); + arc_notifier.setContainer(*this); + } + + + ~DigraphExtender() { + arc_notifier.clear(); + node_notifier.clear(); + } + }; + + // \ingroup _graphbits + // + // \brief Extender for the Graphs + template + class GraphExtender : public Base { + typedef Base Parent; + + public: + + typedef GraphExtender Graph; + + typedef True UndirectedTag; + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + typedef typename Parent::Edge Edge; + + // Graph extension + + int maxId(Node) const { + return Parent::maxNodeId(); + } + + int maxId(Arc) const { + return Parent::maxArcId(); + } + + int maxId(Edge) const { + return Parent::maxEdgeId(); + } + + static Node fromId(int id, Node) { + return Parent::nodeFromId(id); + } + + static Arc fromId(int id, Arc) { + return Parent::arcFromId(id); + } + + static Edge fromId(int id, Edge) { + return Parent::edgeFromId(id); + } + + Node oppositeNode(const Node &n, const Edge &e) const { + if( n == Parent::u(e)) + return Parent::v(e); + else if( n == Parent::v(e)) + return Parent::u(e); + else + return INVALID; + } + + Arc oppositeArc(const Arc &arc) const { + return Parent::direct(arc, !Parent::direction(arc)); + } + + using Parent::direct; + Arc direct(const Edge &edge, const Node &node) const { + return Parent::direct(edge, Parent::u(edge) == node); + } + + // Alterable extension + + typedef AlterationNotifier NodeNotifier; + typedef AlterationNotifier ArcNotifier; + typedef AlterationNotifier EdgeNotifier; + + + protected: + + mutable NodeNotifier node_notifier; + mutable ArcNotifier arc_notifier; + mutable EdgeNotifier edge_notifier; + + public: + + NodeNotifier& notifier(Node) const { + return node_notifier; + } + + ArcNotifier& notifier(Arc) const { + return arc_notifier; + } + + EdgeNotifier& notifier(Edge) const { + return edge_notifier; + } + + + + class NodeIt : public Node { + const Graph* _graph; + public: + + NodeIt() {} + + NodeIt(Invalid i) : Node(i) { } + + explicit NodeIt(const Graph& graph) : _graph(&graph) { + _graph->first(static_cast(*this)); + } + + NodeIt(const Graph& graph, const Node& node) + : Node(node), _graph(&graph) {} + + NodeIt& operator++() { + _graph->next(*this); + return *this; + } + + }; + + + class ArcIt : public Arc { + const Graph* _graph; + public: + + ArcIt() { } + + ArcIt(Invalid i) : Arc(i) { } + + explicit ArcIt(const Graph& graph) : _graph(&graph) { + _graph->first(static_cast(*this)); + } + + ArcIt(const Graph& graph, const Arc& arc) : + Arc(arc), _graph(&graph) { } + + ArcIt& operator++() { + _graph->next(*this); + return *this; + } + + }; + + + class OutArcIt : public Arc { + const Graph* _graph; + public: + + OutArcIt() { } + + OutArcIt(Invalid i) : Arc(i) { } + + OutArcIt(const Graph& graph, const Node& node) + : _graph(&graph) { + _graph->firstOut(*this, node); + } + + OutArcIt(const Graph& graph, const Arc& arc) + : Arc(arc), _graph(&graph) {} + + OutArcIt& operator++() { + _graph->nextOut(*this); + return *this; + } + + }; + + + class InArcIt : public Arc { + const Graph* _graph; + public: + + InArcIt() { } + + InArcIt(Invalid i) : Arc(i) { } + + InArcIt(const Graph& graph, const Node& node) + : _graph(&graph) { + _graph->firstIn(*this, node); + } + + InArcIt(const Graph& graph, const Arc& arc) : + Arc(arc), _graph(&graph) {} + + InArcIt& operator++() { + _graph->nextIn(*this); + return *this; + } + + }; + + + class EdgeIt : public Parent::Edge { + const Graph* _graph; + public: + + EdgeIt() { } + + EdgeIt(Invalid i) : Edge(i) { } + + explicit EdgeIt(const Graph& graph) : _graph(&graph) { + _graph->first(static_cast(*this)); + } + + EdgeIt(const Graph& graph, const Edge& edge) : + Edge(edge), _graph(&graph) { } + + EdgeIt& operator++() { + _graph->next(*this); + return *this; + } + + }; + + class IncEdgeIt : public Parent::Edge { + friend class GraphExtender; + const Graph* _graph; + bool _direction; + public: + + IncEdgeIt() { } + + IncEdgeIt(Invalid i) : Edge(i), _direction(false) { } + + IncEdgeIt(const Graph& graph, const Node &node) : _graph(&graph) { + _graph->firstInc(*this, _direction, node); + } + + IncEdgeIt(const Graph& graph, const Edge &edge, const Node &node) + : _graph(&graph), Edge(edge) { + _direction = (_graph->source(edge) == node); + } + + IncEdgeIt& operator++() { + _graph->nextInc(*this, _direction); + return *this; + } + }; + + // \brief Base node of the iterator + // + // Returns the base node (ie. the source in this case) of the iterator + Node baseNode(const OutArcIt &arc) const { + return Parent::source(static_cast(arc)); + } + // \brief Running node of the iterator + // + // Returns the running node (ie. the target in this case) of the + // iterator + Node runningNode(const OutArcIt &arc) const { + return Parent::target(static_cast(arc)); + } + + // \brief Base node of the iterator + // + // Returns the base node (ie. the target in this case) of the iterator + Node baseNode(const InArcIt &arc) const { + return Parent::target(static_cast(arc)); + } + // \brief Running node of the iterator + // + // Returns the running node (ie. the source in this case) of the + // iterator + Node runningNode(const InArcIt &arc) const { + return Parent::source(static_cast(arc)); + } + + // Base node of the iterator + // + // Returns the base node of the iterator + Node baseNode(const IncEdgeIt &edge) const { + return edge._direction ? u(edge) : v(edge); + } + // Running node of the iterator + // + // Returns the running node of the iterator + Node runningNode(const IncEdgeIt &edge) const { + return edge._direction ? v(edge) : u(edge); + } + + // Mappable extension + + template + class NodeMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit NodeMap(const Graph& graph) + : Parent(graph) {} + NodeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} + + private: + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + template + class ArcMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit ArcMap(const Graph& graph) + : Parent(graph) {} + ArcMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} + + private: + ArcMap& operator=(const ArcMap& cmap) { + return operator=(cmap); + } + + template + ArcMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + + template + class EdgeMap + : public MapExtender > { + typedef MapExtender > Parent; + + public: + explicit EdgeMap(const Graph& graph) + : Parent(graph) {} + + EdgeMap(const Graph& graph, const _Value& value) + : Parent(graph, value) {} + + private: + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + }; + + // Alteration extension + + Node addNode() { + Node node = Parent::addNode(); + notifier(Node()).add(node); + return node; + } + + Edge addEdge(const Node& from, const Node& to) { + Edge edge = Parent::addEdge(from, to); + notifier(Edge()).add(edge); + std::vector ev; + ev.push_back(Parent::direct(edge, true)); + ev.push_back(Parent::direct(edge, false)); + notifier(Arc()).add(ev); + return edge; + } + + void clear() { + notifier(Arc()).clear(); + notifier(Edge()).clear(); + notifier(Node()).clear(); + Parent::clear(); + } + + template + void build(const Graph& graph, NodeRefMap& nodeRef, + EdgeRefMap& edgeRef) { + Parent::build(graph, nodeRef, edgeRef); + notifier(Node()).build(); + notifier(Edge()).build(); + notifier(Arc()).build(); + } + + void erase(const Node& node) { + Arc arc; + Parent::firstOut(arc, node); + while (arc != INVALID ) { + erase(arc); + Parent::firstOut(arc, node); + } + + Parent::firstIn(arc, node); + while (arc != INVALID ) { + erase(arc); + Parent::firstIn(arc, node); + } + + notifier(Node()).erase(node); + Parent::erase(node); + } + + void erase(const Edge& edge) { + std::vector av; + av.push_back(Parent::direct(edge, true)); + av.push_back(Parent::direct(edge, false)); + notifier(Arc()).erase(av); + notifier(Edge()).erase(edge); + Parent::erase(edge); + } + + GraphExtender() { + node_notifier.setContainer(*this); + arc_notifier.setContainer(*this); + edge_notifier.setContainer(*this); + } + + ~GraphExtender() { + edge_notifier.clear(); + arc_notifier.clear(); + node_notifier.clear(); + } + + }; + +} + +#endif diff --git a/lemon/lemon/bits/map_extender.h b/lemon/lemon/bits/map_extender.h new file mode 100644 index 0000000..9e3e0c7 --- /dev/null +++ b/lemon/lemon/bits/map_extender.h @@ -0,0 +1,332 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_MAP_EXTENDER_H +#define LEMON_BITS_MAP_EXTENDER_H + +#include + +#include + +#include +#include + +//\file +//\brief Extenders for iterable maps. + +namespace lemon { + + // \ingroup graphbits + // + // \brief Extender for maps + template + class MapExtender : public _Map { + typedef _Map Parent; + typedef typename Parent::GraphType GraphType; + + public: + + typedef MapExtender Map; + typedef typename Parent::Key Item; + + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + typedef typename Parent::Reference Reference; + typedef typename Parent::ConstReference ConstReference; + + typedef typename Parent::ReferenceMapTag ReferenceMapTag; + + class MapIt; + class ConstMapIt; + + friend class MapIt; + friend class ConstMapIt; + + public: + + MapExtender(const GraphType& graph) + : Parent(graph) {} + + MapExtender(const GraphType& graph, const Value& value) + : Parent(graph, value) {} + + private: + MapExtender& operator=(const MapExtender& cmap) { + return operator=(cmap); + } + + template + MapExtender& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + + public: + class MapIt : public Item { + typedef Item Parent; + + public: + + typedef typename Map::Value Value; + + MapIt() : map(NULL) {} + + MapIt(Invalid i) : Parent(i), map(NULL) {} + + explicit MapIt(Map& _map) : map(&_map) { + map->notifier()->first(*this); + } + + MapIt(const Map& _map, const Item& item) + : Parent(item), map(&_map) {} + + MapIt& operator++() { + map->notifier()->next(*this); + return *this; + } + + typename MapTraits::ConstReturnValue operator*() const { + return (*map)[*this]; + } + + typename MapTraits::ReturnValue operator*() { + return (*map)[*this]; + } + + void set(const Value& value) { + map->set(*this, value); + } + + protected: + Map* map; + + }; + + class ConstMapIt : public Item { + typedef Item Parent; + + public: + + typedef typename Map::Value Value; + + ConstMapIt() : map(NULL) {} + + ConstMapIt(Invalid i) : Parent(i), map(NULL) {} + + explicit ConstMapIt(Map& _map) : map(&_map) { + map->notifier()->first(*this); + } + + ConstMapIt(const Map& _map, const Item& item) + : Parent(item), map(_map) {} + + ConstMapIt& operator++() { + map->notifier()->next(*this); + return *this; + } + + typename MapTraits::ConstReturnValue operator*() const { + return map[*this]; + } + + protected: + const Map* map; + }; + + class ItemIt : public Item { + typedef Item Parent; + + public: + ItemIt() : map(NULL) {} + + + ItemIt(Invalid i) : Parent(i), map(NULL) {} + + explicit ItemIt(Map& _map) : map(&_map) { + map->notifier()->first(*this); + } + + ItemIt(const Map& _map, const Item& item) + : Parent(item), map(&_map) {} + + ItemIt& operator++() { + map->notifier()->next(*this); + return *this; + } + + protected: + const Map* map; + + }; + }; + + // \ingroup graphbits + // + // \brief Extender for maps which use a subset of the items. + template + class SubMapExtender : public _Map { + typedef _Map Parent; + typedef _Graph GraphType; + + public: + + typedef SubMapExtender Map; + typedef typename Parent::Key Item; + + typedef typename Parent::Key Key; + typedef typename Parent::Value Value; + typedef typename Parent::Reference Reference; + typedef typename Parent::ConstReference ConstReference; + + typedef typename Parent::ReferenceMapTag ReferenceMapTag; + + class MapIt; + class ConstMapIt; + + friend class MapIt; + friend class ConstMapIt; + + public: + + SubMapExtender(const GraphType& _graph) + : Parent(_graph), graph(_graph) {} + + SubMapExtender(const GraphType& _graph, const Value& _value) + : Parent(_graph, _value), graph(_graph) {} + + private: + SubMapExtender& operator=(const SubMapExtender& cmap) { + return operator=(cmap); + } + + template + SubMapExtender& operator=(const CMap& cmap) { + checkConcept, CMap>(); + Item it; + for (graph.first(it); it != INVALID; graph.next(it)) { + Parent::set(it, cmap[it]); + } + return *this; + } + + public: + class MapIt : public Item { + typedef Item Parent; + + public: + typedef typename Map::Value Value; + + MapIt() : map(NULL) {} + + MapIt(Invalid i) : Parent(i), map(NULL) { } + + explicit MapIt(Map& _map) : map(&_map) { + map->graph.first(*this); + } + + MapIt(const Map& _map, const Item& item) + : Parent(item), map(&_map) {} + + MapIt& operator++() { + map->graph.next(*this); + return *this; + } + + typename MapTraits::ConstReturnValue operator*() const { + return (*map)[*this]; + } + + typename MapTraits::ReturnValue operator*() { + return (*map)[*this]; + } + + void set(const Value& value) { + map->set(*this, value); + } + + protected: + Map* map; + + }; + + class ConstMapIt : public Item { + typedef Item Parent; + + public: + + typedef typename Map::Value Value; + + ConstMapIt() : map(NULL) {} + + ConstMapIt(Invalid i) : Parent(i), map(NULL) { } + + explicit ConstMapIt(Map& _map) : map(&_map) { + map->graph.first(*this); + } + + ConstMapIt(const Map& _map, const Item& item) + : Parent(item), map(&_map) {} + + ConstMapIt& operator++() { + map->graph.next(*this); + return *this; + } + + typename MapTraits::ConstReturnValue operator*() const { + return (*map)[*this]; + } + + protected: + const Map* map; + }; + + class ItemIt : public Item { + typedef Item Parent; + + public: + ItemIt() : map(NULL) {} + + + ItemIt(Invalid i) : Parent(i), map(NULL) { } + + explicit ItemIt(Map& _map) : map(&_map) { + map->graph.first(*this); + } + + ItemIt(const Map& _map, const Item& item) + : Parent(item), map(&_map) {} + + ItemIt& operator++() { + map->graph.next(*this); + return *this; + } + + protected: + const Map* map; + + }; + + private: + + const GraphType& graph; + + }; + +} + +#endif diff --git a/lemon/lemon/bits/path_dump.h b/lemon/lemon/bits/path_dump.h new file mode 100644 index 0000000..c4efa09 --- /dev/null +++ b/lemon/lemon/bits/path_dump.h @@ -0,0 +1,177 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_PATH_DUMP_H +#define LEMON_BITS_PATH_DUMP_H + +#include +#include + +namespace lemon { + + template + class PredMapPath { + public: + typedef True RevPathTag; + + typedef _Digraph Digraph; + typedef typename Digraph::Arc Arc; + typedef _PredMap PredMap; + + PredMapPath(const Digraph& _digraph, const PredMap& _predMap, + typename Digraph::Node _target) + : digraph(_digraph), predMap(_predMap), target(_target) {} + + int length() const { + int len = 0; + typename Digraph::Node node = target; + typename Digraph::Arc arc; + while ((arc = predMap[node]) != INVALID) { + node = digraph.source(arc); + ++len; + } + return len; + } + + bool empty() const { + return predMap[target] == INVALID; + } + + class RevArcIt { + public: + RevArcIt() {} + RevArcIt(Invalid) : path(0), current(INVALID) {} + RevArcIt(const PredMapPath& _path) + : path(&_path), current(_path.target) { + if (path->predMap[current] == INVALID) current = INVALID; + } + + operator const typename Digraph::Arc() const { + return path->predMap[current]; + } + + RevArcIt& operator++() { + current = path->digraph.source(path->predMap[current]); + if (path->predMap[current] == INVALID) current = INVALID; + return *this; + } + + bool operator==(const RevArcIt& e) const { + return current == e.current; + } + + bool operator!=(const RevArcIt& e) const { + return current != e.current; + } + + bool operator<(const RevArcIt& e) const { + return current < e.current; + } + + private: + const PredMapPath* path; + typename Digraph::Node current; + }; + + private: + const Digraph& digraph; + const PredMap& predMap; + typename Digraph::Node target; + }; + + + template + class PredMatrixMapPath { + public: + typedef True RevPathTag; + + typedef _Digraph Digraph; + typedef typename Digraph::Arc Arc; + typedef _PredMatrixMap PredMatrixMap; + + PredMatrixMapPath(const Digraph& _digraph, + const PredMatrixMap& _predMatrixMap, + typename Digraph::Node _source, + typename Digraph::Node _target) + : digraph(_digraph), predMatrixMap(_predMatrixMap), + source(_source), target(_target) {} + + int length() const { + int len = 0; + typename Digraph::Node node = target; + typename Digraph::Arc arc; + while ((arc = predMatrixMap(source, node)) != INVALID) { + node = digraph.source(arc); + ++len; + } + return len; + } + + bool empty() const { + return predMatrixMap(source, target) == INVALID; + } + + class RevArcIt { + public: + RevArcIt() {} + RevArcIt(Invalid) : path(0), current(INVALID) {} + RevArcIt(const PredMatrixMapPath& _path) + : path(&_path), current(_path.target) { + if (path->predMatrixMap(path->source, current) == INVALID) + current = INVALID; + } + + operator const typename Digraph::Arc() const { + return path->predMatrixMap(path->source, current); + } + + RevArcIt& operator++() { + current = + path->digraph.source(path->predMatrixMap(path->source, current)); + if (path->predMatrixMap(path->source, current) == INVALID) + current = INVALID; + return *this; + } + + bool operator==(const RevArcIt& e) const { + return current == e.current; + } + + bool operator!=(const RevArcIt& e) const { + return current != e.current; + } + + bool operator<(const RevArcIt& e) const { + return current < e.current; + } + + private: + const PredMatrixMapPath* path; + typename Digraph::Node current; + }; + + private: + const Digraph& digraph; + const PredMatrixMap& predMatrixMap; + typename Digraph::Node source; + typename Digraph::Node target; + }; + +} + +#endif diff --git a/lemon/lemon/bits/solver_bits.h b/lemon/lemon/bits/solver_bits.h new file mode 100644 index 0000000..f145ce6 --- /dev/null +++ b/lemon/lemon/bits/solver_bits.h @@ -0,0 +1,193 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_SOLVER_BITS_H +#define LEMON_BITS_SOLVER_BITS_H + +#include + +namespace lemon { + + namespace _solver_bits { + + class VarIndex { + private: + struct ItemT { + int prev, next; + int index; + }; + std::vector items; + int first_item, last_item, first_free_item; + + std::vector cross; + + public: + + VarIndex() + : first_item(-1), last_item(-1), first_free_item(-1) { + } + + void clear() { + first_item = -1; + first_free_item = -1; + items.clear(); + cross.clear(); + } + + int addIndex(int idx) { + int n; + if (first_free_item == -1) { + n = items.size(); + items.push_back(ItemT()); + } else { + n = first_free_item; + first_free_item = items[n].next; + if (first_free_item != -1) { + items[first_free_item].prev = -1; + } + } + items[n].index = idx; + if (static_cast(cross.size()) <= idx) { + cross.resize(idx + 1, -1); + } + cross[idx] = n; + + items[n].prev = last_item; + items[n].next = -1; + if (last_item != -1) { + items[last_item].next = n; + } else { + first_item = n; + } + last_item = n; + + return n; + } + + int addIndex(int idx, int n) { + while (n >= static_cast(items.size())) { + items.push_back(ItemT()); + items.back().prev = -1; + items.back().next = first_free_item; + if (first_free_item != -1) { + items[first_free_item].prev = items.size() - 1; + } + first_free_item = items.size() - 1; + } + if (items[n].next != -1) { + items[items[n].next].prev = items[n].prev; + } + if (items[n].prev != -1) { + items[items[n].prev].next = items[n].next; + } else { + first_free_item = items[n].next; + } + + items[n].index = idx; + if (static_cast(cross.size()) <= idx) { + cross.resize(idx + 1, -1); + } + cross[idx] = n; + + items[n].prev = last_item; + items[n].next = -1; + if (last_item != -1) { + items[last_item].next = n; + } else { + first_item = n; + } + last_item = n; + + return n; + } + + void eraseIndex(int idx) { + int n = cross[idx]; + + if (items[n].prev != -1) { + items[items[n].prev].next = items[n].next; + } else { + first_item = items[n].next; + } + if (items[n].next != -1) { + items[items[n].next].prev = items[n].prev; + } else { + last_item = items[n].prev; + } + + if (first_free_item != -1) { + items[first_free_item].prev = n; + } + items[n].next = first_free_item; + items[n].prev = -1; + first_free_item = n; + + while (!cross.empty() && cross.back() == -1) { + cross.pop_back(); + } + } + + int maxIndex() const { + return cross.size() - 1; + } + + void shiftIndices(int idx) { + for (int i = idx + 1; i < static_cast(cross.size()); ++i) { + cross[i - 1] = cross[i]; + if (cross[i] != -1) { + --items[cross[i]].index; + } + } + cross.back() = -1; + cross.pop_back(); + while (!cross.empty() && cross.back() == -1) { + cross.pop_back(); + } + } + + void relocateIndex(int idx, int jdx) { + cross[idx] = cross[jdx]; + items[cross[jdx]].index = idx; + cross[jdx] = -1; + + while (!cross.empty() && cross.back() == -1) { + cross.pop_back(); + } + } + + int operator[](int idx) const { + return cross[idx]; + } + + int operator()(int fdx) const { + return items[fdx].index; + } + + void firstItem(int& fdx) const { + fdx = first_item; + } + + void nextItem(int& fdx) const { + fdx = items[fdx].next; + } + + }; + } +} + +#endif diff --git a/lemon/lemon/bits/traits.h b/lemon/lemon/bits/traits.h new file mode 100644 index 0000000..909393c --- /dev/null +++ b/lemon/lemon/bits/traits.h @@ -0,0 +1,306 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_TRAITS_H +#define LEMON_BITS_TRAITS_H + +//\file +//\brief Traits for graphs and maps +// + +#include + +namespace lemon { + + struct InvalidType {}; + + template + class ItemSetTraits {}; + + + template + struct NodeNotifierIndicator { + typedef InvalidType Type; + }; + template + struct NodeNotifierIndicator< + GR, + typename enable_if::type + > { + typedef typename GR::NodeNotifier Type; + }; + + template + class ItemSetTraits { + public: + + typedef GR Graph; + typedef GR Digraph; + + typedef typename GR::Node Item; + typedef typename GR::NodeIt ItemIt; + + typedef typename NodeNotifierIndicator::Type ItemNotifier; + + template + class Map : public GR::template NodeMap { + typedef typename GR::template NodeMap Parent; + + public: + typedef typename GR::template NodeMap Type; + typedef typename Parent::Value Value; + + Map(const GR& _digraph) : Parent(_digraph) {} + Map(const GR& _digraph, const Value& _value) + : Parent(_digraph, _value) {} + + }; + + }; + + template + struct ArcNotifierIndicator { + typedef InvalidType Type; + }; + template + struct ArcNotifierIndicator< + GR, + typename enable_if::type + > { + typedef typename GR::ArcNotifier Type; + }; + + template + class ItemSetTraits { + public: + + typedef GR Graph; + typedef GR Digraph; + + typedef typename GR::Arc Item; + typedef typename GR::ArcIt ItemIt; + + typedef typename ArcNotifierIndicator::Type ItemNotifier; + + template + class Map : public GR::template ArcMap { + typedef typename GR::template ArcMap Parent; + + public: + typedef typename GR::template ArcMap Type; + typedef typename Parent::Value Value; + + Map(const GR& _digraph) : Parent(_digraph) {} + Map(const GR& _digraph, const Value& _value) + : Parent(_digraph, _value) {} + }; + + }; + + template + struct EdgeNotifierIndicator { + typedef InvalidType Type; + }; + template + struct EdgeNotifierIndicator< + GR, + typename enable_if::type + > { + typedef typename GR::EdgeNotifier Type; + }; + + template + class ItemSetTraits { + public: + + typedef GR Graph; + typedef GR Digraph; + + typedef typename GR::Edge Item; + typedef typename GR::EdgeIt ItemIt; + + typedef typename EdgeNotifierIndicator::Type ItemNotifier; + + template + class Map : public GR::template EdgeMap { + typedef typename GR::template EdgeMap Parent; + + public: + typedef typename GR::template EdgeMap Type; + typedef typename Parent::Value Value; + + Map(const GR& _digraph) : Parent(_digraph) {} + Map(const GR& _digraph, const Value& _value) + : Parent(_digraph, _value) {} + }; + + }; + + template + struct MapTraits { + typedef False ReferenceMapTag; + + typedef typename Map::Key Key; + typedef typename Map::Value Value; + + typedef Value ConstReturnValue; + typedef Value ReturnValue; + }; + + template + struct MapTraits< + Map, typename enable_if::type > + { + typedef True ReferenceMapTag; + + typedef typename Map::Key Key; + typedef typename Map::Value Value; + + typedef typename Map::ConstReference ConstReturnValue; + typedef typename Map::Reference ReturnValue; + + typedef typename Map::ConstReference ConstReference; + typedef typename Map::Reference Reference; + }; + + template + struct MatrixMapTraits { + typedef False ReferenceMapTag; + + typedef typename MatrixMap::FirstKey FirstKey; + typedef typename MatrixMap::SecondKey SecondKey; + typedef typename MatrixMap::Value Value; + + typedef Value ConstReturnValue; + typedef Value ReturnValue; + }; + + template + struct MatrixMapTraits< + MatrixMap, typename enable_if::type > + { + typedef True ReferenceMapTag; + + typedef typename MatrixMap::FirstKey FirstKey; + typedef typename MatrixMap::SecondKey SecondKey; + typedef typename MatrixMap::Value Value; + + typedef typename MatrixMap::ConstReference ConstReturnValue; + typedef typename MatrixMap::Reference ReturnValue; + + typedef typename MatrixMap::ConstReference ConstReference; + typedef typename MatrixMap::Reference Reference; + }; + + // Indicators for the tags + + template + struct NodeNumTagIndicator { + static const bool value = false; + }; + + template + struct NodeNumTagIndicator< + GR, + typename enable_if::type + > { + static const bool value = true; + }; + + template + struct ArcNumTagIndicator { + static const bool value = false; + }; + + template + struct ArcNumTagIndicator< + GR, + typename enable_if::type + > { + static const bool value = true; + }; + + template + struct EdgeNumTagIndicator { + static const bool value = false; + }; + + template + struct EdgeNumTagIndicator< + GR, + typename enable_if::type + > { + static const bool value = true; + }; + + template + struct FindArcTagIndicator { + static const bool value = false; + }; + + template + struct FindArcTagIndicator< + GR, + typename enable_if::type + > { + static const bool value = true; + }; + + template + struct FindEdgeTagIndicator { + static const bool value = false; + }; + + template + struct FindEdgeTagIndicator< + GR, + typename enable_if::type + > { + static const bool value = true; + }; + + template + struct UndirectedTagIndicator { + static const bool value = false; + }; + + template + struct UndirectedTagIndicator< + GR, + typename enable_if::type + > { + static const bool value = true; + }; + + template + struct BuildTagIndicator { + static const bool value = false; + }; + + template + struct BuildTagIndicator< + GR, + typename enable_if::type + > { + static const bool value = true; + }; + +} + +#endif diff --git a/lemon/lemon/bits/variant.h b/lemon/lemon/bits/variant.h new file mode 100644 index 0000000..b830189 --- /dev/null +++ b/lemon/lemon/bits/variant.h @@ -0,0 +1,494 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_VARIANT_H +#define LEMON_BITS_VARIANT_H + +#include + +// \file +// \brief Variant types + +namespace lemon { + + namespace _variant_bits { + + template + struct CTMax { + static const int value = left < right ? right : left; + }; + + } + + + // \brief Simple Variant type for two types + // + // Simple Variant type for two types. The Variant type is a type-safe + // union. C++ has strong limitations for using unions, for + // example you cannot store a type with non-default constructor or + // destructor in a union. This class always knowns the current + // state of the variant and it cares for the proper construction + // and destruction. + template + class BiVariant { + public: + + // \brief The \c First type. + typedef _First First; + // \brief The \c Second type. + typedef _Second Second; + + // \brief Constructor + // + // This constructor initalizes to the default value of the \c First + // type. + BiVariant() { + flag = true; + new(reinterpret_cast(data)) First(); + } + + // \brief Constructor + // + // This constructor initalizes to the given value of the \c First + // type. + BiVariant(const First& f) { + flag = true; + new(reinterpret_cast(data)) First(f); + } + + // \brief Constructor + // + // This constructor initalizes to the given value of the \c + // Second type. + BiVariant(const Second& s) { + flag = false; + new(reinterpret_cast(data)) Second(s); + } + + // \brief Copy constructor + // + // Copy constructor + BiVariant(const BiVariant& bivariant) { + flag = bivariant.flag; + if (flag) { + new(reinterpret_cast(data)) First(bivariant.first()); + } else { + new(reinterpret_cast(data)) Second(bivariant.second()); + } + } + + // \brief Destrcutor + // + // Destructor + ~BiVariant() { + destroy(); + } + + // \brief Set to the default value of the \c First type. + // + // This function sets the variant to the default value of the \c + // First type. + BiVariant& setFirst() { + destroy(); + flag = true; + new(reinterpret_cast(data)) First(); + return *this; + } + + // \brief Set to the given value of the \c First type. + // + // This function sets the variant to the given value of the \c + // First type. + BiVariant& setFirst(const First& f) { + destroy(); + flag = true; + new(reinterpret_cast(data)) First(f); + return *this; + } + + // \brief Set to the default value of the \c Second type. + // + // This function sets the variant to the default value of the \c + // Second type. + BiVariant& setSecond() { + destroy(); + flag = false; + new(reinterpret_cast(data)) Second(); + return *this; + } + + // \brief Set to the given value of the \c Second type. + // + // This function sets the variant to the given value of the \c + // Second type. + BiVariant& setSecond(const Second& s) { + destroy(); + flag = false; + new(reinterpret_cast(data)) Second(s); + return *this; + } + + // \brief Operator form of the \c setFirst() + BiVariant& operator=(const First& f) { + return setFirst(f); + } + + // \brief Operator form of the \c setSecond() + BiVariant& operator=(const Second& s) { + return setSecond(s); + } + + // \brief Assign operator + BiVariant& operator=(const BiVariant& bivariant) { + if (this == &bivariant) return *this; + destroy(); + flag = bivariant.flag; + if (flag) { + new(reinterpret_cast(data)) First(bivariant.first()); + } else { + new(reinterpret_cast(data)) Second(bivariant.second()); + } + return *this; + } + + // \brief Reference to the value + // + // Reference to the value of the \c First type. + // \pre The BiVariant should store value of \c First type. + First& first() { + LEMON_DEBUG(flag, "Variant wrong state"); + return *reinterpret_cast(data); + } + + // \brief Const reference to the value + // + // Const reference to the value of the \c First type. + // \pre The BiVariant should store value of \c First type. + const First& first() const { + LEMON_DEBUG(flag, "Variant wrong state"); + return *reinterpret_cast(data); + } + + // \brief Operator form of the \c first() + operator First&() { return first(); } + // \brief Operator form of the const \c first() + operator const First&() const { return first(); } + + // \brief Reference to the value + // + // Reference to the value of the \c Second type. + // \pre The BiVariant should store value of \c Second type. + Second& second() { + LEMON_DEBUG(!flag, "Variant wrong state"); + return *reinterpret_cast(data); + } + + // \brief Const reference to the value + // + // Const reference to the value of the \c Second type. + // \pre The BiVariant should store value of \c Second type. + const Second& second() const { + LEMON_DEBUG(!flag, "Variant wrong state"); + return *reinterpret_cast(data); + } + + // \brief Operator form of the \c second() + operator Second&() { return second(); } + // \brief Operator form of the const \c second() + operator const Second&() const { return second(); } + + // \brief %True when the variant is in the first state + // + // %True when the variant stores value of the \c First type. + bool firstState() const { return flag; } + + // \brief %True when the variant is in the second state + // + // %True when the variant stores value of the \c Second type. + bool secondState() const { return !flag; } + + private: + + void destroy() { + if (flag) { + reinterpret_cast(data)->~First(); + } else { + reinterpret_cast(data)->~Second(); + } + } + + char data[_variant_bits::CTMax::value]; + bool flag; + }; + + namespace _variant_bits { + + template + struct Memory { + + typedef typename _TypeMap::template Map<_idx>::Type Current; + + static void destroy(int index, char* place) { + if (index == _idx) { + reinterpret_cast(place)->~Current(); + } else { + Memory<_idx - 1, _TypeMap>::destroy(index, place); + } + } + + static void copy(int index, char* to, const char* from) { + if (index == _idx) { + new (reinterpret_cast(to)) + Current(reinterpret_cast(from)); + } else { + Memory<_idx - 1, _TypeMap>::copy(index, to, from); + } + } + + }; + + template + struct Memory<-1, _TypeMap> { + + static void destroy(int, char*) { + LEMON_DEBUG(false, "Variant wrong index."); + } + + static void copy(int, char*, const char*) { + LEMON_DEBUG(false, "Variant wrong index."); + } + }; + + template + struct Size { + static const int value = + CTMax::Type), + Size<_idx - 1, _TypeMap>::value>::value; + }; + + template + struct Size<0, _TypeMap> { + static const int value = + sizeof(typename _TypeMap::template Map<0>::Type); + }; + + } + + // \brief Variant type + // + // Simple Variant type. The Variant type is a type-safe union. + // C++ has strong limitations for using unions, for example you + // cannot store type with non-default constructor or destructor in + // a union. This class always knowns the current state of the + // variant and it cares for the proper construction and + // destruction. + // + // \param _num The number of the types which can be stored in the + // variant type. + // \param _TypeMap This class describes the types of the Variant. The + // _TypeMap::Map::Type should be a valid type for each index + // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper + // class to define such type mappings up to 10 types. + // + // And the usage of the class: + //\code + // typedef Variant<3, VariantTypeMap > MyVariant; + // MyVariant var; + // var.set<0>(12); + // std::cout << var.get<0>() << std::endl; + // var.set<1>("alpha"); + // std::cout << var.get<1>() << std::endl; + // var.set<2>(0.75); + // std::cout << var.get<2>() << std::endl; + //\endcode + // + // The result of course: + //\code + // 12 + // alpha + // 0.75 + //\endcode + template + class Variant { + public: + + static const int num = _num; + + typedef _TypeMap TypeMap; + + // \brief Constructor + // + // This constructor initalizes to the default value of the \c type + // with 0 index. + Variant() { + flag = 0; + new(reinterpret_cast::Type*>(data)) + typename TypeMap::template Map<0>::Type(); + } + + + // \brief Copy constructor + // + // Copy constructor + Variant(const Variant& variant) { + flag = variant.flag; + _variant_bits::Memory::copy(flag, data, variant.data); + } + + // \brief Assign operator + // + // Assign operator + Variant& operator=(const Variant& variant) { + if (this == &variant) return *this; + _variant_bits::Memory:: + destroy(flag, data); + flag = variant.flag; + _variant_bits::Memory:: + copy(flag, data, variant.data); + return *this; + } + + // \brief Destrcutor + // + // Destructor + ~Variant() { + _variant_bits::Memory::destroy(flag, data); + } + + // \brief Set to the default value of the type with \c _idx index. + // + // This function sets the variant to the default value of the + // type with \c _idx index. + template + Variant& set() { + _variant_bits::Memory::destroy(flag, data); + flag = _idx; + new(reinterpret_cast::Type*>(data)) + typename TypeMap::template Map<_idx>::Type(); + return *this; + } + + // \brief Set to the given value of the type with \c _idx index. + // + // This function sets the variant to the given value of the type + // with \c _idx index. + template + Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) { + _variant_bits::Memory::destroy(flag, data); + flag = _idx; + new(reinterpret_cast::Type*>(data)) + typename TypeMap::template Map<_idx>::Type(init); + return *this; + } + + // \brief Gets the current value of the type with \c _idx index. + // + // Gets the current value of the type with \c _idx index. + template + const typename TypeMap::template Map<_idx>::Type& get() const { + LEMON_DEBUG(_idx == flag, "Variant wrong index"); + return *reinterpret_cast::Type*>(data); + } + + // \brief Gets the current value of the type with \c _idx index. + // + // Gets the current value of the type with \c _idx index. + template + typename _TypeMap::template Map<_idx>::Type& get() { + LEMON_DEBUG(_idx == flag, "Variant wrong index"); + return *reinterpret_cast::Type*> + (data); + } + + // \brief Returns the current state of the variant. + // + // Returns the current state of the variant. + int state() const { + return flag; + } + + private: + + char data[_variant_bits::Size::value]; + int flag; + }; + + namespace _variant_bits { + + template + struct Get { + typedef typename Get<_index - 1, typename _List::Next>::Type Type; + }; + + template + struct Get<0, _List> { + typedef typename _List::Type Type; + }; + + struct List {}; + + template + struct Insert { + typedef _List Next; + typedef _Type Type; + }; + + template + struct Mapper { + typedef List L10; + typedef Insert<_T9, L10> L9; + typedef Insert<_T8, L9> L8; + typedef Insert<_T7, L8> L7; + typedef Insert<_T6, L7> L6; + typedef Insert<_T5, L6> L5; + typedef Insert<_T4, L5> L4; + typedef Insert<_T3, L4> L3; + typedef Insert<_T2, L3> L2; + typedef Insert<_T1, L2> L1; + typedef Insert<_T0, L1> L0; + typedef typename Get<_idx, L0>::Type Type; + }; + + } + + // \brief Helper class for Variant + // + // Helper class to define type mappings for Variant. This class + // converts the template parameters to be mappable by integer. + // \see Variant + template < + typename _T0, + typename _T1 = void, typename _T2 = void, typename _T3 = void, + typename _T4 = void, typename _T5 = void, typename _T6 = void, + typename _T7 = void, typename _T8 = void, typename _T9 = void> + struct VariantTypeMap { + template + struct Map { + typedef typename _variant_bits:: + Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type + Type; + }; + }; + +} + + +#endif diff --git a/lemon/lemon/bits/vector_map.h b/lemon/lemon/bits/vector_map.h new file mode 100644 index 0000000..d60841d --- /dev/null +++ b/lemon/lemon/bits/vector_map.h @@ -0,0 +1,244 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_VECTOR_MAP_H +#define LEMON_BITS_VECTOR_MAP_H + +#include +#include + +#include +#include + +#include +#include + +//\ingroup graphbits +// +//\file +//\brief Vector based graph maps. +namespace lemon { + + // \ingroup graphbits + // + // \brief Graph map based on the std::vector storage. + // + // The VectorMap template class is graph map structure that automatically + // updates the map when a key is added to or erased from the graph. + // This map type uses std::vector to store the values. + // + // \tparam _Graph The graph this map is attached to. + // \tparam _Item The item type of the graph items. + // \tparam _Value The value type of the map. + template + class VectorMap + : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { + private: + + // The container type of the map. + typedef std::vector<_Value> Container; + + public: + + // The graph type of the map. + typedef _Graph GraphType; + // The item type of the map. + typedef _Item Item; + // The reference map tag. + typedef True ReferenceMapTag; + + // The key type of the map. + typedef _Item Key; + // The value type of the map. + typedef _Value Value; + + // The notifier type. + typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier; + + // The map type. + typedef VectorMap Map; + + // The reference type of the map; + typedef typename Container::reference Reference; + // The const reference type of the map; + typedef typename Container::const_reference ConstReference; + + private: + + // The base class of the map. + typedef typename Notifier::ObserverBase Parent; + + public: + + // \brief Constructor to attach the new map into the notifier. + // + // It constructs a map and attachs it into the notifier. + // It adds all the items of the graph to the map. + VectorMap(const GraphType& graph) { + Parent::attach(graph.notifier(Item())); + container.resize(Parent::notifier()->maxId() + 1); + } + + // \brief Constructor uses given value to initialize the map. + // + // It constructs a map uses a given value to initialize the map. + // It adds all the items of the graph to the map. + VectorMap(const GraphType& graph, const Value& value) { + Parent::attach(graph.notifier(Item())); + container.resize(Parent::notifier()->maxId() + 1, value); + } + + private: + // \brief Copy constructor + // + // Copy constructor. + VectorMap(const VectorMap& _copy) : Parent() { + if (_copy.attached()) { + Parent::attach(*_copy.notifier()); + container = _copy.container; + } + } + + // \brief Assign operator. + // + // This operator assigns for each item in the map the + // value mapped to the same item in the copied map. + // The parameter map should be indiced with the same + // itemset because this assign operator does not change + // the container of the map. + VectorMap& operator=(const VectorMap& cmap) { + return operator=(cmap); + } + + + // \brief Template assign operator. + // + // The given parameter should conform to the ReadMap + // concecpt and could be indiced by the current item set of + // the NodeMap. In this case the value for each item + // is assigned by the value of the given ReadMap. + template + VectorMap& operator=(const CMap& cmap) { + checkConcept, CMap>(); + const typename Parent::Notifier* nf = Parent::notifier(); + Item it; + for (nf->first(it); it != INVALID; nf->next(it)) { + set(it, cmap[it]); + } + return *this; + } + + public: + + // \brief The subcript operator. + // + // The subscript operator. The map can be subscripted by the + // actual items of the graph. + Reference operator[](const Key& key) { + return container[Parent::notifier()->id(key)]; + } + + // \brief The const subcript operator. + // + // The const subscript operator. The map can be subscripted by the + // actual items of the graph. + ConstReference operator[](const Key& key) const { + return container[Parent::notifier()->id(key)]; + } + + + // \brief The setter function of the map. + // + // It the same as operator[](key) = value expression. + void set(const Key& key, const Value& value) { + (*this)[key] = value; + } + + protected: + + // \brief Adds a new key to the map. + // + // It adds a new key to the map. It is called by the observer notifier + // and it overrides the add() member function of the observer base. + virtual void add(const Key& key) { + int id = Parent::notifier()->id(key); + if (id >= int(container.size())) { + container.resize(id + 1); + } + } + + // \brief Adds more new keys to the map. + // + // It adds more new keys to the map. It is called by the observer notifier + // and it overrides the add() member function of the observer base. + virtual void add(const std::vector& keys) { + int max = container.size() - 1; + for (int i = 0; i < int(keys.size()); ++i) { + int id = Parent::notifier()->id(keys[i]); + if (id >= max) { + max = id; + } + } + container.resize(max + 1); + } + + // \brief Erase a key from the map. + // + // Erase a key from the map. It is called by the observer notifier + // and it overrides the erase() member function of the observer base. + virtual void erase(const Key& key) { + container[Parent::notifier()->id(key)] = Value(); + } + + // \brief Erase more keys from the map. + // + // It erases more keys from the map. It is called by the observer notifier + // and it overrides the erase() member function of the observer base. + virtual void erase(const std::vector& keys) { + for (int i = 0; i < int(keys.size()); ++i) { + container[Parent::notifier()->id(keys[i])] = Value(); + } + } + + // \brief Build the map. + // + // It builds the map. It is called by the observer notifier + // and it overrides the build() member function of the observer base. + virtual void build() { + int size = Parent::notifier()->maxId() + 1; + container.reserve(size); + container.resize(size); + } + + // \brief Clear the map. + // + // It erases all items from the map. It is called by the observer notifier + // and it overrides the clear() member function of the observer base. + virtual void clear() { + container.clear(); + } + + private: + + Container container; + + }; + +} + +#endif diff --git a/lemon/lemon/bits/windows.cc b/lemon/lemon/bits/windows.cc new file mode 100644 index 0000000..0a1266c --- /dev/null +++ b/lemon/lemon/bits/windows.cc @@ -0,0 +1,134 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Some basic non-inline functions and static global data. + +#include + +#ifdef WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#ifdef UNICODE +#undef UNICODE +#endif +#include +#ifdef LOCALE_INVARIANT +#define MY_LOCALE LOCALE_INVARIANT +#else +#define MY_LOCALE LOCALE_NEUTRAL +#endif +#else +#include +#include +#ifndef WIN32 +#include +#endif +#include +#endif + +#include +#include + +namespace lemon { + namespace bits { + void getWinProcTimes(double &rtime, + double &utime, double &stime, + double &cutime, double &cstime) + { +#ifdef WIN32 + static const double ch = 4294967296.0e-7; + static const double cl = 1.0e-7; + + FILETIME system; + GetSystemTimeAsFileTime(&system); + rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime; + + FILETIME create, exit, kernel, user; + if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) { + utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime; + stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime; + cutime = 0; + cstime = 0; + } else { + rtime = 0; + utime = 0; + stime = 0; + cutime = 0; + cstime = 0; + } +#else + timeval tv; + gettimeofday(&tv, 0); + rtime=tv.tv_sec+double(tv.tv_usec)/1e6; + + tms ts; + double tck=sysconf(_SC_CLK_TCK); + times(&ts); + utime=ts.tms_utime/tck; + stime=ts.tms_stime/tck; + cutime=ts.tms_cutime/tck; + cstime=ts.tms_cstime/tck; +#endif + } + + std::string getWinFormattedDate() + { + std::ostringstream os; +#ifdef WIN32 + SYSTEMTIME time; + GetSystemTime(&time); + char buf1[11], buf2[9], buf3[5]; + if (GetDateFormat(MY_LOCALE, 0, &time, + ("ddd MMM dd"), buf1, 11) && + GetTimeFormat(MY_LOCALE, 0, &time, + ("HH':'mm':'ss"), buf2, 9) && + GetDateFormat(MY_LOCALE, 0, &time, + ("yyyy"), buf3, 5)) { + os << buf1 << ' ' << buf2 << ' ' << buf3; + } + else os << "unknown"; +#else + timeval tv; + gettimeofday(&tv, 0); + + char cbuf[26]; + ctime_r(&tv.tv_sec,cbuf); + os << cbuf; +#endif + return os.str(); + } + + int getWinRndSeed() + { +#ifdef WIN32 + FILETIME time; + GetSystemTimeAsFileTime(&time); + return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime; +#else + timeval tv; + gettimeofday(&tv, 0); + return getpid() + tv.tv_sec + tv.tv_usec; +#endif + } + } +} diff --git a/lemon/lemon/bits/windows.h b/lemon/lemon/bits/windows.h new file mode 100644 index 0000000..0ac0292 --- /dev/null +++ b/lemon/lemon/bits/windows.h @@ -0,0 +1,34 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_WINDOWS_H +#define LEMON_BITS_WINDOWS_H + +#include + +namespace lemon { + namespace bits { + void getWinProcTimes(double &rtime, + double &utime, double &stime, + double &cutime, double &cstime); + std::string getWinFormattedDate(); + int getWinRndSeed(); + } +} + +#endif diff --git a/lemon/lemon/bucket_heap.h b/lemon/lemon/bucket_heap.h new file mode 100644 index 0000000..92dbc08 --- /dev/null +++ b/lemon/lemon/bucket_heap.h @@ -0,0 +1,594 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BUCKET_HEAP_H +#define LEMON_BUCKET_HEAP_H + +///\ingroup heaps +///\file +///\brief Bucket heap implementation. + +#include +#include +#include + +namespace lemon { + + namespace _bucket_heap_bits { + + template + struct DirectionTraits { + static bool less(int left, int right) { + return left < right; + } + static void increase(int& value) { + ++value; + } + }; + + template <> + struct DirectionTraits { + static bool less(int left, int right) { + return left > right; + } + static void increase(int& value) { + --value; + } + }; + + } + + /// \ingroup heaps + /// + /// \brief Bucket heap data structure. + /// + /// This class implements the \e bucket \e heap data structure. + /// It practically conforms to the \ref concepts::Heap "heap concept", + /// but it has some limitations. + /// + /// The bucket heap is a very simple structure. It can store only + /// \c int priorities and it maintains a list of items for each priority + /// in the range [0..C). So it should only be used when the + /// priorities are small. It is not intended to use as a Dijkstra heap. + /// + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap. + /// The default is \e min-heap. If this parameter is set to \c false, + /// then the comparison is reversed, so the top(), prio() and pop() + /// functions deal with the item having maximum priority instead of the + /// minimum. + /// + /// \sa SimpleBucketHeap + template + class BucketHeap { + + public: + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef int Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + + private: + + typedef _bucket_heap_bits::DirectionTraits Direction; + + public: + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {} + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { + _data.clear(); _first.clear(); _minimum = 0; + } + + private: + + void relocateLast(int idx) { + if (idx + 1 < int(_data.size())) { + _data[idx] = _data.back(); + if (_data[idx].prev != -1) { + _data[_data[idx].prev].next = idx; + } else { + _first[_data[idx].value] = idx; + } + if (_data[idx].next != -1) { + _data[_data[idx].next].prev = idx; + } + _iim[_data[idx].item] = idx; + } + _data.pop_back(); + } + + void unlace(int idx) { + if (_data[idx].prev != -1) { + _data[_data[idx].prev].next = _data[idx].next; + } else { + _first[_data[idx].value] = _data[idx].next; + } + if (_data[idx].next != -1) { + _data[_data[idx].next].prev = _data[idx].prev; + } + } + + void lace(int idx) { + if (int(_first.size()) <= _data[idx].value) { + _first.resize(_data[idx].value + 1, -1); + } + _data[idx].next = _first[_data[idx].value]; + if (_data[idx].next != -1) { + _data[_data[idx].next].prev = idx; + } + _first[_data[idx].value] = idx; + _data[idx].prev = -1; + } + + public: + + /// \brief Insert a pair of item and priority into the heap. + /// + /// This function inserts \c p.first to the heap with priority + /// \c p.second. + /// \param p The pair to insert. + /// \pre \c p.first must not be stored in the heap. + void push(const Pair& p) { + push(p.first, p.second); + } + + /// \brief Insert an item into the heap with the given priority. + /// + /// This function inserts the given item into the heap with the + /// given priority. + /// \param i The item to insert. + /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. + void push(const Item &i, const Prio &p) { + int idx = _data.size(); + _iim[i] = idx; + _data.push_back(BucketItem(i, p)); + lace(idx); + if (Direction::less(p, _minimum)) { + _minimum = p; + } + } + + /// \brief Return the item having minimum priority. + /// + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { + while (_first[_minimum] == -1) { + Direction::increase(_minimum); + } + return _data[_first[_minimum]].item; + } + + /// \brief The minimum priority. + /// + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { + while (_first[_minimum] == -1) { + Direction::increase(_minimum); + } + return _minimum; + } + + /// \brief Remove the item having minimum priority. + /// + /// This function removes the item having minimum priority. + /// \pre The heap must be non-empty. + void pop() { + while (_first[_minimum] == -1) { + Direction::increase(_minimum); + } + int idx = _first[_minimum]; + _iim[_data[idx].item] = -2; + unlace(idx); + relocateLast(idx); + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. + void erase(const Item &i) { + int idx = _iim[i]; + _iim[_data[idx].item] = -2; + unlace(idx); + relocateLast(idx); + } + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param i The item. + /// \pre \e i must be in the heap. + Prio operator[](const Item &i) const { + int idx = _iim[i]; + return _data[idx].value; + } + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// \param i The item. + /// \param p The priority. + void set(const Item &i, const Prio &p) { + int idx = _iim[i]; + if (idx < 0) { + push(i, p); + } else if (Direction::less(p, _data[idx].value)) { + decrease(i, p); + } else { + increase(i, p); + } + } + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at least \e p. + void decrease(const Item &i, const Prio &p) { + int idx = _iim[i]; + unlace(idx); + _data[idx].value = p; + if (Direction::less(p, _minimum)) { + _minimum = p; + } + lace(idx); + } + + /// \brief Increase the priority of an item to the given value. + /// + /// This function increases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at most \e p. + void increase(const Item &i, const Prio &p) { + int idx = _iim[i]; + unlace(idx); + _data[idx].value = p; + lace(idx); + } + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param i The item. + State state(const Item &i) const { + int idx = _iim[i]; + if (idx >= 0) idx = 0; + return State(idx); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) { + erase(i); + } + _iim[i] = st; + break; + case IN_HEAP: + break; + } + } + + private: + + struct BucketItem { + BucketItem(const Item& _item, int _value) + : item(_item), value(_value) {} + + Item item; + int value; + + int prev, next; + }; + + ItemIntMap& _iim; + std::vector _first; + std::vector _data; + mutable int _minimum; + + }; // class BucketHeap + + /// \ingroup heaps + /// + /// \brief Simplified bucket heap data structure. + /// + /// This class implements a simplified \e bucket \e heap data + /// structure. It does not provide some functionality, but it is + /// faster and simpler than BucketHeap. The main difference is + /// that BucketHeap stores a doubly-linked list for each key while + /// this class stores only simply-linked lists. It supports erasing + /// only for the item having minimum priority and it does not support + /// key increasing and decreasing. + /// + /// Note that this implementation does not conform to the + /// \ref concepts::Heap "heap concept" due to the lack of some + /// functionality. + /// + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap. + /// The default is \e min-heap. If this parameter is set to \c false, + /// then the comparison is reversed, so the top(), prio() and pop() + /// functions deal with the item having maximum priority instead of the + /// minimum. + /// + /// \sa BucketHeap + template + class SimpleBucketHeap { + + public: + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef int Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + + private: + + typedef _bucket_heap_bits::DirectionTraits Direction; + + public: + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit SimpleBucketHeap(ItemIntMap &map) + : _iim(map), _free(-1), _num(0), _minimum(0) {} + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _num; } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _num == 0; } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { + _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0; + } + + /// \brief Insert a pair of item and priority into the heap. + /// + /// This function inserts \c p.first to the heap with priority + /// \c p.second. + /// \param p The pair to insert. + /// \pre \c p.first must not be stored in the heap. + void push(const Pair& p) { + push(p.first, p.second); + } + + /// \brief Insert an item into the heap with the given priority. + /// + /// This function inserts the given item into the heap with the + /// given priority. + /// \param i The item to insert. + /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. + void push(const Item &i, const Prio &p) { + int idx; + if (_free == -1) { + idx = _data.size(); + _data.push_back(BucketItem(i)); + } else { + idx = _free; + _free = _data[idx].next; + _data[idx].item = i; + } + _iim[i] = idx; + if (p >= int(_first.size())) _first.resize(p + 1, -1); + _data[idx].next = _first[p]; + _first[p] = idx; + if (Direction::less(p, _minimum)) { + _minimum = p; + } + ++_num; + } + + /// \brief Return the item having minimum priority. + /// + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { + while (_first[_minimum] == -1) { + Direction::increase(_minimum); + } + return _data[_first[_minimum]].item; + } + + /// \brief The minimum priority. + /// + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { + while (_first[_minimum] == -1) { + Direction::increase(_minimum); + } + return _minimum; + } + + /// \brief Remove the item having minimum priority. + /// + /// This function removes the item having minimum priority. + /// \pre The heap must be non-empty. + void pop() { + while (_first[_minimum] == -1) { + Direction::increase(_minimum); + } + int idx = _first[_minimum]; + _iim[_data[idx].item] = -2; + _first[_minimum] = _data[idx].next; + _data[idx].next = _free; + _free = idx; + --_num; + } + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param i The item. + /// \pre \e i must be in the heap. + /// \warning This operator is not a constant time function because + /// it scans the whole data structure to find the proper value. + Prio operator[](const Item &i) const { + for (int k = 0; k < int(_first.size()); ++k) { + int idx = _first[k]; + while (idx != -1) { + if (_data[idx].item == i) { + return k; + } + idx = _data[idx].next; + } + } + return -1; + } + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param i The item. + State state(const Item &i) const { + int idx = _iim[i]; + if (idx >= 0) idx = 0; + return State(idx); + } + + private: + + struct BucketItem { + BucketItem(const Item& _item) + : item(_item) {} + + Item item; + int next; + }; + + ItemIntMap& _iim; + std::vector _first; + std::vector _data; + int _free, _num; + mutable int _minimum; + + }; // class SimpleBucketHeap + +} + +#endif diff --git a/lemon/lemon/capacity_scaling.h b/lemon/lemon/capacity_scaling.h new file mode 100644 index 0000000..86208a0 --- /dev/null +++ b/lemon/lemon/capacity_scaling.h @@ -0,0 +1,990 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CAPACITY_SCALING_H +#define LEMON_CAPACITY_SCALING_H + +/// \ingroup min_cost_flow_algs +/// +/// \file +/// \brief Capacity Scaling algorithm for finding a minimum cost flow. + +#include +#include +#include +#include + +namespace lemon { + + /// \brief Default traits class of CapacityScaling algorithm. + /// + /// Default traits class of CapacityScaling algorithm. + /// \tparam GR Digraph type. + /// \tparam V The number type used for flow amounts, capacity bounds + /// and supply values. By default it is \c int. + /// \tparam C The number type used for costs and potentials. + /// By default it is the same as \c V. + template + struct CapacityScalingDefaultTraits + { + /// The type of the digraph + typedef GR Digraph; + /// The type of the flow amounts, capacity bounds and supply values + typedef V Value; + /// The type of the arc costs + typedef C Cost; + + /// \brief The type of the heap used for internal Dijkstra computations. + /// + /// The type of the heap used for internal Dijkstra computations. + /// It must conform to the \ref lemon::concepts::Heap "Heap" concept, + /// its priority type must be \c Cost and its cross reference type + /// must be \ref RangeMap "RangeMap". + typedef BinHeap > Heap; + }; + + /// \addtogroup min_cost_flow_algs + /// @{ + + /// \brief Implementation of the Capacity Scaling algorithm for + /// finding a \ref min_cost_flow "minimum cost flow". + /// + /// \ref CapacityScaling implements the capacity scaling version + /// of the successive shortest path algorithm for finding a + /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows, + /// \ref edmondskarp72theoretical. It is an efficient dual + /// solution method. + /// + /// Most of the parameters of the problem (except for the digraph) + /// can be given using separate functions, and the algorithm can be + /// executed using the \ref run() function. If some parameters are not + /// specified, then default values will be used. + /// + /// \tparam GR The digraph type the algorithm runs on. + /// \tparam V The number type used for flow amounts, capacity bounds + /// and supply values in the algorithm. By default, it is \c int. + /// \tparam C The number type used for costs and potentials in the + /// algorithm. By default, it is the same as \c V. + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref CapacityScalingDefaultTraits + /// "CapacityScalingDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. + /// + /// \warning Both number types must be signed and all input data must + /// be integer. + /// \warning This algorithm does not support negative costs for such + /// arcs that have infinite upper bound. +#ifdef DOXYGEN + template +#else + template < typename GR, typename V = int, typename C = V, + typename TR = CapacityScalingDefaultTraits > +#endif + class CapacityScaling + { + public: + + /// The type of the digraph + typedef typename TR::Digraph Digraph; + /// The type of the flow amounts, capacity bounds and supply values + typedef typename TR::Value Value; + /// The type of the arc costs + typedef typename TR::Cost Cost; + + /// The type of the heap used for internal Dijkstra computations + typedef typename TR::Heap Heap; + + /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm + typedef TR Traits; + + public: + + /// \brief Problem type constants for the \c run() function. + /// + /// Enum type containing the problem type constants that can be + /// returned by the \ref run() function of the algorithm. + enum ProblemType { + /// The problem has no feasible solution (flow). + INFEASIBLE, + /// The problem has optimal solution (i.e. it is feasible and + /// bounded), and the algorithm has found optimal flow and node + /// potentials (primal and dual solutions). + OPTIMAL, + /// The digraph contains an arc of negative cost and infinite + /// upper bound. It means that the objective function is unbounded + /// on that arc, however, note that it could actually be bounded + /// over the feasible flows, but this algroithm cannot handle + /// these cases. + UNBOUNDED + }; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + typedef std::vector IntVector; + typedef std::vector ValueVector; + typedef std::vector CostVector; + typedef std::vector BoolVector; + // Note: vector is used instead of vector for efficiency reasons + + private: + + // Data related to the underlying digraph + const GR &_graph; + int _node_num; + int _arc_num; + int _res_arc_num; + int _root; + + // Parameters of the problem + bool _have_lower; + Value _sum_supply; + + // Data structures for storing the digraph + IntNodeMap _node_id; + IntArcMap _arc_idf; + IntArcMap _arc_idb; + IntVector _first_out; + BoolVector _forward; + IntVector _source; + IntVector _target; + IntVector _reverse; + + // Node and arc data + ValueVector _lower; + ValueVector _upper; + CostVector _cost; + ValueVector _supply; + + ValueVector _res_cap; + CostVector _pi; + ValueVector _excess; + IntVector _excess_nodes; + IntVector _deficit_nodes; + + Value _delta; + int _factor; + IntVector _pred; + + public: + + /// \brief Constant for infinite upper bounds (capacities). + /// + /// Constant for infinite upper bounds (capacities). + /// It is \c std::numeric_limits::infinity() if available, + /// \c std::numeric_limits::max() otherwise. + const Value INF; + + private: + + // Special implementation of the Dijkstra algorithm for finding + // shortest paths in the residual network of the digraph with + // respect to the reduced arc costs and modifying the node + // potentials according to the found distance labels. + class ResidualDijkstra + { + private: + + int _node_num; + bool _geq; + const IntVector &_first_out; + const IntVector &_target; + const CostVector &_cost; + const ValueVector &_res_cap; + const ValueVector &_excess; + CostVector &_pi; + IntVector &_pred; + + IntVector _proc_nodes; + CostVector _dist; + + public: + + ResidualDijkstra(CapacityScaling& cs) : + _node_num(cs._node_num), _geq(cs._sum_supply < 0), + _first_out(cs._first_out), _target(cs._target), _cost(cs._cost), + _res_cap(cs._res_cap), _excess(cs._excess), _pi(cs._pi), + _pred(cs._pred), _dist(cs._node_num) + {} + + int run(int s, Value delta = 1) { + RangeMap heap_cross_ref(_node_num, Heap::PRE_HEAP); + Heap heap(heap_cross_ref); + heap.push(s, 0); + _pred[s] = -1; + _proc_nodes.clear(); + + // Process nodes + while (!heap.empty() && _excess[heap.top()] > -delta) { + int u = heap.top(), v; + Cost d = heap.prio() + _pi[u], dn; + _dist[u] = heap.prio(); + _proc_nodes.push_back(u); + heap.pop(); + + // Traverse outgoing residual arcs + int last_out = _geq ? _first_out[u+1] : _first_out[u+1] - 1; + for (int a = _first_out[u]; a != last_out; ++a) { + if (_res_cap[a] < delta) continue; + v = _target[a]; + switch (heap.state(v)) { + case Heap::PRE_HEAP: + heap.push(v, d + _cost[a] - _pi[v]); + _pred[v] = a; + break; + case Heap::IN_HEAP: + dn = d + _cost[a] - _pi[v]; + if (dn < heap[v]) { + heap.decrease(v, dn); + _pred[v] = a; + } + break; + case Heap::POST_HEAP: + break; + } + } + } + if (heap.empty()) return -1; + + // Update potentials of processed nodes + int t = heap.top(); + Cost dt = heap.prio(); + for (int i = 0; i < int(_proc_nodes.size()); ++i) { + _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt; + } + + return t; + } + + }; //class ResidualDijkstra + + public: + + /// \name Named Template Parameters + /// @{ + + template + struct SetHeapTraits : public Traits { + typedef T Heap; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c Heap type. + /// + /// \ref named-templ-param "Named parameter" for setting \c Heap + /// type, which is used for internal Dijkstra computations. + /// It must conform to the \ref lemon::concepts::Heap "Heap" concept, + /// its priority type must be \c Cost and its cross reference type + /// must be \ref RangeMap "RangeMap". + template + struct SetHeap + : public CapacityScaling > { + typedef CapacityScaling > Create; + }; + + /// @} + + protected: + + CapacityScaling() {} + + public: + + /// \brief Constructor. + /// + /// The constructor of the class. + /// + /// \param graph The digraph the algorithm runs on. + CapacityScaling(const GR& graph) : + _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph), + INF(std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max()) + { + // Check the number types + LEMON_ASSERT(std::numeric_limits::is_signed, + "The flow type of CapacityScaling must be signed"); + LEMON_ASSERT(std::numeric_limits::is_signed, + "The cost type of CapacityScaling must be signed"); + + // Reset data structures + reset(); + } + + /// \name Parameters + /// The parameters of the algorithm can be specified using these + /// functions. + + /// @{ + + /// \brief Set the lower bounds on the arcs. + /// + /// This function sets the lower bounds on the arcs. + /// If it is not used before calling \ref run(), the lower bounds + /// will be set to zero on all arcs. + /// + /// \param map An arc map storing the lower bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CapacityScaling& lowerMap(const LowerMap& map) { + _have_lower = true; + for (ArcIt a(_graph); a != INVALID; ++a) { + _lower[_arc_idf[a]] = map[a]; + _lower[_arc_idb[a]] = map[a]; + } + return *this; + } + + /// \brief Set the upper bounds (capacities) on the arcs. + /// + /// This function sets the upper bounds (capacities) on the arcs. + /// If it is not used before calling \ref run(), the upper bounds + /// will be set to \ref INF on all arcs (i.e. the flow value will be + /// unbounded from above). + /// + /// \param map An arc map storing the upper bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CapacityScaling& upperMap(const UpperMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _upper[_arc_idf[a]] = map[a]; + } + return *this; + } + + /// \brief Set the costs of the arcs. + /// + /// This function sets the costs of the arcs. + /// If it is not used before calling \ref run(), the costs + /// will be set to \c 1 on all arcs. + /// + /// \param map An arc map storing the costs. + /// Its \c Value type must be convertible to the \c Cost type + /// of the algorithm. + /// + /// \return (*this) + template + CapacityScaling& costMap(const CostMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _cost[_arc_idf[a]] = map[a]; + _cost[_arc_idb[a]] = -map[a]; + } + return *this; + } + + /// \brief Set the supply values of the nodes. + /// + /// This function sets the supply values of the nodes. + /// If neither this function nor \ref stSupply() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// \param map A node map storing the supply values. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CapacityScaling& supplyMap(const SupplyMap& map) { + for (NodeIt n(_graph); n != INVALID; ++n) { + _supply[_node_id[n]] = map[n]; + } + return *this; + } + + /// \brief Set single source and target nodes and a supply value. + /// + /// This function sets a single source node and a single target node + /// and the required flow value. + /// If neither this function nor \ref supplyMap() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// Using this function has the same effect as using \ref supplyMap() + /// with such a map in which \c k is assigned to \c s, \c -k is + /// assigned to \c t and all other nodes have zero supply value. + /// + /// \param s The source node. + /// \param t The target node. + /// \param k The required amount of flow from node \c s to node \c t + /// (i.e. the supply of \c s and the demand of \c t). + /// + /// \return (*this) + CapacityScaling& stSupply(const Node& s, const Node& t, Value k) { + for (int i = 0; i != _node_num; ++i) { + _supply[i] = 0; + } + _supply[_node_id[s]] = k; + _supply[_node_id[t]] = -k; + return *this; + } + + /// @} + + /// \name Execution control + /// The algorithm can be executed using \ref run(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// The paramters can be specified using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// For example, + /// \code + /// CapacityScaling cs(graph); + /// cs.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// This function can be called more than once. All the given parameters + /// are kept for the next call, unless \ref resetParams() or \ref reset() + /// is used, thus only the modified parameters have to be set again. + /// If the underlying digraph was also modified after the construction + /// of the class (or the last \ref reset() call), then the \ref reset() + /// function must be called. + /// + /// \param factor The capacity scaling factor. It must be larger than + /// one to use scaling. If it is less or equal to one, then scaling + /// will be disabled. + /// + /// \return \c INFEASIBLE if no feasible flow exists, + /// \n \c OPTIMAL if the problem has optimal solution + /// (i.e. it is feasible and bounded), and the algorithm has found + /// optimal flow and node potentials (primal and dual solutions), + /// \n \c UNBOUNDED if the digraph contains an arc of negative cost + /// and infinite upper bound. It means that the objective function + /// is unbounded on that arc, however, note that it could actually be + /// bounded over the feasible flows, but this algroithm cannot handle + /// these cases. + /// + /// \see ProblemType + /// \see resetParams(), reset() + ProblemType run(int factor = 4) { + _factor = factor; + ProblemType pt = init(); + if (pt != OPTIMAL) return pt; + return start(); + } + + /// \brief Reset all the parameters that have been given before. + /// + /// This function resets all the paramaters that have been given + /// before using functions \ref lowerMap(), \ref upperMap(), + /// \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// + /// It is useful for multiple \ref run() calls. Basically, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// For example, + /// \code + /// CapacityScaling cs(graph); + /// + /// // First run + /// cs.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// + /// // Run again with modified cost map (resetParams() is not called, + /// // so only the cost map have to be set again) + /// cost[e] += 100; + /// cs.costMap(cost).run(); + /// + /// // Run again from scratch using resetParams() + /// // (the lower bounds will be set to zero on all arcs) + /// cs.resetParams(); + /// cs.upperMap(capacity).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// \return (*this) + /// + /// \see reset(), run() + CapacityScaling& resetParams() { + for (int i = 0; i != _node_num; ++i) { + _supply[i] = 0; + } + for (int j = 0; j != _res_arc_num; ++j) { + _lower[j] = 0; + _upper[j] = INF; + _cost[j] = _forward[j] ? 1 : -1; + } + _have_lower = false; + return *this; + } + + /// \brief Reset the internal data structures and all the parameters + /// that have been given before. + /// + /// This function resets the internal data structures and all the + /// paramaters that have been given before using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// + /// It is useful for multiple \ref run() calls. Basically, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// See \ref resetParams() for examples. + /// + /// \return (*this) + /// + /// \see resetParams(), run() + CapacityScaling& reset() { + // Resize vectors + _node_num = countNodes(_graph); + _arc_num = countArcs(_graph); + _res_arc_num = 2 * (_arc_num + _node_num); + _root = _node_num; + ++_node_num; + + _first_out.resize(_node_num + 1); + _forward.resize(_res_arc_num); + _source.resize(_res_arc_num); + _target.resize(_res_arc_num); + _reverse.resize(_res_arc_num); + + _lower.resize(_res_arc_num); + _upper.resize(_res_arc_num); + _cost.resize(_res_arc_num); + _supply.resize(_node_num); + + _res_cap.resize(_res_arc_num); + _pi.resize(_node_num); + _excess.resize(_node_num); + _pred.resize(_node_num); + + // Copy the graph + int i = 0, j = 0, k = 2 * _arc_num + _node_num - 1; + for (NodeIt n(_graph); n != INVALID; ++n, ++i) { + _node_id[n] = i; + } + i = 0; + for (NodeIt n(_graph); n != INVALID; ++n, ++i) { + _first_out[i] = j; + for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) { + _arc_idf[a] = j; + _forward[j] = true; + _source[j] = i; + _target[j] = _node_id[_graph.runningNode(a)]; + } + for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) { + _arc_idb[a] = j; + _forward[j] = false; + _source[j] = i; + _target[j] = _node_id[_graph.runningNode(a)]; + } + _forward[j] = false; + _source[j] = i; + _target[j] = _root; + _reverse[j] = k; + _forward[k] = true; + _source[k] = _root; + _target[k] = i; + _reverse[k] = j; + ++j; ++k; + } + _first_out[i] = j; + _first_out[_node_num] = k; + for (ArcIt a(_graph); a != INVALID; ++a) { + int fi = _arc_idf[a]; + int bi = _arc_idb[a]; + _reverse[fi] = bi; + _reverse[bi] = fi; + } + + // Reset parameters + resetParams(); + return *this; + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions.\n + /// The \ref run() function must be called before using them. + + /// @{ + + /// \brief Return the total cost of the found flow. + /// + /// This function returns the total cost of the found flow. + /// Its complexity is O(e). + /// + /// \note The return type of the function can be specified as a + /// template parameter. For example, + /// \code + /// cs.totalCost(); + /// \endcode + /// It is useful if the total cost cannot be stored in the \c Cost + /// type of the algorithm, which is the default return type of the + /// function. + /// + /// \pre \ref run() must be called before using this function. + template + Number totalCost() const { + Number c = 0; + for (ArcIt a(_graph); a != INVALID; ++a) { + int i = _arc_idb[a]; + c += static_cast(_res_cap[i]) * + (-static_cast(_cost[i])); + } + return c; + } + +#ifndef DOXYGEN + Cost totalCost() const { + return totalCost(); + } +#endif + + /// \brief Return the flow on the given arc. + /// + /// This function returns the flow on the given arc. + /// + /// \pre \ref run() must be called before using this function. + Value flow(const Arc& a) const { + return _res_cap[_arc_idb[a]]; + } + + /// \brief Return the flow map (the primal solution). + /// + /// This function copies the flow value on each arc into the given + /// map. The \c Value type of the algorithm must be convertible to + /// the \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void flowMap(FlowMap &map) const { + for (ArcIt a(_graph); a != INVALID; ++a) { + map.set(a, _res_cap[_arc_idb[a]]); + } + } + + /// \brief Return the potential (dual value) of the given node. + /// + /// This function returns the potential (dual value) of the + /// given node. + /// + /// \pre \ref run() must be called before using this function. + Cost potential(const Node& n) const { + return _pi[_node_id[n]]; + } + + /// \brief Return the potential map (the dual solution). + /// + /// This function copies the potential (dual value) of each node + /// into the given map. + /// The \c Cost type of the algorithm must be convertible to the + /// \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void potentialMap(PotentialMap &map) const { + for (NodeIt n(_graph); n != INVALID; ++n) { + map.set(n, _pi[_node_id[n]]); + } + } + + /// @} + + private: + + // Initialize the algorithm + ProblemType init() { + if (_node_num <= 1) return INFEASIBLE; + + // Check the sum of supply values + _sum_supply = 0; + for (int i = 0; i != _root; ++i) { + _sum_supply += _supply[i]; + } + if (_sum_supply > 0) return INFEASIBLE; + + // Initialize vectors + for (int i = 0; i != _root; ++i) { + _pi[i] = 0; + _excess[i] = _supply[i]; + } + + // Remove non-zero lower bounds + const Value MAX = std::numeric_limits::max(); + int last_out; + if (_have_lower) { + for (int i = 0; i != _root; ++i) { + last_out = _first_out[i+1]; + for (int j = _first_out[i]; j != last_out; ++j) { + if (_forward[j]) { + Value c = _lower[j]; + if (c >= 0) { + _res_cap[j] = _upper[j] < MAX ? _upper[j] - c : INF; + } else { + _res_cap[j] = _upper[j] < MAX + c ? _upper[j] - c : INF; + } + _excess[i] -= c; + _excess[_target[j]] += c; + } else { + _res_cap[j] = 0; + } + } + } + } else { + for (int j = 0; j != _res_arc_num; ++j) { + _res_cap[j] = _forward[j] ? _upper[j] : 0; + } + } + + // Handle negative costs + for (int i = 0; i != _root; ++i) { + last_out = _first_out[i+1] - 1; + for (int j = _first_out[i]; j != last_out; ++j) { + Value rc = _res_cap[j]; + if (_cost[j] < 0 && rc > 0) { + if (rc >= MAX) return UNBOUNDED; + _excess[i] -= rc; + _excess[_target[j]] += rc; + _res_cap[j] = 0; + _res_cap[_reverse[j]] += rc; + } + } + } + + // Handle GEQ supply type + if (_sum_supply < 0) { + _pi[_root] = 0; + _excess[_root] = -_sum_supply; + for (int a = _first_out[_root]; a != _res_arc_num; ++a) { + int ra = _reverse[a]; + _res_cap[a] = -_sum_supply + 1; + _res_cap[ra] = 0; + _cost[a] = 0; + _cost[ra] = 0; + } + } else { + _pi[_root] = 0; + _excess[_root] = 0; + for (int a = _first_out[_root]; a != _res_arc_num; ++a) { + int ra = _reverse[a]; + _res_cap[a] = 1; + _res_cap[ra] = 0; + _cost[a] = 0; + _cost[ra] = 0; + } + } + + // Initialize delta value + if (_factor > 1) { + // With scaling + Value max_sup = 0, max_dem = 0, max_cap = 0; + for (int i = 0; i != _root; ++i) { + Value ex = _excess[i]; + if ( ex > max_sup) max_sup = ex; + if (-ex > max_dem) max_dem = -ex; + int last_out = _first_out[i+1] - 1; + for (int j = _first_out[i]; j != last_out; ++j) { + if (_res_cap[j] > max_cap) max_cap = _res_cap[j]; + } + } + max_sup = std::min(std::min(max_sup, max_dem), max_cap); + for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ; + } else { + // Without scaling + _delta = 1; + } + + return OPTIMAL; + } + + ProblemType start() { + // Execute the algorithm + ProblemType pt; + if (_delta > 1) + pt = startWithScaling(); + else + pt = startWithoutScaling(); + + // Handle non-zero lower bounds + if (_have_lower) { + int limit = _first_out[_root]; + for (int j = 0; j != limit; ++j) { + if (!_forward[j]) _res_cap[j] += _lower[j]; + } + } + + // Shift potentials if necessary + Cost pr = _pi[_root]; + if (_sum_supply < 0 || pr > 0) { + for (int i = 0; i != _node_num; ++i) { + _pi[i] -= pr; + } + } + + return pt; + } + + // Execute the capacity scaling algorithm + ProblemType startWithScaling() { + // Perform capacity scaling phases + int s, t; + ResidualDijkstra _dijkstra(*this); + while (true) { + // Saturate all arcs not satisfying the optimality condition + int last_out; + for (int u = 0; u != _node_num; ++u) { + last_out = _sum_supply < 0 ? + _first_out[u+1] : _first_out[u+1] - 1; + for (int a = _first_out[u]; a != last_out; ++a) { + int v = _target[a]; + Cost c = _cost[a] + _pi[u] - _pi[v]; + Value rc = _res_cap[a]; + if (c < 0 && rc >= _delta) { + _excess[u] -= rc; + _excess[v] += rc; + _res_cap[a] = 0; + _res_cap[_reverse[a]] += rc; + } + } + } + + // Find excess nodes and deficit nodes + _excess_nodes.clear(); + _deficit_nodes.clear(); + for (int u = 0; u != _node_num; ++u) { + Value ex = _excess[u]; + if (ex >= _delta) _excess_nodes.push_back(u); + if (ex <= -_delta) _deficit_nodes.push_back(u); + } + int next_node = 0, next_def_node = 0; + + // Find augmenting shortest paths + while (next_node < int(_excess_nodes.size())) { + // Check deficit nodes + if (_delta > 1) { + bool delta_deficit = false; + for ( ; next_def_node < int(_deficit_nodes.size()); + ++next_def_node ) { + if (_excess[_deficit_nodes[next_def_node]] <= -_delta) { + delta_deficit = true; + break; + } + } + if (!delta_deficit) break; + } + + // Run Dijkstra in the residual network + s = _excess_nodes[next_node]; + if ((t = _dijkstra.run(s, _delta)) == -1) { + if (_delta > 1) { + ++next_node; + continue; + } + return INFEASIBLE; + } + + // Augment along a shortest path from s to t + Value d = std::min(_excess[s], -_excess[t]); + int u = t; + int a; + if (d > _delta) { + while ((a = _pred[u]) != -1) { + if (_res_cap[a] < d) d = _res_cap[a]; + u = _source[a]; + } + } + u = t; + while ((a = _pred[u]) != -1) { + _res_cap[a] -= d; + _res_cap[_reverse[a]] += d; + u = _source[a]; + } + _excess[s] -= d; + _excess[t] += d; + + if (_excess[s] < _delta) ++next_node; + } + + if (_delta == 1) break; + _delta = _delta <= _factor ? 1 : _delta / _factor; + } + + return OPTIMAL; + } + + // Execute the successive shortest path algorithm + ProblemType startWithoutScaling() { + // Find excess nodes + _excess_nodes.clear(); + for (int i = 0; i != _node_num; ++i) { + if (_excess[i] > 0) _excess_nodes.push_back(i); + } + if (_excess_nodes.size() == 0) return OPTIMAL; + int next_node = 0; + + // Find shortest paths + int s, t; + ResidualDijkstra _dijkstra(*this); + while ( _excess[_excess_nodes[next_node]] > 0 || + ++next_node < int(_excess_nodes.size()) ) + { + // Run Dijkstra in the residual network + s = _excess_nodes[next_node]; + if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE; + + // Augment along a shortest path from s to t + Value d = std::min(_excess[s], -_excess[t]); + int u = t; + int a; + if (d > 1) { + while ((a = _pred[u]) != -1) { + if (_res_cap[a] < d) d = _res_cap[a]; + u = _source[a]; + } + } + u = t; + while ((a = _pred[u]) != -1) { + _res_cap[a] -= d; + _res_cap[_reverse[a]] += d; + u = _source[a]; + } + _excess[s] -= d; + _excess[t] += d; + } + + return OPTIMAL; + } + + }; //class CapacityScaling + + ///@} + +} //namespace lemon + +#endif //LEMON_CAPACITY_SCALING_H diff --git a/lemon/lemon/cbc.cc b/lemon/lemon/cbc.cc new file mode 100644 index 0000000..5564163 --- /dev/null +++ b/lemon/lemon/cbc.cc @@ -0,0 +1,475 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Implementation of the CBC MIP solver interface. + +#include "cbc.h" + +#include +#include +#include + +#ifdef COIN_HAS_CLP +#include "coin/OsiClpSolverInterface.hpp" +#endif +#ifdef COIN_HAS_OSL +#include "coin/OsiOslSolverInterface.hpp" +#endif + +#include "coin/CbcCutGenerator.hpp" +#include "coin/CbcHeuristicLocal.hpp" +#include "coin/CbcHeuristicGreedy.hpp" +#include "coin/CbcHeuristicFPump.hpp" +#include "coin/CbcHeuristicRINS.hpp" + +#include "coin/CglGomory.hpp" +#include "coin/CglProbing.hpp" +#include "coin/CglKnapsackCover.hpp" +#include "coin/CglOddHole.hpp" +#include "coin/CglClique.hpp" +#include "coin/CglFlowCover.hpp" +#include "coin/CglMixedIntegerRounding.hpp" + +#include "coin/CbcHeuristic.hpp" + +namespace lemon { + + CbcMip::CbcMip() { + _prob = new CoinModel(); + _prob->setProblemName("LEMON"); + _osi_solver = 0; + _cbc_model = 0; + messageLevel(MESSAGE_NOTHING); + } + + CbcMip::CbcMip(const CbcMip& other) { + _prob = new CoinModel(*other._prob); + _prob->setProblemName("LEMON"); + _osi_solver = 0; + _cbc_model = 0; + messageLevel(MESSAGE_NOTHING); + } + + CbcMip::~CbcMip() { + delete _prob; + if (_osi_solver) delete _osi_solver; + if (_cbc_model) delete _cbc_model; + } + + const char* CbcMip::_solverName() const { return "CbcMip"; } + + int CbcMip::_addCol() { + _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false); + return _prob->numberColumns() - 1; + } + + CbcMip* CbcMip::newSolver() const { + CbcMip* newlp = new CbcMip; + return newlp; + } + + CbcMip* CbcMip::cloneSolver() const { + CbcMip* copylp = new CbcMip(*this); + return copylp; + } + + int CbcMip::_addRow() { + _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX); + return _prob->numberRows() - 1; + } + + int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) { + std::vector indexes; + std::vector values; + + for(ExprIterator it = b; it != e; ++it) { + indexes.push_back(it->first); + values.push_back(it->second); + } + + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u); + return _prob->numberRows() - 1; + } + + void CbcMip::_eraseCol(int i) { + _prob->deleteColumn(i); + } + + void CbcMip::_eraseRow(int i) { + _prob->deleteRow(i); + } + + void CbcMip::_eraseColId(int i) { + cols.eraseIndex(i); + } + + void CbcMip::_eraseRowId(int i) { + rows.eraseIndex(i); + } + + void CbcMip::_getColName(int c, std::string& name) const { + name = _prob->getColumnName(c); + } + + void CbcMip::_setColName(int c, const std::string& name) { + _prob->setColumnName(c, name.c_str()); + } + + int CbcMip::_colByName(const std::string& name) const { + return _prob->column(name.c_str()); + } + + void CbcMip::_getRowName(int r, std::string& name) const { + name = _prob->getRowName(r); + } + + void CbcMip::_setRowName(int r, const std::string& name) { + _prob->setRowName(r, name.c_str()); + } + + int CbcMip::_rowByName(const std::string& name) const { + return _prob->row(name.c_str()); + } + + void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) { + for (ExprIterator it = b; it != e; ++it) { + _prob->setElement(i, it->first, it->second); + } + } + + void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const { + int length = _prob->numberRows(); + + std::vector indices(length); + std::vector values(length); + + length = _prob->getRow(ix, &indices[0], &values[0]); + + for (int i = 0; i < length; ++i) { + *b = std::make_pair(indices[i], values[i]); + ++b; + } + } + + void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) { + for (ExprIterator it = b; it != e; ++it) { + _prob->setElement(it->first, ix, it->second); + } + } + + void CbcMip::_getColCoeffs(int ix, InsertIterator b) const { + int length = _prob->numberColumns(); + + std::vector indices(length); + std::vector values(length); + + length = _prob->getColumn(ix, &indices[0], &values[0]); + + for (int i = 0; i < length; ++i) { + *b = std::make_pair(indices[i], values[i]); + ++b; + } + } + + void CbcMip::_setCoeff(int ix, int jx, Value value) { + _prob->setElement(ix, jx, value); + } + + CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const { + return _prob->getElement(ix, jx); + } + + + void CbcMip::_setColLowerBound(int i, Value lo) { + LEMON_ASSERT(lo != INF, "Invalid bound"); + _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo); + } + + CbcMip::Value CbcMip::_getColLowerBound(int i) const { + double val = _prob->getColumnLower(i); + return val == - COIN_DBL_MAX ? - INF : val; + } + + void CbcMip::_setColUpperBound(int i, Value up) { + LEMON_ASSERT(up != -INF, "Invalid bound"); + _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up); + } + + CbcMip::Value CbcMip::_getColUpperBound(int i) const { + double val = _prob->getColumnUpper(i); + return val == COIN_DBL_MAX ? INF : val; + } + + void CbcMip::_setRowLowerBound(int i, Value lo) { + LEMON_ASSERT(lo != INF, "Invalid bound"); + _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo); + } + + CbcMip::Value CbcMip::_getRowLowerBound(int i) const { + double val = _prob->getRowLower(i); + return val == - COIN_DBL_MAX ? - INF : val; + } + + void CbcMip::_setRowUpperBound(int i, Value up) { + LEMON_ASSERT(up != -INF, "Invalid bound"); + _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up); + } + + CbcMip::Value CbcMip::_getRowUpperBound(int i) const { + double val = _prob->getRowUpper(i); + return val == COIN_DBL_MAX ? INF : val; + } + + void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) { + int num = _prob->numberColumns(); + for (int i = 0; i < num; ++i) { + _prob->setColumnObjective(i, 0.0); + } + for (ExprIterator it = b; it != e; ++it) { + _prob->setColumnObjective(it->first, it->second); + } + } + + void CbcMip::_getObjCoeffs(InsertIterator b) const { + int num = _prob->numberColumns(); + for (int i = 0; i < num; ++i) { + Value coef = _prob->getColumnObjective(i); + if (coef != 0.0) { + *b = std::make_pair(i, coef); + ++b; + } + } + } + + void CbcMip::_setObjCoeff(int i, Value obj_coef) { + _prob->setColumnObjective(i, obj_coef); + } + + CbcMip::Value CbcMip::_getObjCoeff(int i) const { + return _prob->getColumnObjective(i); + } + + CbcMip::SolveExitStatus CbcMip::_solve() { + + if (_osi_solver) { + delete _osi_solver; + } +#ifdef COIN_HAS_CLP + _osi_solver = new OsiClpSolverInterface(); +#elif COIN_HAS_OSL + _osi_solver = new OsiOslSolverInterface(); +#else +#error Cannot instantiate Osi solver +#endif + + _osi_solver->loadFromCoinModel(*_prob); + + if (_cbc_model) { + delete _cbc_model; + } + _cbc_model= new CbcModel(*_osi_solver); + + _osi_solver->messageHandler()->setLogLevel(_message_level); + _cbc_model->setLogLevel(_message_level); + + _cbc_model->initialSolve(); + _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry); + + if (!_cbc_model->isInitialSolveAbandoned() && + _cbc_model->isInitialSolveProvenOptimal() && + !_cbc_model->isInitialSolveProvenPrimalInfeasible() && + !_cbc_model->isInitialSolveProvenDualInfeasible()) { + + CglProbing generator1; + generator1.setUsingObjective(true); + generator1.setMaxPass(3); + generator1.setMaxProbe(100); + generator1.setMaxLook(50); + generator1.setRowCuts(3); + _cbc_model->addCutGenerator(&generator1, -1, "Probing"); + + CglGomory generator2; + generator2.setLimit(300); + _cbc_model->addCutGenerator(&generator2, -1, "Gomory"); + + CglKnapsackCover generator3; + _cbc_model->addCutGenerator(&generator3, -1, "Knapsack"); + + CglOddHole generator4; + generator4.setMinimumViolation(0.005); + generator4.setMinimumViolationPer(0.00002); + generator4.setMaximumEntries(200); + _cbc_model->addCutGenerator(&generator4, -1, "OddHole"); + + CglClique generator5; + generator5.setStarCliqueReport(false); + generator5.setRowCliqueReport(false); + _cbc_model->addCutGenerator(&generator5, -1, "Clique"); + + CglMixedIntegerRounding mixedGen; + _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding"); + + CglFlowCover flowGen; + _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover"); + +#ifdef COIN_HAS_CLP + OsiClpSolverInterface* osiclp = + dynamic_cast(_cbc_model->solver()); + if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) { + osiclp->setupForRepeatedUse(2, 0); + } +#endif + + CbcRounding heuristic1(*_cbc_model); + heuristic1.setWhen(3); + _cbc_model->addHeuristic(&heuristic1); + + CbcHeuristicLocal heuristic2(*_cbc_model); + heuristic2.setWhen(3); + _cbc_model->addHeuristic(&heuristic2); + + CbcHeuristicGreedyCover heuristic3(*_cbc_model); + heuristic3.setAlgorithm(11); + heuristic3.setWhen(3); + _cbc_model->addHeuristic(&heuristic3); + + CbcHeuristicFPump heuristic4(*_cbc_model); + heuristic4.setWhen(3); + _cbc_model->addHeuristic(&heuristic4); + + CbcHeuristicRINS heuristic5(*_cbc_model); + heuristic5.setWhen(3); + _cbc_model->addHeuristic(&heuristic5); + + if (_cbc_model->getNumCols() < 500) { + _cbc_model->setMaximumCutPassesAtRoot(-100); + } else if (_cbc_model->getNumCols() < 5000) { + _cbc_model->setMaximumCutPassesAtRoot(100); + } else { + _cbc_model->setMaximumCutPassesAtRoot(20); + } + + if (_cbc_model->getNumCols() < 5000) { + _cbc_model->setNumberStrong(10); + } + + _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100); + _cbc_model->branchAndBound(); + } + + if (_cbc_model->isAbandoned()) { + return UNSOLVED; + } else { + return SOLVED; + } + } + + CbcMip::Value CbcMip::_getSol(int i) const { + return _cbc_model->getColSolution()[i]; + } + + CbcMip::Value CbcMip::_getSolValue() const { + return _cbc_model->getObjValue(); + } + + CbcMip::ProblemType CbcMip::_getType() const { + if (_cbc_model->isProvenOptimal()) { + return OPTIMAL; + } else if (_cbc_model->isContinuousUnbounded()) { + return UNBOUNDED; + } + return FEASIBLE; + } + + void CbcMip::_setSense(Sense sense) { + switch (sense) { + case MIN: + _prob->setOptimizationDirection(1.0); + break; + case MAX: + _prob->setOptimizationDirection(- 1.0); + break; + } + } + + CbcMip::Sense CbcMip::_getSense() const { + if (_prob->optimizationDirection() > 0.0) { + return MIN; + } else if (_prob->optimizationDirection() < 0.0) { + return MAX; + } else { + LEMON_ASSERT(false, "Wrong sense"); + return CbcMip::Sense(); + } + } + + void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) { + switch (col_type){ + case INTEGER: + _prob->setInteger(i); + break; + case REAL: + _prob->setContinuous(i); + break; + default:; + LEMON_ASSERT(false, "Wrong sense"); + } + } + + CbcMip::ColTypes CbcMip::_getColType(int i) const { + return _prob->getColumnIsInteger(i) ? INTEGER : REAL; + } + + void CbcMip::_clear() { + delete _prob; + if (_osi_solver) { + delete _osi_solver; + _osi_solver = 0; + } + if (_cbc_model) { + delete _cbc_model; + _cbc_model = 0; + } + + _prob = new CoinModel(); + rows.clear(); + cols.clear(); + } + + void CbcMip::_messageLevel(MessageLevel level) { + switch (level) { + case MESSAGE_NOTHING: + _message_level = 0; + break; + case MESSAGE_ERROR: + _message_level = 1; + break; + case MESSAGE_WARNING: + _message_level = 1; + break; + case MESSAGE_NORMAL: + _message_level = 2; + break; + case MESSAGE_VERBOSE: + _message_level = 3; + break; + } + } + +} //END OF NAMESPACE LEMON diff --git a/lemon/lemon/cbc.h b/lemon/lemon/cbc.h new file mode 100644 index 0000000..2ff7a2d --- /dev/null +++ b/lemon/lemon/cbc.h @@ -0,0 +1,130 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +// -*- C++ -*- +#ifndef LEMON_CBC_H +#define LEMON_CBC_H + +///\file +///\brief Header of the LEMON-CBC mip solver interface. +///\ingroup lp_group + +#include + +class CoinModel; +class OsiSolverInterface; +class CbcModel; + +namespace lemon { + + /// \brief Interface for the CBC MIP solver + /// + /// This class implements an interface for the CBC MIP solver. + ///\ingroup lp_group + class CbcMip : public MipSolver { + protected: + + CoinModel *_prob; + OsiSolverInterface *_osi_solver; + CbcModel *_cbc_model; + + public: + + /// \e + CbcMip(); + /// \e + CbcMip(const CbcMip&); + /// \e + ~CbcMip(); + /// \e + virtual CbcMip* newSolver() const; + /// \e + virtual CbcMip* cloneSolver() const; + + protected: + + virtual const char* _solverName() const; + + virtual int _addCol(); + virtual int _addRow(); + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u); + + virtual void _eraseCol(int i); + virtual void _eraseRow(int i); + + virtual void _eraseColId(int i); + virtual void _eraseRowId(int i); + + virtual void _getColName(int col, std::string& name) const; + virtual void _setColName(int col, const std::string& name); + virtual int _colByName(const std::string& name) const; + + virtual void _getRowName(int row, std::string& name) const; + virtual void _setRowName(int row, const std::string& name); + virtual int _rowByName(const std::string& name) const; + + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getRowCoeffs(int i, InsertIterator b) const; + + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getColCoeffs(int i, InsertIterator b) const; + + virtual void _setCoeff(int row, int col, Value value); + virtual Value _getCoeff(int row, int col) const; + + virtual void _setColLowerBound(int i, Value value); + virtual Value _getColLowerBound(int i) const; + virtual void _setColUpperBound(int i, Value value); + virtual Value _getColUpperBound(int i) const; + + virtual void _setRowLowerBound(int i, Value value); + virtual Value _getRowLowerBound(int i) const; + virtual void _setRowUpperBound(int i, Value value); + virtual Value _getRowUpperBound(int i) const; + + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e); + virtual void _getObjCoeffs(InsertIterator b) const; + + virtual void _setObjCoeff(int i, Value obj_coef); + virtual Value _getObjCoeff(int i) const; + + virtual void _setSense(Sense sense); + virtual Sense _getSense() const; + + virtual ColTypes _getColType(int col) const; + virtual void _setColType(int col, ColTypes col_type); + + virtual SolveExitStatus _solve(); + virtual ProblemType _getType() const; + virtual Value _getSol(int i) const; + virtual Value _getSolValue() const; + + virtual void _clear(); + + virtual void _messageLevel(MessageLevel level); + void _applyMessageLevel(); + + int _message_level; + + + + }; + +} + +#endif diff --git a/lemon/lemon/circulation.h b/lemon/lemon/circulation.h new file mode 100644 index 0000000..a181517 --- /dev/null +++ b/lemon/lemon/circulation.h @@ -0,0 +1,808 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CIRCULATION_H +#define LEMON_CIRCULATION_H + +#include +#include +#include + +///\ingroup max_flow +///\file +///\brief Push-relabel algorithm for finding a feasible circulation. +/// +namespace lemon { + + /// \brief Default traits class of Circulation class. + /// + /// Default traits class of Circulation class. + /// + /// \tparam GR Type of the digraph the algorithm runs on. + /// \tparam LM The type of the lower bound map. + /// \tparam UM The type of the upper bound (capacity) map. + /// \tparam SM The type of the supply map. + template + struct CirculationDefaultTraits { + + /// \brief The type of the digraph the algorithm runs on. + typedef GR Digraph; + + /// \brief The type of the lower bound map. + /// + /// The type of the map that stores the lower bounds on the arcs. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. + typedef LM LowerMap; + + /// \brief The type of the upper bound (capacity) map. + /// + /// The type of the map that stores the upper bounds (capacities) + /// on the arcs. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. + typedef UM UpperMap; + + /// \brief The type of supply map. + /// + /// The type of the map that stores the signed supply values of the + /// nodes. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. + typedef SM SupplyMap; + + /// \brief The type of the flow and supply values. + typedef typename SupplyMap::Value Value; + + /// \brief The type of the map that stores the flow values. + /// + /// The type of the map that stores the flow values. + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" + /// concept. +#ifdef DOXYGEN + typedef GR::ArcMap FlowMap; +#else + typedef typename Digraph::template ArcMap FlowMap; +#endif + + /// \brief Instantiates a FlowMap. + /// + /// This function instantiates a \ref FlowMap. + /// \param digraph The digraph for which we would like to define + /// the flow map. + static FlowMap* createFlowMap(const Digraph& digraph) { + return new FlowMap(digraph); + } + + /// \brief The elevator type used by the algorithm. + /// + /// The elevator type used by the algorithm. + /// + /// \sa Elevator, LinkedElevator +#ifdef DOXYGEN + typedef lemon::Elevator Elevator; +#else + typedef lemon::Elevator Elevator; +#endif + + /// \brief Instantiates an Elevator. + /// + /// This function instantiates an \ref Elevator. + /// \param digraph The digraph for which we would like to define + /// the elevator. + /// \param max_level The maximum level of the elevator. + static Elevator* createElevator(const Digraph& digraph, int max_level) { + return new Elevator(digraph, max_level); + } + + /// \brief The tolerance used by the algorithm + /// + /// The tolerance used by the algorithm to handle inexact computation. + typedef lemon::Tolerance Tolerance; + + }; + + /** + \brief Push-relabel algorithm for the network circulation problem. + + \ingroup max_flow + This class implements a push-relabel algorithm for the \e network + \e circulation problem. + It is to find a feasible circulation when lower and upper bounds + are given for the flow values on the arcs and lower bounds are + given for the difference between the outgoing and incoming flow + at the nodes. + + The exact formulation of this problem is the following. + Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$ + \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and + upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$ + holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$ + denotes the signed supply values of the nodes. + If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$ + supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with + \f$-sup(u)\f$ demand. + A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$ + solution of the following problem. + + \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) + \geq sup(u) \quad \forall u\in V, \f] + \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f] + + The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be + zero or negative in order to have a feasible solution (since the sum + of the expressions on the left-hand side of the inequalities is zero). + It means that the total demand must be greater or equal to the total + supply and all the supplies have to be carried out from the supply nodes, + but there could be demands that are not satisfied. + If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand + constraints have to be satisfied with equality, i.e. all demands + have to be satisfied and all supplies have to be used. + + If you need the opposite inequalities in the supply/demand constraints + (i.e. the total demand is less than the total supply and all the demands + have to be satisfied while there could be supplies that are not used), + then you could easily transform the problem to the above form by reversing + the direction of the arcs and taking the negative of the supply values + (e.g. using \ref ReverseDigraph and \ref NegMap adaptors). + + This algorithm either calculates a feasible circulation, or provides + a \ref barrier() "barrier", which prooves that a feasible soultion + cannot exist. + + Note that this algorithm also provides a feasible solution for the + \ref min_cost_flow "minimum cost flow problem". + + \tparam GR The type of the digraph the algorithm runs on. + \tparam LM The type of the lower bound map. The default + map type is \ref concepts::Digraph::ArcMap "GR::ArcMap". + \tparam UM The type of the upper bound (capacity) map. + The default map type is \c LM. + \tparam SM The type of the supply map. The default map type is + \ref concepts::Digraph::NodeMap "GR::NodeMap". + \tparam TR The traits class that defines various types used by the + algorithm. By default, it is \ref CirculationDefaultTraits + "CirculationDefaultTraits". + In most cases, this parameter should not be set directly, + consider to use the named template parameters instead. + */ +#ifdef DOXYGEN +template< typename GR, + typename LM, + typename UM, + typename SM, + typename TR > +#else +template< typename GR, + typename LM = typename GR::template ArcMap, + typename UM = LM, + typename SM = typename GR::template NodeMap, + typename TR = CirculationDefaultTraits > +#endif + class Circulation { + public: + + ///The \ref CirculationDefaultTraits "traits class" of the algorithm. + typedef TR Traits; + ///The type of the digraph the algorithm runs on. + typedef typename Traits::Digraph Digraph; + ///The type of the flow and supply values. + typedef typename Traits::Value Value; + + ///The type of the lower bound map. + typedef typename Traits::LowerMap LowerMap; + ///The type of the upper bound (capacity) map. + typedef typename Traits::UpperMap UpperMap; + ///The type of the supply map. + typedef typename Traits::SupplyMap SupplyMap; + ///The type of the flow map. + typedef typename Traits::FlowMap FlowMap; + + ///The type of the elevator. + typedef typename Traits::Elevator Elevator; + ///The type of the tolerance. + typedef typename Traits::Tolerance Tolerance; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + const Digraph &_g; + int _node_num; + + const LowerMap *_lo; + const UpperMap *_up; + const SupplyMap *_supply; + + FlowMap *_flow; + bool _local_flow; + + Elevator* _level; + bool _local_level; + + typedef typename Digraph::template NodeMap ExcessMap; + ExcessMap* _excess; + + Tolerance _tol; + int _el; + + public: + + typedef Circulation Create; + + ///\name Named Template Parameters + + ///@{ + + template + struct SetFlowMapTraits : public Traits { + typedef T FlowMap; + static FlowMap *createFlowMap(const Digraph&) { + LEMON_ASSERT(false, "FlowMap is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// FlowMap type + /// + /// \ref named-templ-param "Named parameter" for setting FlowMap + /// type. + template + struct SetFlowMap + : public Circulation > { + typedef Circulation > Create; + }; + + template + struct SetElevatorTraits : public Traits { + typedef T Elevator; + static Elevator *createElevator(const Digraph&, int) { + LEMON_ASSERT(false, "Elevator is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// Elevator type + /// + /// \ref named-templ-param "Named parameter" for setting Elevator + /// type. If this named parameter is used, then an external + /// elevator object must be passed to the algorithm using the + /// \ref elevator(Elevator&) "elevator()" function before calling + /// \ref run() or \ref init(). + /// \sa SetStandardElevator + template + struct SetElevator + : public Circulation > { + typedef Circulation > Create; + }; + + template + struct SetStandardElevatorTraits : public Traits { + typedef T Elevator; + static Elevator *createElevator(const Digraph& digraph, int max_level) { + return new Elevator(digraph, max_level); + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// Elevator type with automatic allocation + /// + /// \ref named-templ-param "Named parameter" for setting Elevator + /// type with automatic allocation. + /// The Elevator should have standard constructor interface to be + /// able to automatically created by the algorithm (i.e. the + /// digraph and the maximum level should be passed to it). + /// However, an external elevator object could also be passed to the + /// algorithm with the \ref elevator(Elevator&) "elevator()" function + /// before calling \ref run() or \ref init(). + /// \sa SetElevator + template + struct SetStandardElevator + : public Circulation > { + typedef Circulation > Create; + }; + + /// @} + + protected: + + Circulation() {} + + public: + + /// Constructor. + + /// The constructor of the class. + /// + /// \param graph The digraph the algorithm runs on. + /// \param lower The lower bounds for the flow values on the arcs. + /// \param upper The upper bounds (capacities) for the flow values + /// on the arcs. + /// \param supply The signed supply values of the nodes. + Circulation(const Digraph &graph, const LowerMap &lower, + const UpperMap &upper, const SupplyMap &supply) + : _g(graph), _lo(&lower), _up(&upper), _supply(&supply), + _flow(NULL), _local_flow(false), _level(NULL), _local_level(false), + _excess(NULL) {} + + /// Destructor. + ~Circulation() { + destroyStructures(); + } + + + private: + + bool checkBoundMaps() { + for (ArcIt e(_g);e!=INVALID;++e) { + if (_tol.less((*_up)[e], (*_lo)[e])) return false; + } + return true; + } + + void createStructures() { + _node_num = _el = countNodes(_g); + + if (!_flow) { + _flow = Traits::createFlowMap(_g); + _local_flow = true; + } + if (!_level) { + _level = Traits::createElevator(_g, _node_num); + _local_level = true; + } + if (!_excess) { + _excess = new ExcessMap(_g); + } + } + + void destroyStructures() { + if (_local_flow) { + delete _flow; + } + if (_local_level) { + delete _level; + } + if (_excess) { + delete _excess; + } + } + + public: + + /// Sets the lower bound map. + + /// Sets the lower bound map. + /// \return (*this) + Circulation& lowerMap(const LowerMap& map) { + _lo = ↦ + return *this; + } + + /// Sets the upper bound (capacity) map. + + /// Sets the upper bound (capacity) map. + /// \return (*this) + Circulation& upperMap(const UpperMap& map) { + _up = ↦ + return *this; + } + + /// Sets the supply map. + + /// Sets the supply map. + /// \return (*this) + Circulation& supplyMap(const SupplyMap& map) { + _supply = ↦ + return *this; + } + + /// \brief Sets the flow map. + /// + /// Sets the flow map. + /// If you don't use this function before calling \ref run() or + /// \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated map, + /// of course. + /// \return (*this) + Circulation& flowMap(FlowMap& map) { + if (_local_flow) { + delete _flow; + _local_flow = false; + } + _flow = ↦ + return *this; + } + + /// \brief Sets the elevator used by algorithm. + /// + /// Sets the elevator used by algorithm. + /// If you don't use this function before calling \ref run() or + /// \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated elevator, + /// of course. + /// \return (*this) + Circulation& elevator(Elevator& elevator) { + if (_local_level) { + delete _level; + _local_level = false; + } + _level = &elevator; + return *this; + } + + /// \brief Returns a const reference to the elevator. + /// + /// Returns a const reference to the elevator. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const Elevator& elevator() const { + return *_level; + } + + /// \brief Sets the tolerance used by the algorithm. + /// + /// Sets the tolerance object used by the algorithm. + /// \return (*this) + Circulation& tolerance(const Tolerance& tolerance) { + _tol = tolerance; + return *this; + } + + /// \brief Returns a const reference to the tolerance. + /// + /// Returns a const reference to the tolerance object used by + /// the algorithm. + const Tolerance& tolerance() const { + return _tol; + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to call \ref run().\n + /// If you need better control on the initial solution or the execution, + /// you have to call one of the \ref init() functions first, then + /// the \ref start() function. + + ///@{ + + /// Initializes the internal data structures. + + /// Initializes the internal data structures and sets all flow values + /// to the lower bound. + void init() + { + LEMON_DEBUG(checkBoundMaps(), + "Upper bounds must be greater or equal to the lower bounds"); + + createStructures(); + + for(NodeIt n(_g);n!=INVALID;++n) { + (*_excess)[n] = (*_supply)[n]; + } + + for (ArcIt e(_g);e!=INVALID;++e) { + _flow->set(e, (*_lo)[e]); + (*_excess)[_g.target(e)] += (*_flow)[e]; + (*_excess)[_g.source(e)] -= (*_flow)[e]; + } + + // global relabeling tested, but in general case it provides + // worse performance for random digraphs + _level->initStart(); + for(NodeIt n(_g);n!=INVALID;++n) + _level->initAddItem(n); + _level->initFinish(); + for(NodeIt n(_g);n!=INVALID;++n) + if(_tol.positive((*_excess)[n])) + _level->activate(n); + } + + /// Initializes the internal data structures using a greedy approach. + + /// Initializes the internal data structures using a greedy approach + /// to construct the initial solution. + void greedyInit() + { + LEMON_DEBUG(checkBoundMaps(), + "Upper bounds must be greater or equal to the lower bounds"); + + createStructures(); + + for(NodeIt n(_g);n!=INVALID;++n) { + (*_excess)[n] = (*_supply)[n]; + } + + for (ArcIt e(_g);e!=INVALID;++e) { + if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) { + _flow->set(e, (*_up)[e]); + (*_excess)[_g.target(e)] += (*_up)[e]; + (*_excess)[_g.source(e)] -= (*_up)[e]; + } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) { + _flow->set(e, (*_lo)[e]); + (*_excess)[_g.target(e)] += (*_lo)[e]; + (*_excess)[_g.source(e)] -= (*_lo)[e]; + } else { + Value fc = -(*_excess)[_g.target(e)]; + _flow->set(e, fc); + (*_excess)[_g.target(e)] = 0; + (*_excess)[_g.source(e)] -= fc; + } + } + + _level->initStart(); + for(NodeIt n(_g);n!=INVALID;++n) + _level->initAddItem(n); + _level->initFinish(); + for(NodeIt n(_g);n!=INVALID;++n) + if(_tol.positive((*_excess)[n])) + _level->activate(n); + } + + ///Executes the algorithm + + ///This function executes the algorithm. + /// + ///\return \c true if a feasible circulation is found. + /// + ///\sa barrier() + ///\sa barrierMap() + bool start() + { + + Node act; + Node bact=INVALID; + Node last_activated=INVALID; + while((act=_level->highestActive())!=INVALID) { + int actlevel=(*_level)[act]; + int mlevel=_node_num; + Value exc=(*_excess)[act]; + + for(OutArcIt e(_g,act);e!=INVALID; ++e) { + Node v = _g.target(e); + Value fc=(*_up)[e]-(*_flow)[e]; + if(!_tol.positive(fc)) continue; + if((*_level)[v]set(e, (*_flow)[e] + exc); + (*_excess)[v] += exc; + if(!_level->active(v) && _tol.positive((*_excess)[v])) + _level->activate(v); + (*_excess)[act] = 0; + _level->deactivate(act); + goto next_l; + } + else { + _flow->set(e, (*_up)[e]); + (*_excess)[v] += fc; + if(!_level->active(v) && _tol.positive((*_excess)[v])) + _level->activate(v); + exc-=fc; + } + } + else if((*_level)[v]set(e, (*_flow)[e] - exc); + (*_excess)[v] += exc; + if(!_level->active(v) && _tol.positive((*_excess)[v])) + _level->activate(v); + (*_excess)[act] = 0; + _level->deactivate(act); + goto next_l; + } + else { + _flow->set(e, (*_lo)[e]); + (*_excess)[v] += fc; + if(!_level->active(v) && _tol.positive((*_excess)[v])) + _level->activate(v); + exc-=fc; + } + } + else if((*_level)[v]deactivate(act); + else if(mlevel==_node_num) { + _level->liftHighestActiveToTop(); + _el = _node_num; + return false; + } + else { + _level->liftHighestActive(mlevel+1); + if(_level->onLevel(actlevel)==0) { + _el = actlevel; + return false; + } + } + next_l: + ; + } + return true; + } + + /// Runs the algorithm. + + /// This function runs the algorithm. + /// + /// \return \c true if a feasible circulation is found. + /// + /// \note Apart from the return value, c.run() is just a shortcut of + /// the following code. + /// \code + /// c.greedyInit(); + /// c.start(); + /// \endcode + bool run() { + greedyInit(); + return start(); + } + + /// @} + + /// \name Query Functions + /// The results of the circulation algorithm can be obtained using + /// these functions.\n + /// Either \ref run() or \ref start() should be called before + /// using them. + + ///@{ + + /// \brief Returns the flow value on the given arc. + /// + /// Returns the flow value on the given arc. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + Value flow(const Arc& arc) const { + return (*_flow)[arc]; + } + + /// \brief Returns a const reference to the flow map. + /// + /// Returns a const reference to the arc map storing the found flow. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const FlowMap& flowMap() const { + return *_flow; + } + + /** + \brief Returns \c true if the given node is in a barrier. + + Barrier is a set \e B of nodes for which + + \f[ \sum_{uv\in A: u\in B} upper(uv) - + \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f] + + holds. The existence of a set with this property prooves that a + feasible circualtion cannot exist. + + This function returns \c true if the given node is in the found + barrier. If a feasible circulation is found, the function + gives back \c false for every node. + + \pre Either \ref run() or \ref init() must be called before + using this function. + + \sa barrierMap() + \sa checkBarrier() + */ + bool barrier(const Node& node) const + { + return (*_level)[node] >= _el; + } + + /// \brief Gives back a barrier. + /// + /// This function sets \c bar to the characteristic vector of the + /// found barrier. \c bar should be a \ref concepts::WriteMap "writable" + /// node map with \c bool (or convertible) value type. + /// + /// If a feasible circulation is found, the function gives back an + /// empty set, so \c bar[v] will be \c false for all nodes \c v. + /// + /// \note This function calls \ref barrier() for each node, + /// so it runs in O(n) time. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + /// + /// \sa barrier() + /// \sa checkBarrier() + template + void barrierMap(BarrierMap &bar) const + { + for(NodeIt n(_g);n!=INVALID;++n) + bar.set(n, (*_level)[n] >= _el); + } + + /// @} + + /// \name Checker Functions + /// The feasibility of the results can be checked using + /// these functions.\n + /// Either \ref run() or \ref start() should be called before + /// using them. + + ///@{ + + ///Check if the found flow is a feasible circulation + + ///Check if the found flow is a feasible circulation, + /// + bool checkFlow() const { + for(ArcIt e(_g);e!=INVALID;++e) + if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false; + for(NodeIt n(_g);n!=INVALID;++n) + { + Value dif=-(*_supply)[n]; + for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e]; + for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e]; + if(_tol.negative(dif)) return false; + } + return true; + } + + ///Check whether or not the last execution provides a barrier + + ///Check whether or not the last execution provides a barrier. + ///\sa barrier() + ///\sa barrierMap() + bool checkBarrier() const + { + Value delta=0; + Value inf_cap = std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max(); + for(NodeIt n(_g);n!=INVALID;++n) + if(barrier(n)) + delta-=(*_supply)[n]; + for(ArcIt e(_g);e!=INVALID;++e) + { + Node s=_g.source(e); + Node t=_g.target(e); + if(barrier(s)&&!barrier(t)) { + if (_tol.less(inf_cap - (*_up)[e], delta)) return false; + delta+=(*_up)[e]; + } + else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e]; + } + return _tol.negative(delta); + } + + /// @} + + }; + +} + +#endif diff --git a/lemon/lemon/clp.cc b/lemon/lemon/clp.cc new file mode 100644 index 0000000..1f5a49f --- /dev/null +++ b/lemon/lemon/clp.cc @@ -0,0 +1,466 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +namespace lemon { + + ClpLp::ClpLp() { + _prob = new ClpSimplex(); + _init_temporals(); + messageLevel(MESSAGE_NOTHING); + } + + ClpLp::ClpLp(const ClpLp& other) { + _prob = new ClpSimplex(*other._prob); + rows = other.rows; + cols = other.cols; + _init_temporals(); + messageLevel(MESSAGE_NOTHING); + } + + ClpLp::~ClpLp() { + delete _prob; + _clear_temporals(); + } + + void ClpLp::_init_temporals() { + _primal_ray = 0; + _dual_ray = 0; + } + + void ClpLp::_clear_temporals() { + if (_primal_ray) { + delete[] _primal_ray; + _primal_ray = 0; + } + if (_dual_ray) { + delete[] _dual_ray; + _dual_ray = 0; + } + } + + ClpLp* ClpLp::newSolver() const { + ClpLp* newlp = new ClpLp; + return newlp; + } + + ClpLp* ClpLp::cloneSolver() const { + ClpLp* copylp = new ClpLp(*this); + return copylp; + } + + const char* ClpLp::_solverName() const { return "ClpLp"; } + + int ClpLp::_addCol() { + _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0); + return _prob->numberColumns() - 1; + } + + int ClpLp::_addRow() { + _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX); + return _prob->numberRows() - 1; + } + + int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) { + std::vector indexes; + std::vector values; + + for(ExprIterator it = b; it != e; ++it) { + indexes.push_back(it->first); + values.push_back(it->second); + } + + _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u); + return _prob->numberRows() - 1; + } + + + void ClpLp::_eraseCol(int c) { + _col_names_ref.erase(_prob->getColumnName(c)); + _prob->deleteColumns(1, &c); + } + + void ClpLp::_eraseRow(int r) { + _row_names_ref.erase(_prob->getRowName(r)); + _prob->deleteRows(1, &r); + } + + void ClpLp::_eraseColId(int i) { + cols.eraseIndex(i); + cols.shiftIndices(i); + } + + void ClpLp::_eraseRowId(int i) { + rows.eraseIndex(i); + rows.shiftIndices(i); + } + + void ClpLp::_getColName(int c, std::string& name) const { + name = _prob->getColumnName(c); + } + + void ClpLp::_setColName(int c, const std::string& name) { + _prob->setColumnName(c, const_cast(name)); + _col_names_ref[name] = c; + } + + int ClpLp::_colByName(const std::string& name) const { + std::map::const_iterator it = _col_names_ref.find(name); + return it != _col_names_ref.end() ? it->second : -1; + } + + void ClpLp::_getRowName(int r, std::string& name) const { + name = _prob->getRowName(r); + } + + void ClpLp::_setRowName(int r, const std::string& name) { + _prob->setRowName(r, const_cast(name)); + _row_names_ref[name] = r; + } + + int ClpLp::_rowByName(const std::string& name) const { + std::map::const_iterator it = _row_names_ref.find(name); + return it != _row_names_ref.end() ? it->second : -1; + } + + + void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) { + std::map coeffs; + + int n = _prob->clpMatrix()->getNumCols(); + + const int* indices = _prob->clpMatrix()->getIndices(); + const double* elements = _prob->clpMatrix()->getElements(); + + for (int i = 0; i < n; ++i) { + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i]; + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i]; + + const int* it = std::lower_bound(indices + begin, indices + end, ix); + if (it != indices + end && *it == ix && elements[it - indices] != 0.0) { + coeffs[i] = 0.0; + } + } + + for (ExprIterator it = b; it != e; ++it) { + coeffs[it->first] = it->second; + } + + for (std::map::iterator it = coeffs.begin(); + it != coeffs.end(); ++it) { + _prob->modifyCoefficient(ix, it->first, it->second); + } + } + + void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const { + int n = _prob->clpMatrix()->getNumCols(); + + const int* indices = _prob->clpMatrix()->getIndices(); + const double* elements = _prob->clpMatrix()->getElements(); + + for (int i = 0; i < n; ++i) { + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i]; + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i]; + + const int* it = std::lower_bound(indices + begin, indices + end, ix); + if (it != indices + end && *it == ix) { + *b = std::make_pair(i, elements[it - indices]); + } + } + } + + void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) { + std::map coeffs; + + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix]; + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix]; + + const int* indices = _prob->clpMatrix()->getIndices(); + const double* elements = _prob->clpMatrix()->getElements(); + + for (CoinBigIndex i = begin; i != end; ++i) { + if (elements[i] != 0.0) { + coeffs[indices[i]] = 0.0; + } + } + for (ExprIterator it = b; it != e; ++it) { + coeffs[it->first] = it->second; + } + for (std::map::iterator it = coeffs.begin(); + it != coeffs.end(); ++it) { + _prob->modifyCoefficient(it->first, ix, it->second); + } + } + + void ClpLp::_getColCoeffs(int ix, InsertIterator b) const { + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix]; + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix]; + + const int* indices = _prob->clpMatrix()->getIndices(); + const double* elements = _prob->clpMatrix()->getElements(); + + for (CoinBigIndex i = begin; i != end; ++i) { + *b = std::make_pair(indices[i], elements[i]); + ++b; + } + } + + void ClpLp::_setCoeff(int ix, int jx, Value value) { + _prob->modifyCoefficient(ix, jx, value); + } + + ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const { + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix]; + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix]; + + const int* indices = _prob->clpMatrix()->getIndices(); + const double* elements = _prob->clpMatrix()->getElements(); + + const int* it = std::lower_bound(indices + begin, indices + end, jx); + if (it != indices + end && *it == jx) { + return elements[it - indices]; + } else { + return 0.0; + } + } + + void ClpLp::_setColLowerBound(int i, Value lo) { + _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo); + } + + ClpLp::Value ClpLp::_getColLowerBound(int i) const { + double val = _prob->getColLower()[i]; + return val == - COIN_DBL_MAX ? - INF : val; + } + + void ClpLp::_setColUpperBound(int i, Value up) { + _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up); + } + + ClpLp::Value ClpLp::_getColUpperBound(int i) const { + double val = _prob->getColUpper()[i]; + return val == COIN_DBL_MAX ? INF : val; + } + + void ClpLp::_setRowLowerBound(int i, Value lo) { + _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo); + } + + ClpLp::Value ClpLp::_getRowLowerBound(int i) const { + double val = _prob->getRowLower()[i]; + return val == - COIN_DBL_MAX ? - INF : val; + } + + void ClpLp::_setRowUpperBound(int i, Value up) { + _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up); + } + + ClpLp::Value ClpLp::_getRowUpperBound(int i) const { + double val = _prob->getRowUpper()[i]; + return val == COIN_DBL_MAX ? INF : val; + } + + void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) { + int num = _prob->clpMatrix()->getNumCols(); + for (int i = 0; i < num; ++i) { + _prob->setObjectiveCoefficient(i, 0.0); + } + for (ExprIterator it = b; it != e; ++it) { + _prob->setObjectiveCoefficient(it->first, it->second); + } + } + + void ClpLp::_getObjCoeffs(InsertIterator b) const { + int num = _prob->clpMatrix()->getNumCols(); + for (int i = 0; i < num; ++i) { + Value coef = _prob->getObjCoefficients()[i]; + if (coef != 0.0) { + *b = std::make_pair(i, coef); + ++b; + } + } + } + + void ClpLp::_setObjCoeff(int i, Value obj_coef) { + _prob->setObjectiveCoefficient(i, obj_coef); + } + + ClpLp::Value ClpLp::_getObjCoeff(int i) const { + return _prob->getObjCoefficients()[i]; + } + + ClpLp::SolveExitStatus ClpLp::_solve() { + return _prob->primal() >= 0 ? SOLVED : UNSOLVED; + } + + ClpLp::SolveExitStatus ClpLp::solvePrimal() { + return _prob->primal() >= 0 ? SOLVED : UNSOLVED; + } + + ClpLp::SolveExitStatus ClpLp::solveDual() { + return _prob->dual() >= 0 ? SOLVED : UNSOLVED; + } + + ClpLp::SolveExitStatus ClpLp::solveBarrier() { + return _prob->barrier() >= 0 ? SOLVED : UNSOLVED; + } + + ClpLp::Value ClpLp::_getPrimal(int i) const { + return _prob->primalColumnSolution()[i]; + } + ClpLp::Value ClpLp::_getPrimalValue() const { + return _prob->objectiveValue(); + } + + ClpLp::Value ClpLp::_getDual(int i) const { + return _prob->dualRowSolution()[i]; + } + + ClpLp::Value ClpLp::_getPrimalRay(int i) const { + if (!_primal_ray) { + _primal_ray = _prob->unboundedRay(); + LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided"); + } + return _primal_ray[i]; + } + + ClpLp::Value ClpLp::_getDualRay(int i) const { + if (!_dual_ray) { + _dual_ray = _prob->infeasibilityRay(); + LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided"); + } + return _dual_ray[i]; + } + + ClpLp::VarStatus ClpLp::_getColStatus(int i) const { + switch (_prob->getColumnStatus(i)) { + case ClpSimplex::basic: + return BASIC; + case ClpSimplex::isFree: + return FREE; + case ClpSimplex::atUpperBound: + return UPPER; + case ClpSimplex::atLowerBound: + return LOWER; + case ClpSimplex::isFixed: + return FIXED; + case ClpSimplex::superBasic: + return FREE; + default: + LEMON_ASSERT(false, "Wrong column status"); + return VarStatus(); + } + } + + ClpLp::VarStatus ClpLp::_getRowStatus(int i) const { + switch (_prob->getColumnStatus(i)) { + case ClpSimplex::basic: + return BASIC; + case ClpSimplex::isFree: + return FREE; + case ClpSimplex::atUpperBound: + return UPPER; + case ClpSimplex::atLowerBound: + return LOWER; + case ClpSimplex::isFixed: + return FIXED; + case ClpSimplex::superBasic: + return FREE; + default: + LEMON_ASSERT(false, "Wrong row status"); + return VarStatus(); + } + } + + + ClpLp::ProblemType ClpLp::_getPrimalType() const { + if (_prob->isProvenOptimal()) { + return OPTIMAL; + } else if (_prob->isProvenPrimalInfeasible()) { + return INFEASIBLE; + } else if (_prob->isProvenDualInfeasible()) { + return UNBOUNDED; + } else { + return UNDEFINED; + } + } + + ClpLp::ProblemType ClpLp::_getDualType() const { + if (_prob->isProvenOptimal()) { + return OPTIMAL; + } else if (_prob->isProvenDualInfeasible()) { + return INFEASIBLE; + } else if (_prob->isProvenPrimalInfeasible()) { + return INFEASIBLE; + } else { + return UNDEFINED; + } + } + + void ClpLp::_setSense(ClpLp::Sense sense) { + switch (sense) { + case MIN: + _prob->setOptimizationDirection(1); + break; + case MAX: + _prob->setOptimizationDirection(-1); + break; + } + } + + ClpLp::Sense ClpLp::_getSense() const { + double dir = _prob->optimizationDirection(); + if (dir > 0.0) { + return MIN; + } else { + return MAX; + } + } + + void ClpLp::_clear() { + delete _prob; + _prob = new ClpSimplex(); + rows.clear(); + cols.clear(); + _col_names_ref.clear(); + _clear_temporals(); + } + + void ClpLp::_messageLevel(MessageLevel level) { + switch (level) { + case MESSAGE_NOTHING: + _prob->setLogLevel(0); + break; + case MESSAGE_ERROR: + _prob->setLogLevel(1); + break; + case MESSAGE_WARNING: + _prob->setLogLevel(2); + break; + case MESSAGE_NORMAL: + _prob->setLogLevel(3); + break; + case MESSAGE_VERBOSE: + _prob->setLogLevel(4); + break; + } + } + +} //END OF NAMESPACE LEMON diff --git a/lemon/lemon/clp.h b/lemon/lemon/clp.h new file mode 100644 index 0000000..4091284 --- /dev/null +++ b/lemon/lemon/clp.h @@ -0,0 +1,164 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CLP_H +#define LEMON_CLP_H + +///\file +///\brief Header of the LEMON-CLP lp solver interface. + +#include +#include + +#include + +class ClpSimplex; + +namespace lemon { + + /// \ingroup lp_group + /// + /// \brief Interface for the CLP solver + /// + /// This class implements an interface for the Clp LP solver. The + /// Clp library is an object oriented lp solver library developed at + /// the IBM. The CLP is part of the COIN-OR package and it can be + /// used with Common Public License. + class ClpLp : public LpSolver { + protected: + + ClpSimplex* _prob; + + std::map _col_names_ref; + std::map _row_names_ref; + + public: + + /// \e + ClpLp(); + /// \e + ClpLp(const ClpLp&); + /// \e + ~ClpLp(); + + /// \e + virtual ClpLp* newSolver() const; + /// \e + virtual ClpLp* cloneSolver() const; + + protected: + + mutable double* _primal_ray; + mutable double* _dual_ray; + + void _init_temporals(); + void _clear_temporals(); + + protected: + + virtual const char* _solverName() const; + + virtual int _addCol(); + virtual int _addRow(); + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u); + + virtual void _eraseCol(int i); + virtual void _eraseRow(int i); + + virtual void _eraseColId(int i); + virtual void _eraseRowId(int i); + + virtual void _getColName(int col, std::string& name) const; + virtual void _setColName(int col, const std::string& name); + virtual int _colByName(const std::string& name) const; + + virtual void _getRowName(int row, std::string& name) const; + virtual void _setRowName(int row, const std::string& name); + virtual int _rowByName(const std::string& name) const; + + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getRowCoeffs(int i, InsertIterator b) const; + + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getColCoeffs(int i, InsertIterator b) const; + + virtual void _setCoeff(int row, int col, Value value); + virtual Value _getCoeff(int row, int col) const; + + virtual void _setColLowerBound(int i, Value value); + virtual Value _getColLowerBound(int i) const; + virtual void _setColUpperBound(int i, Value value); + virtual Value _getColUpperBound(int i) const; + + virtual void _setRowLowerBound(int i, Value value); + virtual Value _getRowLowerBound(int i) const; + virtual void _setRowUpperBound(int i, Value value); + virtual Value _getRowUpperBound(int i) const; + + virtual void _setObjCoeffs(ExprIterator, ExprIterator); + virtual void _getObjCoeffs(InsertIterator) const; + + virtual void _setObjCoeff(int i, Value obj_coef); + virtual Value _getObjCoeff(int i) const; + + virtual void _setSense(Sense sense); + virtual Sense _getSense() const; + + virtual SolveExitStatus _solve(); + + virtual Value _getPrimal(int i) const; + virtual Value _getDual(int i) const; + + virtual Value _getPrimalValue() const; + + virtual Value _getPrimalRay(int i) const; + virtual Value _getDualRay(int i) const; + + virtual VarStatus _getColStatus(int i) const; + virtual VarStatus _getRowStatus(int i) const; + + virtual ProblemType _getPrimalType() const; + virtual ProblemType _getDualType() const; + + virtual void _clear(); + + virtual void _messageLevel(MessageLevel); + + public: + + ///Solves LP with primal simplex method. + SolveExitStatus solvePrimal(); + + ///Solves LP with dual simplex method. + SolveExitStatus solveDual(); + + ///Solves LP with barrier method. + SolveExitStatus solveBarrier(); + + ///Returns the constraint identifier understood by CLP. + int clpRow(Row r) const { return rows(id(r)); } + + ///Returns the variable identifier understood by CLP. + int clpCol(Col c) const { return cols(id(c)); } + + }; + +} //END OF NAMESPACE LEMON + +#endif //LEMON_CLP_H + diff --git a/lemon/lemon/color.cc b/lemon/lemon/color.cc new file mode 100644 index 0000000..a49167b --- /dev/null +++ b/lemon/lemon/color.cc @@ -0,0 +1,44 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Color constants + +#include + +namespace lemon { + + const Color WHITE(1,1,1); + + const Color BLACK(0,0,0); + const Color RED(1,0,0); + const Color GREEN(0,1,0); + const Color BLUE(0,0,1); + const Color YELLOW(1,1,0); + const Color MAGENTA(1,0,1); + const Color CYAN(0,1,1); + + const Color GREY(0,0,0); + const Color DARK_RED(.5,0,0); + const Color DARK_GREEN(0,.5,0); + const Color DARK_BLUE(0,0,.5); + const Color DARK_YELLOW(.5,.5,0); + const Color DARK_MAGENTA(.5,0,.5); + const Color DARK_CYAN(0,.5,.5); + +} //namespace lemon diff --git a/lemon/lemon/color.h b/lemon/lemon/color.h new file mode 100644 index 0000000..0235791 --- /dev/null +++ b/lemon/lemon/color.h @@ -0,0 +1,204 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_COLOR_H +#define LEMON_COLOR_H + +#include +#include +#include + + +///\ingroup misc +///\file +///\brief Tools to manage RGB colors. + +namespace lemon { + + + /// \addtogroup misc + /// @{ + + ///Data structure representing RGB colors. + + ///Data structure representing RGB colors. + class Color + { + double _r,_g,_b; + public: + ///Default constructor + Color() {} + ///Constructor + Color(double r,double g,double b) :_r(r),_g(g),_b(b) {}; + ///Set the red component + double & red() {return _r;} + ///Return the red component + const double & red() const {return _r;} + ///Set the green component + double & green() {return _g;} + ///Return the green component + const double & green() const {return _g;} + ///Set the blue component + double & blue() {return _b;} + ///Return the blue component + const double & blue() const {return _b;} + ///Set the color components + void set(double r,double g,double b) { _r=r;_g=g;_b=b; }; + }; + + /// White color constant + extern const Color WHITE; + /// Black color constant + extern const Color BLACK; + /// Red color constant + extern const Color RED; + /// Green color constant + extern const Color GREEN; + /// Blue color constant + extern const Color BLUE; + /// Yellow color constant + extern const Color YELLOW; + /// Magenta color constant + extern const Color MAGENTA; + /// Cyan color constant + extern const Color CYAN; + /// Grey color constant + extern const Color GREY; + /// Dark red color constant + extern const Color DARK_RED; + /// Dark green color constant + extern const Color DARK_GREEN; + /// Drak blue color constant + extern const Color DARK_BLUE; + /// Dark yellow color constant + extern const Color DARK_YELLOW; + /// Dark magenta color constant + extern const Color DARK_MAGENTA; + /// Dark cyan color constant + extern const Color DARK_CYAN; + + ///Map ints to different Colors + + ///This map assigns one of the predefined \ref Color "Color"s to + ///each int. It is possible to change the colors as well as + ///their number. The integer range is cyclically mapped to the + ///provided set of colors. + /// + ///This is a true \ref concepts::ReferenceMap "reference map", so + ///you can also change the actual colors. + + class Palette : public MapBase + { + std::vector colors; + public: + ///Constructor + + ///Constructor. + ///\param have_white Indicates whether white is among the + ///provided initial colors (\c true) or not (\c false). If it is true, + ///white will be assigned to \c 0. + ///\param num The number of the allocated colors. If it is \c -1, + ///the default color configuration is set up (26 color plus optionaly the + ///white). If \c num is less then 26/27 then the default color + ///list is cut. Otherwise the color list is filled repeatedly with + ///the default color list. (The colors can be changed later on.) + Palette(bool have_white=false,int num=-1) + { + if (num==0) return; + do { + if(have_white) colors.push_back(Color(1,1,1)); + + colors.push_back(Color(0,0,0)); + colors.push_back(Color(1,0,0)); + colors.push_back(Color(0,1,0)); + colors.push_back(Color(0,0,1)); + colors.push_back(Color(1,1,0)); + colors.push_back(Color(1,0,1)); + colors.push_back(Color(0,1,1)); + + colors.push_back(Color(.5,0,0)); + colors.push_back(Color(0,.5,0)); + colors.push_back(Color(0,0,.5)); + colors.push_back(Color(.5,.5,0)); + colors.push_back(Color(.5,0,.5)); + colors.push_back(Color(0,.5,.5)); + + colors.push_back(Color(.5,.5,.5)); + colors.push_back(Color(1,.5,.5)); + colors.push_back(Color(.5,1,.5)); + colors.push_back(Color(.5,.5,1)); + colors.push_back(Color(1,1,.5)); + colors.push_back(Color(1,.5,1)); + colors.push_back(Color(.5,1,1)); + + colors.push_back(Color(1,.5,0)); + colors.push_back(Color(.5,1,0)); + colors.push_back(Color(1,0,.5)); + colors.push_back(Color(0,1,.5)); + colors.push_back(Color(0,.5,1)); + colors.push_back(Color(.5,0,1)); + } while(int(colors.size())=0) colors.resize(num); + } + ///\e + Color &operator[](int i) + { + return colors[i%colors.size()]; + } + ///\e + const Color &operator[](int i) const + { + return colors[i%colors.size()]; + } + ///\e + void set(int i,const Color &c) + { + colors[i%colors.size()]=c; + } + ///Adds a new color to the end of the color list. + void add(const Color &c) + { + colors.push_back(c); + } + + ///Sets the number of the existing colors. + void resize(int s) { colors.resize(s);} + ///Returns the number of the existing colors. + int size() const { return int(colors.size());} + }; + + ///Returns a visibly distinct \ref Color + + ///Returns a \ref Color which is as different from the given parameter + ///as it is possible. + inline Color distantColor(const Color &c) + { + return Color(c.red()<.5?1:0,c.green()<.5?1:0,c.blue()<.5?1:0); + } + ///Returns black for light colors and white for the dark ones. + + ///Returns black for light colors and white for the dark ones. + inline Color distantBW(const Color &c){ + return (.2125*c.red()+.7154*c.green()+.0721*c.blue())<.5 ? WHITE : BLACK; + } + + /// @} + +} //END OF NAMESPACE LEMON + +#endif // LEMON_COLOR_H diff --git a/lemon/lemon/concept_check.h b/lemon/lemon/concept_check.h new file mode 100644 index 0000000..200cf03 --- /dev/null +++ b/lemon/lemon/concept_check.h @@ -0,0 +1,61 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +// The contents of this file was inspired by the concept checking +// utility of the BOOST library (http://www.boost.org). + +///\file +///\brief Basic utilities for concept checking. +/// + +#ifndef LEMON_CONCEPT_CHECK_H +#define LEMON_CONCEPT_CHECK_H + +namespace lemon { + + /* + "inline" is used for ignore_unused_variable_warning() + and function_requires() to make sure there is no + overtarget with g++. + */ + + template inline void ignore_unused_variable_warning(const T&) { } + + ///\e + template + inline void function_requires() + { +#if !defined(NDEBUG) + void (Concept::*x)() = & Concept::constraints; + ignore_unused_variable_warning(x); +#endif + } + + ///\e + template + inline void checkConcept() { +#if !defined(NDEBUG) + typedef typename Concept::template Constraints ConceptCheck; + void (ConceptCheck::*x)() = & ConceptCheck::constraints; + ignore_unused_variable_warning(x); +#endif + } + +} // namespace lemon + +#endif // LEMON_CONCEPT_CHECK_H diff --git a/lemon/lemon/concepts/digraph.h b/lemon/lemon/concepts/digraph.h new file mode 100644 index 0000000..33b6c10 --- /dev/null +++ b/lemon/lemon/concepts/digraph.h @@ -0,0 +1,489 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CONCEPTS_DIGRAPH_H +#define LEMON_CONCEPTS_DIGRAPH_H + +///\ingroup graph_concepts +///\file +///\brief The concept of directed graphs. + +#include +#include +#include +#include + +namespace lemon { + namespace concepts { + + /// \ingroup graph_concepts + /// + /// \brief Class describing the concept of directed graphs. + /// + /// This class describes the common interface of all directed + /// graphs (digraphs). + /// + /// Like all concept classes, it only provides an interface + /// without any sensible implementation. So any general algorithm for + /// directed graphs should compile with this class, but it will not + /// run properly, of course. + /// An actual digraph implementation like \ref ListDigraph or + /// \ref SmartDigraph may have additional functionality. + /// + /// \sa Graph + class Digraph { + private: + /// Diraphs are \e not copy constructible. Use DigraphCopy instead. + Digraph(const Digraph &) {} + /// \brief Assignment of a digraph to another one is \e not allowed. + /// Use DigraphCopy instead. + void operator=(const Digraph &) {} + + public: + /// Default constructor. + Digraph() { } + + /// The node type of the digraph + + /// This class identifies a node of the digraph. It also serves + /// as a base class of the node iterators, + /// thus they convert to this type. + class Node { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the object to an undefined value. + Node() { } + /// Copy constructor. + + /// Copy constructor. + /// + Node(const Node&) { } + + /// %Invalid constructor \& conversion. + + /// Initializes the object to be invalid. + /// \sa Invalid for more details. + Node(Invalid) { } + /// Equality operator + + /// Equality operator. + /// + /// Two iterators are equal if and only if they point to the + /// same object or both are \c INVALID. + bool operator==(Node) const { return true; } + + /// Inequality operator + + /// Inequality operator. + bool operator!=(Node) const { return true; } + + /// Artificial ordering operator. + + /// Artificial ordering operator. + /// + /// \note This operator only has to define some strict ordering of + /// the nodes; this order has nothing to do with the iteration + /// ordering of the nodes. + bool operator<(Node) const { return false; } + }; + + /// Iterator class for the nodes. + + /// This iterator goes through each node of the digraph. + /// Its usage is quite simple, for example, you can count the number + /// of nodes in a digraph \c g of type \c %Digraph like this: + ///\code + /// int count=0; + /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count; + ///\endcode + class NodeIt : public Node { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + NodeIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + NodeIt(const NodeIt& n) : Node(n) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + NodeIt(Invalid) { } + /// Sets the iterator to the first node. + + /// Sets the iterator to the first node of the given digraph. + /// + explicit NodeIt(const Digraph&) { } + /// Sets the iterator to the given node. + + /// Sets the iterator to the given node of the given digraph. + /// + NodeIt(const Digraph&, const Node&) { } + /// Next node. + + /// Assign the iterator to the next node. + /// + NodeIt& operator++() { return *this; } + }; + + + /// The arc type of the digraph + + /// This class identifies an arc of the digraph. It also serves + /// as a base class of the arc iterators, + /// thus they will convert to this type. + class Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the object to an undefined value. + Arc() { } + /// Copy constructor. + + /// Copy constructor. + /// + Arc(const Arc&) { } + /// %Invalid constructor \& conversion. + + /// Initializes the object to be invalid. + /// \sa Invalid for more details. + Arc(Invalid) { } + /// Equality operator + + /// Equality operator. + /// + /// Two iterators are equal if and only if they point to the + /// same object or both are \c INVALID. + bool operator==(Arc) const { return true; } + /// Inequality operator + + /// Inequality operator. + bool operator!=(Arc) const { return true; } + + /// Artificial ordering operator. + + /// Artificial ordering operator. + /// + /// \note This operator only has to define some strict ordering of + /// the arcs; this order has nothing to do with the iteration + /// ordering of the arcs. + bool operator<(Arc) const { return false; } + }; + + /// Iterator class for the outgoing arcs of a node. + + /// This iterator goes trough the \e outgoing arcs of a certain node + /// of a digraph. + /// Its usage is quite simple, for example, you can count the number + /// of outgoing arcs of a node \c n + /// in a digraph \c g of type \c %Digraph as follows. + ///\code + /// int count=0; + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count; + ///\endcode + class OutArcIt : public Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + OutArcIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + OutArcIt(const OutArcIt& e) : Arc(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + OutArcIt(Invalid) { } + /// Sets the iterator to the first outgoing arc. + + /// Sets the iterator to the first outgoing arc of the given node. + /// + OutArcIt(const Digraph&, const Node&) { } + /// Sets the iterator to the given arc. + + /// Sets the iterator to the given arc of the given digraph. + /// + OutArcIt(const Digraph&, const Arc&) { } + /// Next outgoing arc + + /// Assign the iterator to the next + /// outgoing arc of the corresponding node. + OutArcIt& operator++() { return *this; } + }; + + /// Iterator class for the incoming arcs of a node. + + /// This iterator goes trough the \e incoming arcs of a certain node + /// of a digraph. + /// Its usage is quite simple, for example, you can count the number + /// of incoming arcs of a node \c n + /// in a digraph \c g of type \c %Digraph as follows. + ///\code + /// int count=0; + /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count; + ///\endcode + class InArcIt : public Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + InArcIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + InArcIt(const InArcIt& e) : Arc(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + InArcIt(Invalid) { } + /// Sets the iterator to the first incoming arc. + + /// Sets the iterator to the first incoming arc of the given node. + /// + InArcIt(const Digraph&, const Node&) { } + /// Sets the iterator to the given arc. + + /// Sets the iterator to the given arc of the given digraph. + /// + InArcIt(const Digraph&, const Arc&) { } + /// Next incoming arc + + /// Assign the iterator to the next + /// incoming arc of the corresponding node. + InArcIt& operator++() { return *this; } + }; + + /// Iterator class for the arcs. + + /// This iterator goes through each arc of the digraph. + /// Its usage is quite simple, for example, you can count the number + /// of arcs in a digraph \c g of type \c %Digraph as follows: + ///\code + /// int count=0; + /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count; + ///\endcode + class ArcIt : public Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + ArcIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + ArcIt(const ArcIt& e) : Arc(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + ArcIt(Invalid) { } + /// Sets the iterator to the first arc. + + /// Sets the iterator to the first arc of the given digraph. + /// + explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); } + /// Sets the iterator to the given arc. + + /// Sets the iterator to the given arc of the given digraph. + /// + ArcIt(const Digraph&, const Arc&) { } + /// Next arc + + /// Assign the iterator to the next arc. + /// + ArcIt& operator++() { return *this; } + }; + + /// \brief The source node of the arc. + /// + /// Returns the source node of the given arc. + Node source(Arc) const { return INVALID; } + + /// \brief The target node of the arc. + /// + /// Returns the target node of the given arc. + Node target(Arc) const { return INVALID; } + + /// \brief The ID of the node. + /// + /// Returns the ID of the given node. + int id(Node) const { return -1; } + + /// \brief The ID of the arc. + /// + /// Returns the ID of the given arc. + int id(Arc) const { return -1; } + + /// \brief The node with the given ID. + /// + /// Returns the node with the given ID. + /// \pre The argument should be a valid node ID in the digraph. + Node nodeFromId(int) const { return INVALID; } + + /// \brief The arc with the given ID. + /// + /// Returns the arc with the given ID. + /// \pre The argument should be a valid arc ID in the digraph. + Arc arcFromId(int) const { return INVALID; } + + /// \brief An upper bound on the node IDs. + /// + /// Returns an upper bound on the node IDs. + int maxNodeId() const { return -1; } + + /// \brief An upper bound on the arc IDs. + /// + /// Returns an upper bound on the arc IDs. + int maxArcId() const { return -1; } + + void first(Node&) const {} + void next(Node&) const {} + + void first(Arc&) const {} + void next(Arc&) const {} + + + void firstIn(Arc&, const Node&) const {} + void nextIn(Arc&) const {} + + void firstOut(Arc&, const Node&) const {} + void nextOut(Arc&) const {} + + // The second parameter is dummy. + Node fromId(int, Node) const { return INVALID; } + // The second parameter is dummy. + Arc fromId(int, Arc) const { return INVALID; } + + // Dummy parameter. + int maxId(Node) const { return -1; } + // Dummy parameter. + int maxId(Arc) const { return -1; } + + /// \brief The opposite node on the arc. + /// + /// Returns the opposite node on the given arc. + Node oppositeNode(Node, Arc) const { return INVALID; } + + /// \brief The base node of the iterator. + /// + /// Returns the base node of the given outgoing arc iterator + /// (i.e. the source node of the corresponding arc). + Node baseNode(OutArcIt) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// Returns the running node of the given outgoing arc iterator + /// (i.e. the target node of the corresponding arc). + Node runningNode(OutArcIt) const { return INVALID; } + + /// \brief The base node of the iterator. + /// + /// Returns the base node of the given incomming arc iterator + /// (i.e. the target node of the corresponding arc). + Node baseNode(InArcIt) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// Returns the running node of the given incomming arc iterator + /// (i.e. the source node of the corresponding arc). + Node runningNode(InArcIt) const { return INVALID; } + + /// \brief Standard graph map type for the nodes. + /// + /// Standard graph map type for the nodes. + /// It conforms to the ReferenceMap concept. + template + class NodeMap : public ReferenceMap { + public: + + /// Constructor + explicit NodeMap(const Digraph&) { } + /// Constructor with given initial value + NodeMap(const Digraph&, T) { } + + private: + ///Copy constructor + NodeMap(const NodeMap& nm) : + ReferenceMap(nm) { } + ///Assignment operator + template + NodeMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + }; + + /// \brief Standard graph map type for the arcs. + /// + /// Standard graph map type for the arcs. + /// It conforms to the ReferenceMap concept. + template + class ArcMap : public ReferenceMap { + public: + + /// Constructor + explicit ArcMap(const Digraph&) { } + /// Constructor with given initial value + ArcMap(const Digraph&, T) { } + + private: + ///Copy constructor + ArcMap(const ArcMap& em) : + ReferenceMap(em) { } + ///Assignment operator + template + ArcMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + }; + + template + struct Constraints { + void constraints() { + checkConcept(); + checkConcept, _Digraph>(); + checkConcept, _Digraph>(); + checkConcept, _Digraph>(); + } + }; + + }; + + } //namespace concepts +} //namespace lemon + + + +#endif diff --git a/lemon/lemon/concepts/graph.h b/lemon/lemon/concepts/graph.h new file mode 100644 index 0000000..0f35dda5 --- /dev/null +++ b/lemon/lemon/concepts/graph.h @@ -0,0 +1,786 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup graph_concepts +///\file +///\brief The concept of undirected graphs. + +#ifndef LEMON_CONCEPTS_GRAPH_H +#define LEMON_CONCEPTS_GRAPH_H + +#include +#include +#include +#include + +namespace lemon { + namespace concepts { + + /// \ingroup graph_concepts + /// + /// \brief Class describing the concept of undirected graphs. + /// + /// This class describes the common interface of all undirected + /// graphs. + /// + /// Like all concept classes, it only provides an interface + /// without any sensible implementation. So any general algorithm for + /// undirected graphs should compile with this class, but it will not + /// run properly, of course. + /// An actual graph implementation like \ref ListGraph or + /// \ref SmartGraph may have additional functionality. + /// + /// The undirected graphs also fulfill the concept of \ref Digraph + /// "directed graphs", since each edge can also be regarded as two + /// oppositely directed arcs. + /// Undirected graphs provide an Edge type for the undirected edges and + /// an Arc type for the directed arcs. The Arc type is convertible to + /// Edge or inherited from it, i.e. the corresponding edge can be + /// obtained from an arc. + /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt + /// and ArcMap classes can be used for the arcs (just like in digraphs). + /// Both InArcIt and OutArcIt iterates on the same edges but with + /// opposite direction. IncEdgeIt also iterates on the same edges + /// as OutArcIt and InArcIt, but it is not convertible to Arc, + /// only to Edge. + /// + /// In LEMON, each undirected edge has an inherent orientation. + /// Thus it can defined if an arc is forward or backward oriented in + /// an undirected graph with respect to this default oriantation of + /// the represented edge. + /// With the direction() and direct() functions the direction + /// of an arc can be obtained and set, respectively. + /// + /// Only nodes and edges can be added to or removed from an undirected + /// graph and the corresponding arcs are added or removed automatically. + /// + /// \sa Digraph + class Graph { + private: + /// Graphs are \e not copy constructible. Use DigraphCopy instead. + Graph(const Graph&) {} + /// \brief Assignment of a graph to another one is \e not allowed. + /// Use DigraphCopy instead. + void operator=(const Graph&) {} + + public: + /// Default constructor. + Graph() {} + + /// \brief Undirected graphs should be tagged with \c UndirectedTag. + /// + /// Undirected graphs should be tagged with \c UndirectedTag. + /// + /// This tag helps the \c enable_if technics to make compile time + /// specializations for undirected graphs. + typedef True UndirectedTag; + + /// The node type of the graph + + /// This class identifies a node of the graph. It also serves + /// as a base class of the node iterators, + /// thus they convert to this type. + class Node { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the object to an undefined value. + Node() { } + /// Copy constructor. + + /// Copy constructor. + /// + Node(const Node&) { } + + /// %Invalid constructor \& conversion. + + /// Initializes the object to be invalid. + /// \sa Invalid for more details. + Node(Invalid) { } + /// Equality operator + + /// Equality operator. + /// + /// Two iterators are equal if and only if they point to the + /// same object or both are \c INVALID. + bool operator==(Node) const { return true; } + + /// Inequality operator + + /// Inequality operator. + bool operator!=(Node) const { return true; } + + /// Artificial ordering operator. + + /// Artificial ordering operator. + /// + /// \note This operator only has to define some strict ordering of + /// the items; this order has nothing to do with the iteration + /// ordering of the items. + bool operator<(Node) const { return false; } + + }; + + /// Iterator class for the nodes. + + /// This iterator goes through each node of the graph. + /// Its usage is quite simple, for example, you can count the number + /// of nodes in a graph \c g of type \c %Graph like this: + ///\code + /// int count=0; + /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count; + ///\endcode + class NodeIt : public Node { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + NodeIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + NodeIt(const NodeIt& n) : Node(n) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + NodeIt(Invalid) { } + /// Sets the iterator to the first node. + + /// Sets the iterator to the first node of the given digraph. + /// + explicit NodeIt(const Graph&) { } + /// Sets the iterator to the given node. + + /// Sets the iterator to the given node of the given digraph. + /// + NodeIt(const Graph&, const Node&) { } + /// Next node. + + /// Assign the iterator to the next node. + /// + NodeIt& operator++() { return *this; } + }; + + + /// The edge type of the graph + + /// This class identifies an edge of the graph. It also serves + /// as a base class of the edge iterators, + /// thus they will convert to this type. + class Edge { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the object to an undefined value. + Edge() { } + /// Copy constructor. + + /// Copy constructor. + /// + Edge(const Edge&) { } + /// %Invalid constructor \& conversion. + + /// Initializes the object to be invalid. + /// \sa Invalid for more details. + Edge(Invalid) { } + /// Equality operator + + /// Equality operator. + /// + /// Two iterators are equal if and only if they point to the + /// same object or both are \c INVALID. + bool operator==(Edge) const { return true; } + /// Inequality operator + + /// Inequality operator. + bool operator!=(Edge) const { return true; } + + /// Artificial ordering operator. + + /// Artificial ordering operator. + /// + /// \note This operator only has to define some strict ordering of + /// the edges; this order has nothing to do with the iteration + /// ordering of the edges. + bool operator<(Edge) const { return false; } + }; + + /// Iterator class for the edges. + + /// This iterator goes through each edge of the graph. + /// Its usage is quite simple, for example, you can count the number + /// of edges in a graph \c g of type \c %Graph as follows: + ///\code + /// int count=0; + /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count; + ///\endcode + class EdgeIt : public Edge { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + EdgeIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + EdgeIt(const EdgeIt& e) : Edge(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + EdgeIt(Invalid) { } + /// Sets the iterator to the first edge. + + /// Sets the iterator to the first edge of the given graph. + /// + explicit EdgeIt(const Graph&) { } + /// Sets the iterator to the given edge. + + /// Sets the iterator to the given edge of the given graph. + /// + EdgeIt(const Graph&, const Edge&) { } + /// Next edge + + /// Assign the iterator to the next edge. + /// + EdgeIt& operator++() { return *this; } + }; + + /// Iterator class for the incident edges of a node. + + /// This iterator goes trough the incident undirected edges + /// of a certain node of a graph. + /// Its usage is quite simple, for example, you can compute the + /// degree (i.e. the number of incident edges) of a node \c n + /// in a graph \c g of type \c %Graph as follows. + /// + ///\code + /// int count=0; + /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count; + ///\endcode + /// + /// \warning Loop edges will be iterated twice. + class IncEdgeIt : public Edge { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + IncEdgeIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + IncEdgeIt(const IncEdgeIt& e) : Edge(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + IncEdgeIt(Invalid) { } + /// Sets the iterator to the first incident edge. + + /// Sets the iterator to the first incident edge of the given node. + /// + IncEdgeIt(const Graph&, const Node&) { } + /// Sets the iterator to the given edge. + + /// Sets the iterator to the given edge of the given graph. + /// + IncEdgeIt(const Graph&, const Edge&) { } + /// Next incident edge + + /// Assign the iterator to the next incident edge + /// of the corresponding node. + IncEdgeIt& operator++() { return *this; } + }; + + /// The arc type of the graph + + /// This class identifies a directed arc of the graph. It also serves + /// as a base class of the arc iterators, + /// thus they will convert to this type. + class Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the object to an undefined value. + Arc() { } + /// Copy constructor. + + /// Copy constructor. + /// + Arc(const Arc&) { } + /// %Invalid constructor \& conversion. + + /// Initializes the object to be invalid. + /// \sa Invalid for more details. + Arc(Invalid) { } + /// Equality operator + + /// Equality operator. + /// + /// Two iterators are equal if and only if they point to the + /// same object or both are \c INVALID. + bool operator==(Arc) const { return true; } + /// Inequality operator + + /// Inequality operator. + bool operator!=(Arc) const { return true; } + + /// Artificial ordering operator. + + /// Artificial ordering operator. + /// + /// \note This operator only has to define some strict ordering of + /// the arcs; this order has nothing to do with the iteration + /// ordering of the arcs. + bool operator<(Arc) const { return false; } + + /// Converison to \c Edge + + /// Converison to \c Edge. + /// + operator Edge() const { return Edge(); } + }; + + /// Iterator class for the arcs. + + /// This iterator goes through each directed arc of the graph. + /// Its usage is quite simple, for example, you can count the number + /// of arcs in a graph \c g of type \c %Graph as follows: + ///\code + /// int count=0; + /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count; + ///\endcode + class ArcIt : public Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + ArcIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + ArcIt(const ArcIt& e) : Arc(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + ArcIt(Invalid) { } + /// Sets the iterator to the first arc. + + /// Sets the iterator to the first arc of the given graph. + /// + explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); } + /// Sets the iterator to the given arc. + + /// Sets the iterator to the given arc of the given graph. + /// + ArcIt(const Graph&, const Arc&) { } + /// Next arc + + /// Assign the iterator to the next arc. + /// + ArcIt& operator++() { return *this; } + }; + + /// Iterator class for the outgoing arcs of a node. + + /// This iterator goes trough the \e outgoing directed arcs of a + /// certain node of a graph. + /// Its usage is quite simple, for example, you can count the number + /// of outgoing arcs of a node \c n + /// in a graph \c g of type \c %Graph as follows. + ///\code + /// int count=0; + /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count; + ///\endcode + class OutArcIt : public Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + OutArcIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + OutArcIt(const OutArcIt& e) : Arc(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + OutArcIt(Invalid) { } + /// Sets the iterator to the first outgoing arc. + + /// Sets the iterator to the first outgoing arc of the given node. + /// + OutArcIt(const Graph& n, const Node& g) { + ignore_unused_variable_warning(n); + ignore_unused_variable_warning(g); + } + /// Sets the iterator to the given arc. + + /// Sets the iterator to the given arc of the given graph. + /// + OutArcIt(const Graph&, const Arc&) { } + /// Next outgoing arc + + /// Assign the iterator to the next + /// outgoing arc of the corresponding node. + OutArcIt& operator++() { return *this; } + }; + + /// Iterator class for the incoming arcs of a node. + + /// This iterator goes trough the \e incoming directed arcs of a + /// certain node of a graph. + /// Its usage is quite simple, for example, you can count the number + /// of incoming arcs of a node \c n + /// in a graph \c g of type \c %Graph as follows. + ///\code + /// int count=0; + /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count; + ///\endcode + class InArcIt : public Arc { + public: + /// Default constructor + + /// Default constructor. + /// \warning It sets the iterator to an undefined value. + InArcIt() { } + /// Copy constructor. + + /// Copy constructor. + /// + InArcIt(const InArcIt& e) : Arc(e) { } + /// %Invalid constructor \& conversion. + + /// Initializes the iterator to be invalid. + /// \sa Invalid for more details. + InArcIt(Invalid) { } + /// Sets the iterator to the first incoming arc. + + /// Sets the iterator to the first incoming arc of the given node. + /// + InArcIt(const Graph& g, const Node& n) { + ignore_unused_variable_warning(n); + ignore_unused_variable_warning(g); + } + /// Sets the iterator to the given arc. + + /// Sets the iterator to the given arc of the given graph. + /// + InArcIt(const Graph&, const Arc&) { } + /// Next incoming arc + + /// Assign the iterator to the next + /// incoming arc of the corresponding node. + InArcIt& operator++() { return *this; } + }; + + /// \brief Standard graph map type for the nodes. + /// + /// Standard graph map type for the nodes. + /// It conforms to the ReferenceMap concept. + template + class NodeMap : public ReferenceMap + { + public: + + /// Constructor + explicit NodeMap(const Graph&) { } + /// Constructor with given initial value + NodeMap(const Graph&, T) { } + + private: + ///Copy constructor + NodeMap(const NodeMap& nm) : + ReferenceMap(nm) { } + ///Assignment operator + template + NodeMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + }; + + /// \brief Standard graph map type for the arcs. + /// + /// Standard graph map type for the arcs. + /// It conforms to the ReferenceMap concept. + template + class ArcMap : public ReferenceMap + { + public: + + /// Constructor + explicit ArcMap(const Graph&) { } + /// Constructor with given initial value + ArcMap(const Graph&, T) { } + + private: + ///Copy constructor + ArcMap(const ArcMap& em) : + ReferenceMap(em) { } + ///Assignment operator + template + ArcMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + }; + + /// \brief Standard graph map type for the edges. + /// + /// Standard graph map type for the edges. + /// It conforms to the ReferenceMap concept. + template + class EdgeMap : public ReferenceMap + { + public: + + /// Constructor + explicit EdgeMap(const Graph&) { } + /// Constructor with given initial value + EdgeMap(const Graph&, T) { } + + private: + ///Copy constructor + EdgeMap(const EdgeMap& em) : + ReferenceMap(em) {} + ///Assignment operator + template + EdgeMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + }; + + /// \brief The first node of the edge. + /// + /// Returns the first node of the given edge. + /// + /// Edges don't have source and target nodes, however, methods + /// u() and v() are used to query the two end-nodes of an edge. + /// The orientation of an edge that arises this way is called + /// the inherent direction, it is used to define the default + /// direction for the corresponding arcs. + /// \sa v() + /// \sa direction() + Node u(Edge) const { return INVALID; } + + /// \brief The second node of the edge. + /// + /// Returns the second node of the given edge. + /// + /// Edges don't have source and target nodes, however, methods + /// u() and v() are used to query the two end-nodes of an edge. + /// The orientation of an edge that arises this way is called + /// the inherent direction, it is used to define the default + /// direction for the corresponding arcs. + /// \sa u() + /// \sa direction() + Node v(Edge) const { return INVALID; } + + /// \brief The source node of the arc. + /// + /// Returns the source node of the given arc. + Node source(Arc) const { return INVALID; } + + /// \brief The target node of the arc. + /// + /// Returns the target node of the given arc. + Node target(Arc) const { return INVALID; } + + /// \brief The ID of the node. + /// + /// Returns the ID of the given node. + int id(Node) const { return -1; } + + /// \brief The ID of the edge. + /// + /// Returns the ID of the given edge. + int id(Edge) const { return -1; } + + /// \brief The ID of the arc. + /// + /// Returns the ID of the given arc. + int id(Arc) const { return -1; } + + /// \brief The node with the given ID. + /// + /// Returns the node with the given ID. + /// \pre The argument should be a valid node ID in the graph. + Node nodeFromId(int) const { return INVALID; } + + /// \brief The edge with the given ID. + /// + /// Returns the edge with the given ID. + /// \pre The argument should be a valid edge ID in the graph. + Edge edgeFromId(int) const { return INVALID; } + + /// \brief The arc with the given ID. + /// + /// Returns the arc with the given ID. + /// \pre The argument should be a valid arc ID in the graph. + Arc arcFromId(int) const { return INVALID; } + + /// \brief An upper bound on the node IDs. + /// + /// Returns an upper bound on the node IDs. + int maxNodeId() const { return -1; } + + /// \brief An upper bound on the edge IDs. + /// + /// Returns an upper bound on the edge IDs. + int maxEdgeId() const { return -1; } + + /// \brief An upper bound on the arc IDs. + /// + /// Returns an upper bound on the arc IDs. + int maxArcId() const { return -1; } + + /// \brief The direction of the arc. + /// + /// Returns \c true if the direction of the given arc is the same as + /// the inherent orientation of the represented edge. + bool direction(Arc) const { return true; } + + /// \brief Direct the edge. + /// + /// Direct the given edge. The returned arc + /// represents the given edge and its direction comes + /// from the bool parameter. If it is \c true, then the direction + /// of the arc is the same as the inherent orientation of the edge. + Arc direct(Edge, bool) const { + return INVALID; + } + + /// \brief Direct the edge. + /// + /// Direct the given edge. The returned arc represents the given + /// edge and its source node is the given node. + Arc direct(Edge, Node) const { + return INVALID; + } + + /// \brief The oppositely directed arc. + /// + /// Returns the oppositely directed arc representing the same edge. + Arc oppositeArc(Arc) const { return INVALID; } + + /// \brief The opposite node on the edge. + /// + /// Returns the opposite node on the given edge. + Node oppositeNode(Node, Edge) const { return INVALID; } + + void first(Node&) const {} + void next(Node&) const {} + + void first(Edge&) const {} + void next(Edge&) const {} + + void first(Arc&) const {} + void next(Arc&) const {} + + void firstOut(Arc&, Node) const {} + void nextOut(Arc&) const {} + + void firstIn(Arc&, Node) const {} + void nextIn(Arc&) const {} + + void firstInc(Edge &, bool &, const Node &) const {} + void nextInc(Edge &, bool &) const {} + + // The second parameter is dummy. + Node fromId(int, Node) const { return INVALID; } + // The second parameter is dummy. + Edge fromId(int, Edge) const { return INVALID; } + // The second parameter is dummy. + Arc fromId(int, Arc) const { return INVALID; } + + // Dummy parameter. + int maxId(Node) const { return -1; } + // Dummy parameter. + int maxId(Edge) const { return -1; } + // Dummy parameter. + int maxId(Arc) const { return -1; } + + /// \brief The base node of the iterator. + /// + /// Returns the base node of the given incident edge iterator. + Node baseNode(IncEdgeIt) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// Returns the running node of the given incident edge iterator. + Node runningNode(IncEdgeIt) const { return INVALID; } + + /// \brief The base node of the iterator. + /// + /// Returns the base node of the given outgoing arc iterator + /// (i.e. the source node of the corresponding arc). + Node baseNode(OutArcIt) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// Returns the running node of the given outgoing arc iterator + /// (i.e. the target node of the corresponding arc). + Node runningNode(OutArcIt) const { return INVALID; } + + /// \brief The base node of the iterator. + /// + /// Returns the base node of the given incomming arc iterator + /// (i.e. the target node of the corresponding arc). + Node baseNode(InArcIt) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// Returns the running node of the given incomming arc iterator + /// (i.e. the source node of the corresponding arc). + Node runningNode(InArcIt) const { return INVALID; } + + template + struct Constraints { + void constraints() { + checkConcept(); + checkConcept, _Graph>(); + checkConcept, _Graph>(); + checkConcept, _Graph>(); + } + }; + + }; + + } + +} + +#endif diff --git a/lemon/lemon/concepts/graph_components.h b/lemon/lemon/concepts/graph_components.h new file mode 100644 index 0000000..4b6f170 --- /dev/null +++ b/lemon/lemon/concepts/graph_components.h @@ -0,0 +1,1516 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup graph_concepts +///\file +///\brief The concepts of graph components. + +#ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H +#define LEMON_CONCEPTS_GRAPH_COMPONENTS_H + +#include +#include + +#include + +namespace lemon { + namespace concepts { + + /// \brief Concept class for \c Node, \c Arc and \c Edge types. + /// + /// This class describes the concept of \c Node, \c Arc and \c Edge + /// subtypes of digraph and graph types. + /// + /// \note This class is a template class so that we can use it to + /// create graph skeleton classes. The reason for this is that \c Node + /// and \c Arc (or \c Edge) types should \e not derive from the same + /// base class. For \c Node you should instantiate it with character + /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'. +#ifndef DOXYGEN + template +#endif + class GraphItem { + public: + /// \brief Default constructor. + /// + /// Default constructor. + /// \warning The default constructor is not required to set + /// the item to some well-defined value. So you should consider it + /// as uninitialized. + GraphItem() {} + + /// \brief Copy constructor. + /// + /// Copy constructor. + GraphItem(const GraphItem &) {} + + /// \brief Constructor for conversion from \c INVALID. + /// + /// Constructor for conversion from \c INVALID. + /// It initializes the item to be invalid. + /// \sa Invalid for more details. + GraphItem(Invalid) {} + + /// \brief Assignment operator. + /// + /// Assignment operator for the item. + GraphItem& operator=(const GraphItem&) { return *this; } + + /// \brief Assignment operator for INVALID. + /// + /// This operator makes the item invalid. + GraphItem& operator=(Invalid) { return *this; } + + /// \brief Equality operator. + /// + /// Equality operator. + bool operator==(const GraphItem&) const { return false; } + + /// \brief Inequality operator. + /// + /// Inequality operator. + bool operator!=(const GraphItem&) const { return false; } + + /// \brief Ordering operator. + /// + /// This operator defines an ordering of the items. + /// It makes possible to use graph item types as key types in + /// associative containers (e.g. \c std::map). + /// + /// \note This operator only has to define some strict ordering of + /// the items; this order has nothing to do with the iteration + /// ordering of the items. + bool operator<(const GraphItem&) const { return false; } + + template + struct Constraints { + void constraints() { + _GraphItem i1; + i1=INVALID; + _GraphItem i2 = i1; + _GraphItem i3 = INVALID; + + i1 = i2 = i3; + + bool b; + b = (ia == ib) && (ia != ib); + b = (ia == INVALID) && (ib != INVALID); + b = (ia < ib); + } + + const _GraphItem &ia; + const _GraphItem &ib; + }; + }; + + /// \brief Base skeleton class for directed graphs. + /// + /// This class describes the base interface of directed graph types. + /// All digraph %concepts have to conform to this class. + /// It just provides types for nodes and arcs and functions + /// to get the source and the target nodes of arcs. + class BaseDigraphComponent { + public: + + typedef BaseDigraphComponent Digraph; + + /// \brief Node class of the digraph. + /// + /// This class represents the nodes of the digraph. + typedef GraphItem<'n'> Node; + + /// \brief Arc class of the digraph. + /// + /// This class represents the arcs of the digraph. + typedef GraphItem<'a'> Arc; + + /// \brief Return the source node of an arc. + /// + /// This function returns the source node of an arc. + Node source(const Arc&) const { return INVALID; } + + /// \brief Return the target node of an arc. + /// + /// This function returns the target node of an arc. + Node target(const Arc&) const { return INVALID; } + + /// \brief Return the opposite node on the given arc. + /// + /// This function returns the opposite node on the given arc. + Node oppositeNode(const Node&, const Arc&) const { + return INVALID; + } + + template + struct Constraints { + typedef typename _Digraph::Node Node; + typedef typename _Digraph::Arc Arc; + + void constraints() { + checkConcept, Node>(); + checkConcept, Arc>(); + { + Node n; + Arc e(INVALID); + n = digraph.source(e); + n = digraph.target(e); + n = digraph.oppositeNode(n, e); + } + } + + const _Digraph& digraph; + }; + }; + + /// \brief Base skeleton class for undirected graphs. + /// + /// This class describes the base interface of undirected graph types. + /// All graph %concepts have to conform to this class. + /// It extends the interface of \ref BaseDigraphComponent with an + /// \c Edge type and functions to get the end nodes of edges, + /// to convert from arcs to edges and to get both direction of edges. + class BaseGraphComponent : public BaseDigraphComponent { + public: + + typedef BaseGraphComponent Graph; + + typedef BaseDigraphComponent::Node Node; + typedef BaseDigraphComponent::Arc Arc; + + /// \brief Undirected edge class of the graph. + /// + /// This class represents the undirected edges of the graph. + /// Undirected graphs can be used as directed graphs, each edge is + /// represented by two opposite directed arcs. + class Edge : public GraphItem<'e'> { + typedef GraphItem<'e'> Parent; + + public: + /// \brief Default constructor. + /// + /// Default constructor. + /// \warning The default constructor is not required to set + /// the item to some well-defined value. So you should consider it + /// as uninitialized. + Edge() {} + + /// \brief Copy constructor. + /// + /// Copy constructor. + Edge(const Edge &) : Parent() {} + + /// \brief Constructor for conversion from \c INVALID. + /// + /// Constructor for conversion from \c INVALID. + /// It initializes the item to be invalid. + /// \sa Invalid for more details. + Edge(Invalid) {} + + /// \brief Constructor for conversion from an arc. + /// + /// Constructor for conversion from an arc. + /// Besides the core graph item functionality each arc should + /// be convertible to the represented edge. + Edge(const Arc&) {} + }; + + /// \brief Return one end node of an edge. + /// + /// This function returns one end node of an edge. + Node u(const Edge&) const { return INVALID; } + + /// \brief Return the other end node of an edge. + /// + /// This function returns the other end node of an edge. + Node v(const Edge&) const { return INVALID; } + + /// \brief Return a directed arc related to an edge. + /// + /// This function returns a directed arc from its direction and the + /// represented edge. + Arc direct(const Edge&, bool) const { return INVALID; } + + /// \brief Return a directed arc related to an edge. + /// + /// This function returns a directed arc from its source node and the + /// represented edge. + Arc direct(const Edge&, const Node&) const { return INVALID; } + + /// \brief Return the direction of the arc. + /// + /// Returns the direction of the arc. Each arc represents an + /// edge with a direction. It gives back the + /// direction. + bool direction(const Arc&) const { return true; } + + /// \brief Return the opposite arc. + /// + /// This function returns the opposite arc, i.e. the arc representing + /// the same edge and has opposite direction. + Arc oppositeArc(const Arc&) const { return INVALID; } + + template + struct Constraints { + typedef typename _Graph::Node Node; + typedef typename _Graph::Arc Arc; + typedef typename _Graph::Edge Edge; + + void constraints() { + checkConcept(); + checkConcept, Edge>(); + { + Node n; + Edge ue(INVALID); + Arc e; + n = graph.u(ue); + n = graph.v(ue); + e = graph.direct(ue, true); + e = graph.direct(ue, false); + e = graph.direct(ue, n); + e = graph.oppositeArc(e); + ue = e; + bool d = graph.direction(e); + ignore_unused_variable_warning(d); + } + } + + const _Graph& graph; + }; + + }; + + /// \brief Skeleton class for \e idable directed graphs. + /// + /// This class describes the interface of \e idable directed graphs. + /// It extends \ref BaseDigraphComponent with the core ID functions. + /// The ids of the items must be unique and immutable. + /// This concept is part of the Digraph concept. + template + class IDableDigraphComponent : public BAS { + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Arc Arc; + + /// \brief Return a unique integer id for the given node. + /// + /// This function returns a unique integer id for the given node. + int id(const Node&) const { return -1; } + + /// \brief Return the node by its unique id. + /// + /// This function returns the node by its unique id. + /// If the digraph does not contain a node with the given id, + /// then the result of the function is undefined. + Node nodeFromId(int) const { return INVALID; } + + /// \brief Return a unique integer id for the given arc. + /// + /// This function returns a unique integer id for the given arc. + int id(const Arc&) const { return -1; } + + /// \brief Return the arc by its unique id. + /// + /// This function returns the arc by its unique id. + /// If the digraph does not contain an arc with the given id, + /// then the result of the function is undefined. + Arc arcFromId(int) const { return INVALID; } + + /// \brief Return an integer greater or equal to the maximum + /// node id. + /// + /// This function returns an integer greater or equal to the + /// maximum node id. + int maxNodeId() const { return -1; } + + /// \brief Return an integer greater or equal to the maximum + /// arc id. + /// + /// This function returns an integer greater or equal to the + /// maximum arc id. + int maxArcId() const { return -1; } + + template + struct Constraints { + + void constraints() { + checkConcept(); + typename _Digraph::Node node; + node=INVALID; + int nid = digraph.id(node); + nid = digraph.id(node); + node = digraph.nodeFromId(nid); + typename _Digraph::Arc arc; + arc=INVALID; + int eid = digraph.id(arc); + eid = digraph.id(arc); + arc = digraph.arcFromId(eid); + + nid = digraph.maxNodeId(); + ignore_unused_variable_warning(nid); + eid = digraph.maxArcId(); + ignore_unused_variable_warning(eid); + } + + const _Digraph& digraph; + }; + }; + + /// \brief Skeleton class for \e idable undirected graphs. + /// + /// This class describes the interface of \e idable undirected + /// graphs. It extends \ref IDableDigraphComponent with the core ID + /// functions of undirected graphs. + /// The ids of the items must be unique and immutable. + /// This concept is part of the Graph concept. + template + class IDableGraphComponent : public IDableDigraphComponent { + public: + + typedef BAS Base; + typedef typename Base::Edge Edge; + + using IDableDigraphComponent::id; + + /// \brief Return a unique integer id for the given edge. + /// + /// This function returns a unique integer id for the given edge. + int id(const Edge&) const { return -1; } + + /// \brief Return the edge by its unique id. + /// + /// This function returns the edge by its unique id. + /// If the graph does not contain an edge with the given id, + /// then the result of the function is undefined. + Edge edgeFromId(int) const { return INVALID; } + + /// \brief Return an integer greater or equal to the maximum + /// edge id. + /// + /// This function returns an integer greater or equal to the + /// maximum edge id. + int maxEdgeId() const { return -1; } + + template + struct Constraints { + + void constraints() { + checkConcept, _Graph >(); + typename _Graph::Edge edge; + int ueid = graph.id(edge); + ueid = graph.id(edge); + edge = graph.edgeFromId(ueid); + ueid = graph.maxEdgeId(); + ignore_unused_variable_warning(ueid); + } + + const _Graph& graph; + }; + }; + + /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types. + /// + /// This class describes the concept of \c NodeIt, \c ArcIt and + /// \c EdgeIt subtypes of digraph and graph types. + template + class GraphItemIt : public Item { + public: + /// \brief Default constructor. + /// + /// Default constructor. + /// \warning The default constructor is not required to set + /// the iterator to some well-defined value. So you should consider it + /// as uninitialized. + GraphItemIt() {} + + /// \brief Copy constructor. + /// + /// Copy constructor. + GraphItemIt(const GraphItemIt& it) : Item(it) {} + + /// \brief Constructor that sets the iterator to the first item. + /// + /// Constructor that sets the iterator to the first item. + explicit GraphItemIt(const GR&) {} + + /// \brief Constructor for conversion from \c INVALID. + /// + /// Constructor for conversion from \c INVALID. + /// It initializes the iterator to be invalid. + /// \sa Invalid for more details. + GraphItemIt(Invalid) {} + + /// \brief Assignment operator. + /// + /// Assignment operator for the iterator. + GraphItemIt& operator=(const GraphItemIt&) { return *this; } + + /// \brief Increment the iterator. + /// + /// This operator increments the iterator, i.e. assigns it to the + /// next item. + GraphItemIt& operator++() { return *this; } + + /// \brief Equality operator + /// + /// Equality operator. + /// Two iterators are equal if and only if they point to the + /// same object or both are invalid. + bool operator==(const GraphItemIt&) const { return true;} + + /// \brief Inequality operator + /// + /// Inequality operator. + /// Two iterators are equal if and only if they point to the + /// same object or both are invalid. + bool operator!=(const GraphItemIt&) const { return true;} + + template + struct Constraints { + void constraints() { + checkConcept, _GraphItemIt>(); + _GraphItemIt it1(g); + _GraphItemIt it2; + _GraphItemIt it3 = it1; + _GraphItemIt it4 = INVALID; + + it2 = ++it1; + ++it2 = it1; + ++(++it1); + + Item bi = it1; + bi = it2; + } + const GR& g; + }; + }; + + /// \brief Concept class for \c InArcIt, \c OutArcIt and + /// \c IncEdgeIt types. + /// + /// This class describes the concept of \c InArcIt, \c OutArcIt + /// and \c IncEdgeIt subtypes of digraph and graph types. + /// + /// \note Since these iterator classes do not inherit from the same + /// base class, there is an additional template parameter (selector) + /// \c sel. For \c InArcIt you should instantiate it with character + /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'. + template + class GraphIncIt : public Item { + public: + /// \brief Default constructor. + /// + /// Default constructor. + /// \warning The default constructor is not required to set + /// the iterator to some well-defined value. So you should consider it + /// as uninitialized. + GraphIncIt() {} + + /// \brief Copy constructor. + /// + /// Copy constructor. + GraphIncIt(const GraphIncIt& it) : Item(it) {} + + /// \brief Constructor that sets the iterator to the first + /// incoming or outgoing arc. + /// + /// Constructor that sets the iterator to the first arc + /// incoming to or outgoing from the given node. + explicit GraphIncIt(const GR&, const Base&) {} + + /// \brief Constructor for conversion from \c INVALID. + /// + /// Constructor for conversion from \c INVALID. + /// It initializes the iterator to be invalid. + /// \sa Invalid for more details. + GraphIncIt(Invalid) {} + + /// \brief Assignment operator. + /// + /// Assignment operator for the iterator. + GraphIncIt& operator=(const GraphIncIt&) { return *this; } + + /// \brief Increment the iterator. + /// + /// This operator increments the iterator, i.e. assigns it to the + /// next arc incoming to or outgoing from the given node. + GraphIncIt& operator++() { return *this; } + + /// \brief Equality operator + /// + /// Equality operator. + /// Two iterators are equal if and only if they point to the + /// same object or both are invalid. + bool operator==(const GraphIncIt&) const { return true;} + + /// \brief Inequality operator + /// + /// Inequality operator. + /// Two iterators are equal if and only if they point to the + /// same object or both are invalid. + bool operator!=(const GraphIncIt&) const { return true;} + + template + struct Constraints { + void constraints() { + checkConcept, _GraphIncIt>(); + _GraphIncIt it1(graph, node); + _GraphIncIt it2; + _GraphIncIt it3 = it1; + _GraphIncIt it4 = INVALID; + + it2 = ++it1; + ++it2 = it1; + ++(++it1); + Item e = it1; + e = it2; + } + const Base& node; + const GR& graph; + }; + }; + + /// \brief Skeleton class for iterable directed graphs. + /// + /// This class describes the interface of iterable directed + /// graphs. It extends \ref BaseDigraphComponent with the core + /// iterable interface. + /// This concept is part of the Digraph concept. + template + class IterableDigraphComponent : public BAS { + + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Arc Arc; + + typedef IterableDigraphComponent Digraph; + + /// \name Base Iteration + /// + /// This interface provides functions for iteration on digraph items. + /// + /// @{ + + /// \brief Return the first node. + /// + /// This function gives back the first node in the iteration order. + void first(Node&) const {} + + /// \brief Return the next node. + /// + /// This function gives back the next node in the iteration order. + void next(Node&) const {} + + /// \brief Return the first arc. + /// + /// This function gives back the first arc in the iteration order. + void first(Arc&) const {} + + /// \brief Return the next arc. + /// + /// This function gives back the next arc in the iteration order. + void next(Arc&) const {} + + /// \brief Return the first arc incomming to the given node. + /// + /// This function gives back the first arc incomming to the + /// given node. + void firstIn(Arc&, const Node&) const {} + + /// \brief Return the next arc incomming to the given node. + /// + /// This function gives back the next arc incomming to the + /// given node. + void nextIn(Arc&) const {} + + /// \brief Return the first arc outgoing form the given node. + /// + /// This function gives back the first arc outgoing form the + /// given node. + void firstOut(Arc&, const Node&) const {} + + /// \brief Return the next arc outgoing form the given node. + /// + /// This function gives back the next arc outgoing form the + /// given node. + void nextOut(Arc&) const {} + + /// @} + + /// \name Class Based Iteration + /// + /// This interface provides iterator classes for digraph items. + /// + /// @{ + + /// \brief This iterator goes through each node. + /// + /// This iterator goes through each node. + /// + typedef GraphItemIt NodeIt; + + /// \brief This iterator goes through each arc. + /// + /// This iterator goes through each arc. + /// + typedef GraphItemIt ArcIt; + + /// \brief This iterator goes trough the incoming arcs of a node. + /// + /// This iterator goes trough the \e incoming arcs of a certain node + /// of a digraph. + typedef GraphIncIt InArcIt; + + /// \brief This iterator goes trough the outgoing arcs of a node. + /// + /// This iterator goes trough the \e outgoing arcs of a certain node + /// of a digraph. + typedef GraphIncIt OutArcIt; + + /// \brief The base node of the iterator. + /// + /// This function gives back the base node of the iterator. + /// It is always the target node of the pointed arc. + Node baseNode(const InArcIt&) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// This function gives back the running node of the iterator. + /// It is always the source node of the pointed arc. + Node runningNode(const InArcIt&) const { return INVALID; } + + /// \brief The base node of the iterator. + /// + /// This function gives back the base node of the iterator. + /// It is always the source node of the pointed arc. + Node baseNode(const OutArcIt&) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// This function gives back the running node of the iterator. + /// It is always the target node of the pointed arc. + Node runningNode(const OutArcIt&) const { return INVALID; } + + /// @} + + template + struct Constraints { + void constraints() { + checkConcept(); + + { + typename _Digraph::Node node(INVALID); + typename _Digraph::Arc arc(INVALID); + { + digraph.first(node); + digraph.next(node); + } + { + digraph.first(arc); + digraph.next(arc); + } + { + digraph.firstIn(arc, node); + digraph.nextIn(arc); + } + { + digraph.firstOut(arc, node); + digraph.nextOut(arc); + } + } + + { + checkConcept, + typename _Digraph::ArcIt >(); + checkConcept, + typename _Digraph::NodeIt >(); + checkConcept, typename _Digraph::InArcIt>(); + checkConcept, typename _Digraph::OutArcIt>(); + + typename _Digraph::Node n; + const typename _Digraph::InArcIt iait(INVALID); + const typename _Digraph::OutArcIt oait(INVALID); + n = digraph.baseNode(iait); + n = digraph.runningNode(iait); + n = digraph.baseNode(oait); + n = digraph.runningNode(oait); + ignore_unused_variable_warning(n); + } + } + + const _Digraph& digraph; + }; + }; + + /// \brief Skeleton class for iterable undirected graphs. + /// + /// This class describes the interface of iterable undirected + /// graphs. It extends \ref IterableDigraphComponent with the core + /// iterable interface of undirected graphs. + /// This concept is part of the Graph concept. + template + class IterableGraphComponent : public IterableDigraphComponent { + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Arc Arc; + typedef typename Base::Edge Edge; + + + typedef IterableGraphComponent Graph; + + /// \name Base Iteration + /// + /// This interface provides functions for iteration on edges. + /// + /// @{ + + using IterableDigraphComponent::first; + using IterableDigraphComponent::next; + + /// \brief Return the first edge. + /// + /// This function gives back the first edge in the iteration order. + void first(Edge&) const {} + + /// \brief Return the next edge. + /// + /// This function gives back the next edge in the iteration order. + void next(Edge&) const {} + + /// \brief Return the first edge incident to the given node. + /// + /// This function gives back the first edge incident to the given + /// node. The bool parameter gives back the direction for which the + /// source node of the directed arc representing the edge is the + /// given node. + void firstInc(Edge&, bool&, const Node&) const {} + + /// \brief Gives back the next of the edges from the + /// given node. + /// + /// This function gives back the next edge incident to the given + /// node. The bool parameter should be used as \c firstInc() use it. + void nextInc(Edge&, bool&) const {} + + using IterableDigraphComponent::baseNode; + using IterableDigraphComponent::runningNode; + + /// @} + + /// \name Class Based Iteration + /// + /// This interface provides iterator classes for edges. + /// + /// @{ + + /// \brief This iterator goes through each edge. + /// + /// This iterator goes through each edge. + typedef GraphItemIt EdgeIt; + + /// \brief This iterator goes trough the incident edges of a + /// node. + /// + /// This iterator goes trough the incident edges of a certain + /// node of a graph. + typedef GraphIncIt IncEdgeIt; + + /// \brief The base node of the iterator. + /// + /// This function gives back the base node of the iterator. + Node baseNode(const IncEdgeIt&) const { return INVALID; } + + /// \brief The running node of the iterator. + /// + /// This function gives back the running node of the iterator. + Node runningNode(const IncEdgeIt&) const { return INVALID; } + + /// @} + + template + struct Constraints { + void constraints() { + checkConcept, _Graph>(); + + { + typename _Graph::Node node(INVALID); + typename _Graph::Edge edge(INVALID); + bool dir; + { + graph.first(edge); + graph.next(edge); + } + { + graph.firstInc(edge, dir, node); + graph.nextInc(edge, dir); + } + + } + + { + checkConcept, + typename _Graph::EdgeIt >(); + checkConcept, typename _Graph::IncEdgeIt>(); + + typename _Graph::Node n; + const typename _Graph::IncEdgeIt ieit(INVALID); + n = graph.baseNode(ieit); + n = graph.runningNode(ieit); + } + } + + const _Graph& graph; + }; + }; + + /// \brief Skeleton class for alterable directed graphs. + /// + /// This class describes the interface of alterable directed + /// graphs. It extends \ref BaseDigraphComponent with the alteration + /// notifier interface. It implements + /// an observer-notifier pattern for each digraph item. More + /// obsevers can be registered into the notifier and whenever an + /// alteration occured in the digraph all the observers will be + /// notified about it. + template + class AlterableDigraphComponent : public BAS { + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Arc Arc; + + + /// Node alteration notifier class. + typedef AlterationNotifier + NodeNotifier; + /// Arc alteration notifier class. + typedef AlterationNotifier + ArcNotifier; + + /// \brief Return the node alteration notifier. + /// + /// This function gives back the node alteration notifier. + NodeNotifier& notifier(Node) const { + return NodeNotifier(); + } + + /// \brief Return the arc alteration notifier. + /// + /// This function gives back the arc alteration notifier. + ArcNotifier& notifier(Arc) const { + return ArcNotifier(); + } + + template + struct Constraints { + void constraints() { + checkConcept(); + typename _Digraph::NodeNotifier& nn + = digraph.notifier(typename _Digraph::Node()); + + typename _Digraph::ArcNotifier& en + = digraph.notifier(typename _Digraph::Arc()); + + ignore_unused_variable_warning(nn); + ignore_unused_variable_warning(en); + } + + const _Digraph& digraph; + }; + }; + + /// \brief Skeleton class for alterable undirected graphs. + /// + /// This class describes the interface of alterable undirected + /// graphs. It extends \ref AlterableDigraphComponent with the alteration + /// notifier interface of undirected graphs. It implements + /// an observer-notifier pattern for the edges. More + /// obsevers can be registered into the notifier and whenever an + /// alteration occured in the graph all the observers will be + /// notified about it. + template + class AlterableGraphComponent : public AlterableDigraphComponent { + public: + + typedef BAS Base; + typedef typename Base::Edge Edge; + + + /// Edge alteration notifier class. + typedef AlterationNotifier + EdgeNotifier; + + /// \brief Return the edge alteration notifier. + /// + /// This function gives back the edge alteration notifier. + EdgeNotifier& notifier(Edge) const { + return EdgeNotifier(); + } + + template + struct Constraints { + void constraints() { + checkConcept, _Graph>(); + typename _Graph::EdgeNotifier& uen + = graph.notifier(typename _Graph::Edge()); + ignore_unused_variable_warning(uen); + } + + const _Graph& graph; + }; + }; + + /// \brief Concept class for standard graph maps. + /// + /// This class describes the concept of standard graph maps, i.e. + /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and + /// graph types, which can be used for associating data to graph items. + /// The standard graph maps must conform to the ReferenceMap concept. + template + class GraphMap : public ReferenceMap { + typedef ReferenceMap Parent; + + public: + + /// The key type of the map. + typedef K Key; + /// The value type of the map. + typedef V Value; + /// The reference type of the map. + typedef Value& Reference; + /// The const reference type of the map. + typedef const Value& ConstReference; + + // The reference map tag. + typedef True ReferenceMapTag; + + /// \brief Construct a new map. + /// + /// Construct a new map for the graph. + explicit GraphMap(const GR&) {} + /// \brief Construct a new map with default value. + /// + /// Construct a new map for the graph and initalize the values. + GraphMap(const GR&, const Value&) {} + + private: + /// \brief Copy constructor. + /// + /// Copy Constructor. + GraphMap(const GraphMap&) : Parent() {} + + /// \brief Assignment operator. + /// + /// Assignment operator. It does not mofify the underlying graph, + /// it just iterates on the current item set and set the map + /// with the value returned by the assigned map. + template + GraphMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + + public: + template + struct Constraints { + void constraints() { + checkConcept + , _Map>(); + _Map m1(g); + _Map m2(g,t); + + // Copy constructor + // _Map m3(m); + + // Assignment operator + // ReadMap cmap; + // m3 = cmap; + + ignore_unused_variable_warning(m1); + ignore_unused_variable_warning(m2); + // ignore_unused_variable_warning(m3); + } + + const _Map &m; + const GR &g; + const typename GraphMap::Value &t; + }; + + }; + + /// \brief Skeleton class for mappable directed graphs. + /// + /// This class describes the interface of mappable directed graphs. + /// It extends \ref BaseDigraphComponent with the standard digraph + /// map classes, namely \c NodeMap and \c ArcMap. + /// This concept is part of the Digraph concept. + template + class MappableDigraphComponent : public BAS { + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Arc Arc; + + typedef MappableDigraphComponent Digraph; + + /// \brief Standard graph map for the nodes. + /// + /// Standard graph map for the nodes. + /// It conforms to the ReferenceMap concept. + template + class NodeMap : public GraphMap { + typedef GraphMap Parent; + + public: + /// \brief Construct a new map. + /// + /// Construct a new map for the digraph. + explicit NodeMap(const MappableDigraphComponent& digraph) + : Parent(digraph) {} + + /// \brief Construct a new map with default value. + /// + /// Construct a new map for the digraph and initalize the values. + NodeMap(const MappableDigraphComponent& digraph, const V& value) + : Parent(digraph, value) {} + + private: + /// \brief Copy constructor. + /// + /// Copy Constructor. + NodeMap(const NodeMap& nm) : Parent(nm) {} + + /// \brief Assignment operator. + /// + /// Assignment operator. + template + NodeMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + + }; + + /// \brief Standard graph map for the arcs. + /// + /// Standard graph map for the arcs. + /// It conforms to the ReferenceMap concept. + template + class ArcMap : public GraphMap { + typedef GraphMap Parent; + + public: + /// \brief Construct a new map. + /// + /// Construct a new map for the digraph. + explicit ArcMap(const MappableDigraphComponent& digraph) + : Parent(digraph) {} + + /// \brief Construct a new map with default value. + /// + /// Construct a new map for the digraph and initalize the values. + ArcMap(const MappableDigraphComponent& digraph, const V& value) + : Parent(digraph, value) {} + + private: + /// \brief Copy constructor. + /// + /// Copy Constructor. + ArcMap(const ArcMap& nm) : Parent(nm) {} + + /// \brief Assignment operator. + /// + /// Assignment operator. + template + ArcMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + + }; + + + template + struct Constraints { + + struct Dummy { + int value; + Dummy() : value(0) {} + Dummy(int _v) : value(_v) {} + }; + + void constraints() { + checkConcept(); + { // int map test + typedef typename _Digraph::template NodeMap IntNodeMap; + checkConcept, + IntNodeMap >(); + } { // bool map test + typedef typename _Digraph::template NodeMap BoolNodeMap; + checkConcept, + BoolNodeMap >(); + } { // Dummy map test + typedef typename _Digraph::template NodeMap DummyNodeMap; + checkConcept, + DummyNodeMap >(); + } + + { // int map test + typedef typename _Digraph::template ArcMap IntArcMap; + checkConcept, + IntArcMap >(); + } { // bool map test + typedef typename _Digraph::template ArcMap BoolArcMap; + checkConcept, + BoolArcMap >(); + } { // Dummy map test + typedef typename _Digraph::template ArcMap DummyArcMap; + checkConcept, + DummyArcMap >(); + } + } + + const _Digraph& digraph; + }; + }; + + /// \brief Skeleton class for mappable undirected graphs. + /// + /// This class describes the interface of mappable undirected graphs. + /// It extends \ref MappableDigraphComponent with the standard graph + /// map class for edges (\c EdgeMap). + /// This concept is part of the Graph concept. + template + class MappableGraphComponent : public MappableDigraphComponent { + public: + + typedef BAS Base; + typedef typename Base::Edge Edge; + + typedef MappableGraphComponent Graph; + + /// \brief Standard graph map for the edges. + /// + /// Standard graph map for the edges. + /// It conforms to the ReferenceMap concept. + template + class EdgeMap : public GraphMap { + typedef GraphMap Parent; + + public: + /// \brief Construct a new map. + /// + /// Construct a new map for the graph. + explicit EdgeMap(const MappableGraphComponent& graph) + : Parent(graph) {} + + /// \brief Construct a new map with default value. + /// + /// Construct a new map for the graph and initalize the values. + EdgeMap(const MappableGraphComponent& graph, const V& value) + : Parent(graph, value) {} + + private: + /// \brief Copy constructor. + /// + /// Copy Constructor. + EdgeMap(const EdgeMap& nm) : Parent(nm) {} + + /// \brief Assignment operator. + /// + /// Assignment operator. + template + EdgeMap& operator=(const CMap&) { + checkConcept, CMap>(); + return *this; + } + + }; + + + template + struct Constraints { + + struct Dummy { + int value; + Dummy() : value(0) {} + Dummy(int _v) : value(_v) {} + }; + + void constraints() { + checkConcept, _Graph>(); + + { // int map test + typedef typename _Graph::template EdgeMap IntEdgeMap; + checkConcept, + IntEdgeMap >(); + } { // bool map test + typedef typename _Graph::template EdgeMap BoolEdgeMap; + checkConcept, + BoolEdgeMap >(); + } { // Dummy map test + typedef typename _Graph::template EdgeMap DummyEdgeMap; + checkConcept, + DummyEdgeMap >(); + } + } + + const _Graph& graph; + }; + }; + + /// \brief Skeleton class for extendable directed graphs. + /// + /// This class describes the interface of extendable directed graphs. + /// It extends \ref BaseDigraphComponent with functions for adding + /// nodes and arcs to the digraph. + /// This concept requires \ref AlterableDigraphComponent. + template + class ExtendableDigraphComponent : public BAS { + public: + typedef BAS Base; + + typedef typename Base::Node Node; + typedef typename Base::Arc Arc; + + /// \brief Add a new node to the digraph. + /// + /// This function adds a new node to the digraph. + Node addNode() { + return INVALID; + } + + /// \brief Add a new arc connecting the given two nodes. + /// + /// This function adds a new arc connecting the given two nodes + /// of the digraph. + Arc addArc(const Node&, const Node&) { + return INVALID; + } + + template + struct Constraints { + void constraints() { + checkConcept(); + typename _Digraph::Node node_a, node_b; + node_a = digraph.addNode(); + node_b = digraph.addNode(); + typename _Digraph::Arc arc; + arc = digraph.addArc(node_a, node_b); + } + + _Digraph& digraph; + }; + }; + + /// \brief Skeleton class for extendable undirected graphs. + /// + /// This class describes the interface of extendable undirected graphs. + /// It extends \ref BaseGraphComponent with functions for adding + /// nodes and edges to the graph. + /// This concept requires \ref AlterableGraphComponent. + template + class ExtendableGraphComponent : public BAS { + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Edge Edge; + + /// \brief Add a new node to the digraph. + /// + /// This function adds a new node to the digraph. + Node addNode() { + return INVALID; + } + + /// \brief Add a new edge connecting the given two nodes. + /// + /// This function adds a new edge connecting the given two nodes + /// of the graph. + Edge addEdge(const Node&, const Node&) { + return INVALID; + } + + template + struct Constraints { + void constraints() { + checkConcept(); + typename _Graph::Node node_a, node_b; + node_a = graph.addNode(); + node_b = graph.addNode(); + typename _Graph::Edge edge; + edge = graph.addEdge(node_a, node_b); + } + + _Graph& graph; + }; + }; + + /// \brief Skeleton class for erasable directed graphs. + /// + /// This class describes the interface of erasable directed graphs. + /// It extends \ref BaseDigraphComponent with functions for removing + /// nodes and arcs from the digraph. + /// This concept requires \ref AlterableDigraphComponent. + template + class ErasableDigraphComponent : public BAS { + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Arc Arc; + + /// \brief Erase a node from the digraph. + /// + /// This function erases the given node from the digraph and all arcs + /// connected to the node. + void erase(const Node&) {} + + /// \brief Erase an arc from the digraph. + /// + /// This function erases the given arc from the digraph. + void erase(const Arc&) {} + + template + struct Constraints { + void constraints() { + checkConcept(); + const typename _Digraph::Node node(INVALID); + digraph.erase(node); + const typename _Digraph::Arc arc(INVALID); + digraph.erase(arc); + } + + _Digraph& digraph; + }; + }; + + /// \brief Skeleton class for erasable undirected graphs. + /// + /// This class describes the interface of erasable undirected graphs. + /// It extends \ref BaseGraphComponent with functions for removing + /// nodes and edges from the graph. + /// This concept requires \ref AlterableGraphComponent. + template + class ErasableGraphComponent : public BAS { + public: + + typedef BAS Base; + typedef typename Base::Node Node; + typedef typename Base::Edge Edge; + + /// \brief Erase a node from the graph. + /// + /// This function erases the given node from the graph and all edges + /// connected to the node. + void erase(const Node&) {} + + /// \brief Erase an edge from the digraph. + /// + /// This function erases the given edge from the digraph. + void erase(const Edge&) {} + + template + struct Constraints { + void constraints() { + checkConcept(); + const typename _Graph::Node node(INVALID); + graph.erase(node); + const typename _Graph::Edge edge(INVALID); + graph.erase(edge); + } + + _Graph& graph; + }; + }; + + /// \brief Skeleton class for clearable directed graphs. + /// + /// This class describes the interface of clearable directed graphs. + /// It extends \ref BaseDigraphComponent with a function for clearing + /// the digraph. + /// This concept requires \ref AlterableDigraphComponent. + template + class ClearableDigraphComponent : public BAS { + public: + + typedef BAS Base; + + /// \brief Erase all nodes and arcs from the digraph. + /// + /// This function erases all nodes and arcs from the digraph. + void clear() {} + + template + struct Constraints { + void constraints() { + checkConcept(); + digraph.clear(); + } + + _Digraph& digraph; + }; + }; + + /// \brief Skeleton class for clearable undirected graphs. + /// + /// This class describes the interface of clearable undirected graphs. + /// It extends \ref BaseGraphComponent with a function for clearing + /// the graph. + /// This concept requires \ref AlterableGraphComponent. + template + class ClearableGraphComponent : public ClearableDigraphComponent { + public: + + typedef BAS Base; + + /// \brief Erase all nodes and edges from the graph. + /// + /// This function erases all nodes and edges from the graph. + void clear() {} + + template + struct Constraints { + void constraints() { + checkConcept(); + graph.clear(); + } + + _Graph& graph; + }; + }; + + } + +} + +#endif diff --git a/lemon/lemon/concepts/heap.h b/lemon/lemon/concepts/heap.h new file mode 100644 index 0000000..1d98743 --- /dev/null +++ b/lemon/lemon/concepts/heap.h @@ -0,0 +1,323 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CONCEPTS_HEAP_H +#define LEMON_CONCEPTS_HEAP_H + +///\ingroup concept +///\file +///\brief The concept of heaps. + +#include +#include + +namespace lemon { + + namespace concepts { + + /// \addtogroup concept + /// @{ + + /// \brief The heap concept. + /// + /// This concept class describes the main interface of heaps. + /// The various \ref heaps "heap structures" are efficient + /// implementations of the abstract data type \e priority \e queue. + /// They store items with specified values called \e priorities + /// in such a way that finding and removing the item with minimum + /// priority are efficient. The basic operations are adding and + /// erasing items, changing the priority of an item, etc. + /// + /// Heaps are crucial in several algorithms, such as Dijkstra and Prim. + /// Any class that conforms to this concept can be used easily in such + /// algorithms. + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. +#ifdef DOXYGEN + template +#else + template > +#endif + class Heap { + public: + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. The "in heap" state constant. + PRE_HEAP = -1, ///< = -1. The "pre-heap" state constant. + POST_HEAP = -2 ///< = -2. The "post-heap" state constant. + }; + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to keys of type + /// \c Item. It is used internally by the heap implementations to + /// handle the cross references. The assigned value must be + /// \c PRE_HEAP (-1) for each item. +#ifdef DOXYGEN + explicit Heap(ItemIntMap &map) {} +#else + explicit Heap(ItemIntMap&) {} +#endif + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to keys of type + /// \c Item. It is used internally by the heap implementations to + /// handle the cross references. The assigned value must be + /// \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. +#ifdef DOXYGEN + explicit Heap(ItemIntMap &map, const CMP &comp) {} +#else + explicit Heap(ItemIntMap&, const CMP&) {} +#endif + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return 0; } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return false; } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() {} + + /// \brief Insert an item into the heap with the given priority. + /// + /// This function inserts the given item into the heap with the + /// given priority. + /// \param i The item to insert. + /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. +#ifdef DOXYGEN + void push(const Item &i, const Prio &p) {} +#else + void push(const Item&, const Prio&) {} +#endif + + /// \brief Return the item having minimum priority. + /// + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { return Item(); } + + /// \brief The minimum priority. + /// + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { return Prio(); } + + /// \brief Remove the item having minimum priority. + /// + /// This function removes the item having minimum priority. + /// \pre The heap must be non-empty. + void pop() {} + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. +#ifdef DOXYGEN + void erase(const Item &i) {} +#else + void erase(const Item&) {} +#endif + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param i The item. + /// \pre \e i must be in the heap. +#ifdef DOXYGEN + Prio operator[](const Item &i) const {} +#else + Prio operator[](const Item&) const { return Prio(); } +#endif + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// + /// \param i The item. + /// \param p The priority. +#ifdef DOXYGEN + void set(const Item &i, const Prio &p) {} +#else + void set(const Item&, const Prio&) {} +#endif + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at least \e p. +#ifdef DOXYGEN + void decrease(const Item &i, const Prio &p) {} +#else + void decrease(const Item&, const Prio&) {} +#endif + + /// \brief Increase the priority of an item to the given value. + /// + /// This function increases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at most \e p. +#ifdef DOXYGEN + void increase(const Item &i, const Prio &p) {} +#else + void increase(const Item&, const Prio&) {} +#endif + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param i The item. +#ifdef DOXYGEN + State state(const Item &i) const {} +#else + State state(const Item&) const { return PRE_HEAP; } +#endif + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. +#ifdef DOXYGEN + void state(const Item& i, State st) {} +#else + void state(const Item&, State) {} +#endif + + + template + struct Constraints { + public: + void constraints() { + typedef typename _Heap::Item OwnItem; + typedef typename _Heap::Prio OwnPrio; + typedef typename _Heap::State OwnState; + + Item item; + Prio prio; + item=Item(); + prio=Prio(); + ignore_unused_variable_warning(item); + ignore_unused_variable_warning(prio); + + OwnItem own_item; + OwnPrio own_prio; + OwnState own_state; + own_item=Item(); + own_prio=Prio(); + ignore_unused_variable_warning(own_item); + ignore_unused_variable_warning(own_prio); + ignore_unused_variable_warning(own_state); + + _Heap heap1(map); + _Heap heap2 = heap1; + ignore_unused_variable_warning(heap1); + ignore_unused_variable_warning(heap2); + + int s = heap.size(); + ignore_unused_variable_warning(s); + bool e = heap.empty(); + ignore_unused_variable_warning(e); + + prio = heap.prio(); + item = heap.top(); + prio = heap[item]; + own_prio = heap.prio(); + own_item = heap.top(); + own_prio = heap[own_item]; + + heap.push(item, prio); + heap.push(own_item, own_prio); + heap.pop(); + + heap.set(item, prio); + heap.decrease(item, prio); + heap.increase(item, prio); + heap.set(own_item, own_prio); + heap.decrease(own_item, own_prio); + heap.increase(own_item, own_prio); + + heap.erase(item); + heap.erase(own_item); + heap.clear(); + + own_state = heap.state(own_item); + heap.state(own_item, own_state); + + own_state = _Heap::PRE_HEAP; + own_state = _Heap::IN_HEAP; + own_state = _Heap::POST_HEAP; + } + + _Heap& heap; + ItemIntMap& map; + }; + }; + + /// @} + } // namespace lemon +} +#endif diff --git a/lemon/lemon/concepts/maps.h b/lemon/lemon/concepts/maps.h new file mode 100644 index 0000000..df73624 --- /dev/null +++ b/lemon/lemon/concepts/maps.h @@ -0,0 +1,217 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CONCEPTS_MAPS_H +#define LEMON_CONCEPTS_MAPS_H + +#include +#include + +///\ingroup map_concepts +///\file +///\brief The concept of maps. + +namespace lemon { + + namespace concepts { + + /// \addtogroup map_concepts + /// @{ + + /// Readable map concept + + /// Readable map concept. + /// + template + class ReadMap + { + public: + /// The key type of the map. + typedef K Key; + /// \brief The value type of the map. + /// (The type of objects associated with the keys). + typedef T Value; + + /// Returns the value associated with the given key. + Value operator[](const Key &) const { + return *static_cast(0); + } + + template + struct Constraints { + void constraints() { + Value val = m[key]; + val = m[key]; + typename _ReadMap::Value own_val = m[own_key]; + own_val = m[own_key]; + + ignore_unused_variable_warning(key); + ignore_unused_variable_warning(val); + ignore_unused_variable_warning(own_key); + ignore_unused_variable_warning(own_val); + } + const Key& key; + const typename _ReadMap::Key& own_key; + const _ReadMap& m; + }; + + }; + + + /// Writable map concept + + /// Writable map concept. + /// + template + class WriteMap + { + public: + /// The key type of the map. + typedef K Key; + /// \brief The value type of the map. + /// (The type of objects associated with the keys). + typedef T Value; + + /// Sets the value associated with the given key. + void set(const Key &, const Value &) {} + + /// Default constructor. + WriteMap() {} + + template + struct Constraints { + void constraints() { + m.set(key, val); + m.set(own_key, own_val); + + ignore_unused_variable_warning(key); + ignore_unused_variable_warning(val); + ignore_unused_variable_warning(own_key); + ignore_unused_variable_warning(own_val); + } + const Key& key; + const Value& val; + const typename _WriteMap::Key& own_key; + const typename _WriteMap::Value& own_val; + _WriteMap& m; + }; + }; + + /// Read/writable map concept + + /// Read/writable map concept. + /// + template + class ReadWriteMap : public ReadMap, + public WriteMap + { + public: + /// The key type of the map. + typedef K Key; + /// \brief The value type of the map. + /// (The type of objects associated with the keys). + typedef T Value; + + /// Returns the value associated with the given key. + Value operator[](const Key &) const { + return *static_cast(0); + } + + /// Sets the value associated with the given key. + void set(const Key &, const Value &) {} + + template + struct Constraints { + void constraints() { + checkConcept, _ReadWriteMap >(); + checkConcept, _ReadWriteMap >(); + } + }; + }; + + + /// Dereferable map concept + + /// Dereferable map concept. + /// + template + class ReferenceMap : public ReadWriteMap + { + public: + /// Tag for reference maps. + typedef True ReferenceMapTag; + /// The key type of the map. + typedef K Key; + /// \brief The value type of the map. + /// (The type of objects associated with the keys). + typedef T Value; + /// The reference type of the map. + typedef R Reference; + /// The const reference type of the map. + typedef CR ConstReference; + + public: + + /// Returns a reference to the value associated with the given key. + Reference operator[](const Key &) { + return *static_cast(0); + } + + /// Returns a const reference to the value associated with the given key. + ConstReference operator[](const Key &) const { + return *static_cast(0); + } + + /// Sets the value associated with the given key. + void set(const Key &k,const Value &t) { operator[](k)=t; } + + template + struct Constraints { + typename enable_if::type + constraints() { + checkConcept, _ReferenceMap >(); + ref = m[key]; + m[key] = val; + m[key] = ref; + m[key] = cref; + own_ref = m[own_key]; + m[own_key] = own_val; + m[own_key] = own_ref; + m[own_key] = own_cref; + m[key] = m[own_key]; + m[own_key] = m[key]; + } + const Key& key; + Value& val; + Reference ref; + ConstReference cref; + const typename _ReferenceMap::Key& own_key; + typename _ReferenceMap::Value& own_val; + typename _ReferenceMap::Reference own_ref; + typename _ReferenceMap::ConstReference own_cref; + _ReferenceMap& m; + }; + }; + + // @} + + } //namespace concepts + +} //namespace lemon + +#endif diff --git a/lemon/lemon/concepts/path.h b/lemon/lemon/concepts/path.h new file mode 100644 index 0000000..fe32284 --- /dev/null +++ b/lemon/lemon/concepts/path.h @@ -0,0 +1,310 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup concept +///\file +///\brief The concept of paths +/// + +#ifndef LEMON_CONCEPTS_PATH_H +#define LEMON_CONCEPTS_PATH_H + +#include +#include + +namespace lemon { + namespace concepts { + + /// \addtogroup concept + /// @{ + + /// \brief A skeleton structure for representing directed paths in + /// a digraph. + /// + /// A skeleton structure for representing directed paths in a + /// digraph. + /// In a sense, a path can be treated as a list of arcs. + /// LEMON path types just store this list. As a consequence, they cannot + /// enumerate the nodes on the path directly and a zero length path + /// cannot store its source node. + /// + /// The arcs of a path should be stored in the order of their directions, + /// i.e. the target node of each arc should be the same as the source + /// node of the next arc. This consistency could be checked using + /// \ref checkPath(). + /// The source and target nodes of a (consistent) path can be obtained + /// using \ref pathSource() and \ref pathTarget(). + /// + /// A path can be constructed from another path of any type using the + /// copy constructor or the assignment operator. + /// + /// \tparam GR The digraph type in which the path is. + template + class Path { + public: + + /// Type of the underlying digraph. + typedef GR Digraph; + /// Arc type of the underlying digraph. + typedef typename Digraph::Arc Arc; + + class ArcIt; + + /// \brief Default constructor + Path() {} + + /// \brief Template copy constructor + template + Path(const CPath& cpath) {} + + /// \brief Template assigment operator + template + Path& operator=(const CPath& cpath) { + ignore_unused_variable_warning(cpath); + return *this; + } + + /// Length of the path, i.e. the number of arcs on the path. + int length() const { return 0;} + + /// Returns whether the path is empty. + bool empty() const { return true;} + + /// Resets the path to an empty path. + void clear() {} + + /// \brief LEMON style iterator for enumerating the arcs of a path. + /// + /// LEMON style iterator class for enumerating the arcs of a path. + class ArcIt { + public: + /// Default constructor + ArcIt() {} + /// Invalid constructor + ArcIt(Invalid) {} + /// Sets the iterator to the first arc of the given path + ArcIt(const Path &) {} + + /// Conversion to \c Arc + operator Arc() const { return INVALID; } + + /// Next arc + ArcIt& operator++() {return *this;} + + /// Comparison operator + bool operator==(const ArcIt&) const {return true;} + /// Comparison operator + bool operator!=(const ArcIt&) const {return true;} + /// Comparison operator + bool operator<(const ArcIt&) const {return false;} + + }; + + template + struct Constraints { + void constraints() { + Path pc; + _Path p, pp(pc); + int l = p.length(); + int e = p.empty(); + p.clear(); + + p = pc; + + typename _Path::ArcIt id, ii(INVALID), i(p); + + ++i; + typename Digraph::Arc ed = i; + + e = (i == ii); + e = (i != ii); + e = (i < ii); + + ignore_unused_variable_warning(l); + ignore_unused_variable_warning(pp); + ignore_unused_variable_warning(e); + ignore_unused_variable_warning(id); + ignore_unused_variable_warning(ii); + ignore_unused_variable_warning(ed); + } + }; + + }; + + namespace _path_bits { + + template + struct PathDumperConstraints { + void constraints() { + int l = p.length(); + int e = p.empty(); + + typename _Path::ArcIt id, i(p); + + ++i; + typename _Digraph::Arc ed = i; + + e = (i == INVALID); + e = (i != INVALID); + + ignore_unused_variable_warning(l); + ignore_unused_variable_warning(e); + ignore_unused_variable_warning(id); + ignore_unused_variable_warning(ed); + } + _Path& p; + }; + + template + struct PathDumperConstraints< + _Digraph, _Path, + typename enable_if::type + > { + void constraints() { + int l = p.length(); + int e = p.empty(); + + typename _Path::RevArcIt id, i(p); + + ++i; + typename _Digraph::Arc ed = i; + + e = (i == INVALID); + e = (i != INVALID); + + ignore_unused_variable_warning(l); + ignore_unused_variable_warning(e); + ignore_unused_variable_warning(id); + ignore_unused_variable_warning(ed); + } + _Path& p; + }; + + } + + + /// \brief A skeleton structure for path dumpers. + /// + /// A skeleton structure for path dumpers. The path dumpers are + /// the generalization of the paths, they can enumerate the arcs + /// of the path either in forward or in backward order. + /// These classes are typically not used directly, they are rather + /// used to be assigned to a real path type. + /// + /// The main purpose of this concept is that the shortest path + /// algorithms can enumerate the arcs easily in reverse order. + /// In LEMON, such algorithms give back a (reverse) path dumper that + /// can be assigned to a real path. The dumpers can be implemented as + /// an adaptor class to the predecessor map. + /// + /// \tparam GR The digraph type in which the path is. + template + class PathDumper { + public: + + /// Type of the underlying digraph. + typedef GR Digraph; + /// Arc type of the underlying digraph. + typedef typename Digraph::Arc Arc; + + /// Length of the path, i.e. the number of arcs on the path. + int length() const { return 0;} + + /// Returns whether the path is empty. + bool empty() const { return true;} + + /// \brief Forward or reverse dumping + /// + /// If this tag is defined to be \c True, then reverse dumping + /// is provided in the path dumper. In this case, \c RevArcIt + /// iterator should be implemented instead of \c ArcIt iterator. + typedef False RevPathTag; + + /// \brief LEMON style iterator for enumerating the arcs of a path. + /// + /// LEMON style iterator class for enumerating the arcs of a path. + class ArcIt { + public: + /// Default constructor + ArcIt() {} + /// Invalid constructor + ArcIt(Invalid) {} + /// Sets the iterator to the first arc of the given path + ArcIt(const PathDumper&) {} + + /// Conversion to \c Arc + operator Arc() const { return INVALID; } + + /// Next arc + ArcIt& operator++() {return *this;} + + /// Comparison operator + bool operator==(const ArcIt&) const {return true;} + /// Comparison operator + bool operator!=(const ArcIt&) const {return true;} + /// Comparison operator + bool operator<(const ArcIt&) const {return false;} + + }; + + /// \brief LEMON style iterator for enumerating the arcs of a path + /// in reverse direction. + /// + /// LEMON style iterator class for enumerating the arcs of a path + /// in reverse direction. + class RevArcIt { + public: + /// Default constructor + RevArcIt() {} + /// Invalid constructor + RevArcIt(Invalid) {} + /// Sets the iterator to the last arc of the given path + RevArcIt(const PathDumper &) {} + + /// Conversion to \c Arc + operator Arc() const { return INVALID; } + + /// Next arc + RevArcIt& operator++() {return *this;} + + /// Comparison operator + bool operator==(const RevArcIt&) const {return true;} + /// Comparison operator + bool operator!=(const RevArcIt&) const {return true;} + /// Comparison operator + bool operator<(const RevArcIt&) const {return false;} + + }; + + template + struct Constraints { + void constraints() { + function_requires<_path_bits:: + PathDumperConstraints >(); + } + }; + + }; + + + ///@} + } + +} // namespace lemon + +#endif diff --git a/lemon/lemon/config.h b/lemon/lemon/config.h new file mode 100644 index 0000000..170920c --- /dev/null +++ b/lemon/lemon/config.h @@ -0,0 +1,27 @@ +/* lemon/config.h. Generated from config.h.in by configure. */ +/* The version string */ +#define LEMON_VERSION 1.2.3 + +/* Define to 1 if you have long long */ +#define LEMON_HAVE_LONG_LONG 1 + +/* Define to 1 if you have any LP solver. */ +/* #undef LEMON_HAVE_LP */ + +/* Define to 1 if you have any MIP solver. */ +/* #undef LEMON_HAVE_MIP */ + +/* Define to 1 if you have CPLEX. */ +/* #undef LEMON_HAVE_CPLEX */ + +/* Define to 1 if you have GLPK. */ +/* #undef LEMON_HAVE_GLPK */ + +/* Define to 1 if you have SOPLEX */ +/* #undef LEMON_HAVE_SOPLEX */ + +/* Define to 1 if you have CLP */ +/* #undef LEMON_HAVE_CLP */ + +/* Define to 1 if you have CBC */ +/* #undef LEMON_HAVE_CBC */ diff --git a/lemon/lemon/config.h.cmake b/lemon/lemon/config.h.cmake new file mode 100644 index 0000000..3c3f870 --- /dev/null +++ b/lemon/lemon/config.h.cmake @@ -0,0 +1,8 @@ +#define LEMON_VERSION "@PROJECT_VERSION@" +#cmakedefine LEMON_HAVE_LONG_LONG 1 +#cmakedefine LEMON_HAVE_LP 1 +#cmakedefine LEMON_HAVE_MIP 1 +#cmakedefine LEMON_HAVE_GLPK 1 +#cmakedefine LEMON_HAVE_CPLEX 1 +#cmakedefine LEMON_HAVE_CLP 1 +#cmakedefine LEMON_HAVE_CBC 1 diff --git a/lemon/lemon/config.h.in b/lemon/lemon/config.h.in new file mode 100644 index 0000000..94d606e --- /dev/null +++ b/lemon/lemon/config.h.in @@ -0,0 +1,26 @@ +/* The version string */ +#undef LEMON_VERSION + +/* Define to 1 if you have long long */ +#undef LEMON_HAVE_LONG_LONG + +/* Define to 1 if you have any LP solver. */ +#undef LEMON_HAVE_LP + +/* Define to 1 if you have any MIP solver. */ +#undef LEMON_HAVE_MIP + +/* Define to 1 if you have CPLEX. */ +#undef LEMON_HAVE_CPLEX + +/* Define to 1 if you have GLPK. */ +#undef LEMON_HAVE_GLPK + +/* Define to 1 if you have SOPLEX */ +#undef LEMON_HAVE_SOPLEX + +/* Define to 1 if you have CLP */ +#undef LEMON_HAVE_CLP + +/* Define to 1 if you have CBC */ +#undef LEMON_HAVE_CBC diff --git a/lemon/lemon/connectivity.h b/lemon/lemon/connectivity.h new file mode 100644 index 0000000..19f6df5 --- /dev/null +++ b/lemon/lemon/connectivity.h @@ -0,0 +1,1665 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CONNECTIVITY_H +#define LEMON_CONNECTIVITY_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +/// \ingroup graph_properties +/// \file +/// \brief Connectivity algorithms +/// +/// Connectivity algorithms + +namespace lemon { + + /// \ingroup graph_properties + /// + /// \brief Check whether an undirected graph is connected. + /// + /// This function checks whether the given undirected graph is connected, + /// i.e. there is a path between any two nodes in the graph. + /// + /// \return \c true if the graph is connected. + /// \note By definition, the empty graph is connected. + /// + /// \see countConnectedComponents(), connectedComponents() + /// \see stronglyConnected() + template + bool connected(const Graph& graph) { + checkConcept(); + typedef typename Graph::NodeIt NodeIt; + if (NodeIt(graph) == INVALID) return true; + Dfs dfs(graph); + dfs.run(NodeIt(graph)); + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + return false; + } + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Count the number of connected components of an undirected graph + /// + /// This function counts the number of connected components of the given + /// undirected graph. + /// + /// The connected components are the classes of an equivalence relation + /// on the nodes of an undirected graph. Two nodes are in the same class + /// if they are connected with a path. + /// + /// \return The number of connected components. + /// \note By definition, the empty graph consists + /// of zero connected components. + /// + /// \see connected(), connectedComponents() + template + int countConnectedComponents(const Graph &graph) { + checkConcept(); + typedef typename Graph::Node Node; + typedef typename Graph::Arc Arc; + + typedef NullMap PredMap; + typedef NullMap DistMap; + + int compNum = 0; + typename Bfs:: + template SetPredMap:: + template SetDistMap:: + Create bfs(graph); + + PredMap predMap; + bfs.predMap(predMap); + + DistMap distMap; + bfs.distMap(distMap); + + bfs.init(); + for(typename Graph::NodeIt n(graph); n != INVALID; ++n) { + if (!bfs.reached(n)) { + bfs.addSource(n); + bfs.start(); + ++compNum; + } + } + return compNum; + } + + /// \ingroup graph_properties + /// + /// \brief Find the connected components of an undirected graph + /// + /// This function finds the connected components of the given undirected + /// graph. + /// + /// The connected components are the classes of an equivalence relation + /// on the nodes of an undirected graph. Two nodes are in the same class + /// if they are connected with a path. + /// + /// \image html connected_components.png + /// \image latex connected_components.eps "Connected components" width=\textwidth + /// + /// \param graph The undirected graph. + /// \retval compMap A writable node map. The values will be set from 0 to + /// the number of the connected components minus one. Each value of the map + /// will be set exactly once, and the values of a certain component will be + /// set continuously. + /// \return The number of connected components. + /// \note By definition, the empty graph consists + /// of zero connected components. + /// + /// \see connected(), countConnectedComponents() + template + int connectedComponents(const Graph &graph, NodeMap &compMap) { + checkConcept(); + typedef typename Graph::Node Node; + typedef typename Graph::Arc Arc; + checkConcept, NodeMap>(); + + typedef NullMap PredMap; + typedef NullMap DistMap; + + int compNum = 0; + typename Bfs:: + template SetPredMap:: + template SetDistMap:: + Create bfs(graph); + + PredMap predMap; + bfs.predMap(predMap); + + DistMap distMap; + bfs.distMap(distMap); + + bfs.init(); + for(typename Graph::NodeIt n(graph); n != INVALID; ++n) { + if(!bfs.reached(n)) { + bfs.addSource(n); + while (!bfs.emptyQueue()) { + compMap.set(bfs.nextNode(), compNum); + bfs.processNextNode(); + } + ++compNum; + } + } + return compNum; + } + + namespace _connectivity_bits { + + template + struct LeaveOrderVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + LeaveOrderVisitor(Iterator it) : _it(it) {} + + void leave(const Node& node) { + *(_it++) = node; + } + + private: + Iterator _it; + }; + + template + struct FillMapVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Map::Value Value; + + FillMapVisitor(Map& map, Value& value) + : _map(map), _value(value) {} + + void reach(const Node& node) { + _map.set(node, _value); + } + private: + Map& _map; + Value& _value; + }; + + template + struct StronglyConnectedCutArcsVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + + StronglyConnectedCutArcsVisitor(const Digraph& digraph, + ArcMap& cutMap, + int& cutNum) + : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum), + _compMap(digraph, -1), _num(-1) { + } + + void start(const Node&) { + ++_num; + } + + void reach(const Node& node) { + _compMap.set(node, _num); + } + + void examine(const Arc& arc) { + if (_compMap[_digraph.source(arc)] != + _compMap[_digraph.target(arc)]) { + _cutMap.set(arc, true); + ++_cutNum; + } + } + private: + const Digraph& _digraph; + ArcMap& _cutMap; + int& _cutNum; + + typename Digraph::template NodeMap _compMap; + int _num; + }; + + } + + + /// \ingroup graph_properties + /// + /// \brief Check whether a directed graph is strongly connected. + /// + /// This function checks whether the given directed graph is strongly + /// connected, i.e. any two nodes of the digraph are + /// connected with directed paths in both direction. + /// + /// \return \c true if the digraph is strongly connected. + /// \note By definition, the empty digraph is strongly connected. + /// + /// \see countStronglyConnectedComponents(), stronglyConnectedComponents() + /// \see connected() + template + bool stronglyConnected(const Digraph& digraph) { + checkConcept(); + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + + typename Digraph::Node source = NodeIt(digraph); + if (source == INVALID) return true; + + using namespace _connectivity_bits; + + typedef DfsVisitor Visitor; + Visitor visitor; + + DfsVisit dfs(digraph, visitor); + dfs.init(); + dfs.addSource(source); + dfs.start(); + + for (NodeIt it(digraph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + return false; + } + } + + typedef ReverseDigraph RDigraph; + typedef typename RDigraph::NodeIt RNodeIt; + RDigraph rdigraph(digraph); + + typedef DfsVisitor RVisitor; + RVisitor rvisitor; + + DfsVisit rdfs(rdigraph, rvisitor); + rdfs.init(); + rdfs.addSource(source); + rdfs.start(); + + for (RNodeIt it(rdigraph); it != INVALID; ++it) { + if (!rdfs.reached(it)) { + return false; + } + } + + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Count the number of strongly connected components of a + /// directed graph + /// + /// This function counts the number of strongly connected components of + /// the given directed graph. + /// + /// The strongly connected components are the classes of an + /// equivalence relation on the nodes of a digraph. Two nodes are in + /// the same class if they are connected with directed paths in both + /// direction. + /// + /// \return The number of strongly connected components. + /// \note By definition, the empty digraph has zero + /// strongly connected components. + /// + /// \see stronglyConnected(), stronglyConnectedComponents() + template + int countStronglyConnectedComponents(const Digraph& digraph) { + checkConcept(); + + using namespace _connectivity_bits; + + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::ArcIt ArcIt; + + typedef std::vector Container; + typedef typename Container::iterator Iterator; + + Container nodes(countNodes(digraph)); + typedef LeaveOrderVisitor Visitor; + Visitor visitor(nodes.begin()); + + DfsVisit dfs(digraph, visitor); + dfs.init(); + for (NodeIt it(digraph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + + typedef typename Container::reverse_iterator RIterator; + typedef ReverseDigraph RDigraph; + + RDigraph rdigraph(digraph); + + typedef DfsVisitor RVisitor; + RVisitor rvisitor; + + DfsVisit rdfs(rdigraph, rvisitor); + + int compNum = 0; + + rdfs.init(); + for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) { + if (!rdfs.reached(*it)) { + rdfs.addSource(*it); + rdfs.start(); + ++compNum; + } + } + return compNum; + } + + /// \ingroup graph_properties + /// + /// \brief Find the strongly connected components of a directed graph + /// + /// This function finds the strongly connected components of the given + /// directed graph. In addition, the numbering of the components will + /// satisfy that there is no arc going from a higher numbered component + /// to a lower one (i.e. it provides a topological order of the components). + /// + /// The strongly connected components are the classes of an + /// equivalence relation on the nodes of a digraph. Two nodes are in + /// the same class if they are connected with directed paths in both + /// direction. + /// + /// \image html strongly_connected_components.png + /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth + /// + /// \param digraph The digraph. + /// \retval compMap A writable node map. The values will be set from 0 to + /// the number of the strongly connected components minus one. Each value + /// of the map will be set exactly once, and the values of a certain + /// component will be set continuously. + /// \return The number of strongly connected components. + /// \note By definition, the empty digraph has zero + /// strongly connected components. + /// + /// \see stronglyConnected(), countStronglyConnectedComponents() + template + int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) { + checkConcept(); + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + checkConcept, NodeMap>(); + + using namespace _connectivity_bits; + + typedef std::vector Container; + typedef typename Container::iterator Iterator; + + Container nodes(countNodes(digraph)); + typedef LeaveOrderVisitor Visitor; + Visitor visitor(nodes.begin()); + + DfsVisit dfs(digraph, visitor); + dfs.init(); + for (NodeIt it(digraph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + + typedef typename Container::reverse_iterator RIterator; + typedef ReverseDigraph RDigraph; + + RDigraph rdigraph(digraph); + + int compNum = 0; + + typedef FillMapVisitor RVisitor; + RVisitor rvisitor(compMap, compNum); + + DfsVisit rdfs(rdigraph, rvisitor); + + rdfs.init(); + for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) { + if (!rdfs.reached(*it)) { + rdfs.addSource(*it); + rdfs.start(); + ++compNum; + } + } + return compNum; + } + + /// \ingroup graph_properties + /// + /// \brief Find the cut arcs of the strongly connected components. + /// + /// This function finds the cut arcs of the strongly connected components + /// of the given digraph. + /// + /// The strongly connected components are the classes of an + /// equivalence relation on the nodes of a digraph. Two nodes are in + /// the same class if they are connected with directed paths in both + /// direction. + /// The strongly connected components are separated by the cut arcs. + /// + /// \param digraph The digraph. + /// \retval cutMap A writable arc map. The values will be set to \c true + /// for the cut arcs (exactly once for each cut arc), and will not be + /// changed for other arcs. + /// \return The number of cut arcs. + /// + /// \see stronglyConnected(), stronglyConnectedComponents() + template + int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) { + checkConcept(); + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::NodeIt NodeIt; + checkConcept, ArcMap>(); + + using namespace _connectivity_bits; + + typedef std::vector Container; + typedef typename Container::iterator Iterator; + + Container nodes(countNodes(digraph)); + typedef LeaveOrderVisitor Visitor; + Visitor visitor(nodes.begin()); + + DfsVisit dfs(digraph, visitor); + dfs.init(); + for (NodeIt it(digraph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + + typedef typename Container::reverse_iterator RIterator; + typedef ReverseDigraph RDigraph; + + RDigraph rdigraph(digraph); + + int cutNum = 0; + + typedef StronglyConnectedCutArcsVisitor RVisitor; + RVisitor rvisitor(rdigraph, cutMap, cutNum); + + DfsVisit rdfs(rdigraph, rvisitor); + + rdfs.init(); + for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) { + if (!rdfs.reached(*it)) { + rdfs.addSource(*it); + rdfs.start(); + } + } + return cutNum; + } + + namespace _connectivity_bits { + + template + class CountBiNodeConnectedComponentsVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Edge Edge; + + CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum) + : _graph(graph), _compNum(compNum), + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {} + + void start(const Node& node) { + _predMap.set(node, INVALID); + } + + void reach(const Node& node) { + _numMap.set(node, _num); + _retMap.set(node, _num); + ++_num; + } + + void discover(const Arc& edge) { + _predMap.set(_graph.target(edge), _graph.source(edge)); + } + + void examine(const Arc& edge) { + if (_graph.source(edge) == _graph.target(edge) && + _graph.direction(edge)) { + ++_compNum; + return; + } + if (_predMap[_graph.source(edge)] == _graph.target(edge)) { + return; + } + if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]); + } + } + + void backtrack(const Arc& edge) { + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) { + ++_compNum; + } + } + + private: + const Digraph& _graph; + int& _compNum; + + typename Digraph::template NodeMap _numMap; + typename Digraph::template NodeMap _retMap; + typename Digraph::template NodeMap _predMap; + int _num; + }; + + template + class BiNodeConnectedComponentsVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Edge Edge; + + BiNodeConnectedComponentsVisitor(const Digraph& graph, + ArcMap& compMap, int &compNum) + : _graph(graph), _compMap(compMap), _compNum(compNum), + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {} + + void start(const Node& node) { + _predMap.set(node, INVALID); + } + + void reach(const Node& node) { + _numMap.set(node, _num); + _retMap.set(node, _num); + ++_num; + } + + void discover(const Arc& edge) { + Node target = _graph.target(edge); + _predMap.set(target, edge); + _edgeStack.push(edge); + } + + void examine(const Arc& edge) { + Node source = _graph.source(edge); + Node target = _graph.target(edge); + if (source == target && _graph.direction(edge)) { + _compMap.set(edge, _compNum); + ++_compNum; + return; + } + if (_numMap[target] < _numMap[source]) { + if (_predMap[source] != _graph.oppositeArc(edge)) { + _edgeStack.push(edge); + } + } + if (_predMap[source] != INVALID && + target == _graph.source(_predMap[source])) { + return; + } + if (_retMap[source] > _numMap[target]) { + _retMap.set(source, _numMap[target]); + } + } + + void backtrack(const Arc& edge) { + Node source = _graph.source(edge); + Node target = _graph.target(edge); + if (_retMap[source] > _retMap[target]) { + _retMap.set(source, _retMap[target]); + } + if (_numMap[source] <= _retMap[target]) { + while (_edgeStack.top() != edge) { + _compMap.set(_edgeStack.top(), _compNum); + _edgeStack.pop(); + } + _compMap.set(edge, _compNum); + _edgeStack.pop(); + ++_compNum; + } + } + + private: + const Digraph& _graph; + ArcMap& _compMap; + int& _compNum; + + typename Digraph::template NodeMap _numMap; + typename Digraph::template NodeMap _retMap; + typename Digraph::template NodeMap _predMap; + std::stack _edgeStack; + int _num; + }; + + + template + class BiNodeConnectedCutNodesVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Edge Edge; + + BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap, + int& cutNum) + : _graph(graph), _cutMap(cutMap), _cutNum(cutNum), + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {} + + void start(const Node& node) { + _predMap.set(node, INVALID); + rootCut = false; + } + + void reach(const Node& node) { + _numMap.set(node, _num); + _retMap.set(node, _num); + ++_num; + } + + void discover(const Arc& edge) { + _predMap.set(_graph.target(edge), _graph.source(edge)); + } + + void examine(const Arc& edge) { + if (_graph.source(edge) == _graph.target(edge) && + _graph.direction(edge)) { + if (!_cutMap[_graph.source(edge)]) { + _cutMap.set(_graph.source(edge), true); + ++_cutNum; + } + return; + } + if (_predMap[_graph.source(edge)] == _graph.target(edge)) return; + if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]); + } + } + + void backtrack(const Arc& edge) { + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) { + if (_predMap[_graph.source(edge)] != INVALID) { + if (!_cutMap[_graph.source(edge)]) { + _cutMap.set(_graph.source(edge), true); + ++_cutNum; + } + } else if (rootCut) { + if (!_cutMap[_graph.source(edge)]) { + _cutMap.set(_graph.source(edge), true); + ++_cutNum; + } + } else { + rootCut = true; + } + } + } + + private: + const Digraph& _graph; + NodeMap& _cutMap; + int& _cutNum; + + typename Digraph::template NodeMap _numMap; + typename Digraph::template NodeMap _retMap; + typename Digraph::template NodeMap _predMap; + std::stack _edgeStack; + int _num; + bool rootCut; + }; + + } + + template + int countBiNodeConnectedComponents(const Graph& graph); + + /// \ingroup graph_properties + /// + /// \brief Check whether an undirected graph is bi-node-connected. + /// + /// This function checks whether the given undirected graph is + /// bi-node-connected, i.e. any two edges are on same circle. + /// + /// \return \c true if the graph bi-node-connected. + /// \note By definition, the empty graph is bi-node-connected. + /// + /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents() + template + bool biNodeConnected(const Graph& graph) { + return countBiNodeConnectedComponents(graph) <= 1; + } + + /// \ingroup graph_properties + /// + /// \brief Count the number of bi-node-connected components of an + /// undirected graph. + /// + /// This function counts the number of bi-node-connected components of + /// the given undirected graph. + /// + /// The bi-node-connected components are the classes of an equivalence + /// relation on the edges of a undirected graph. Two edges are in the + /// same class if they are on same circle. + /// + /// \return The number of bi-node-connected components. + /// + /// \see biNodeConnected(), biNodeConnectedComponents() + template + int countBiNodeConnectedComponents(const Graph& graph) { + checkConcept(); + typedef typename Graph::NodeIt NodeIt; + + using namespace _connectivity_bits; + + typedef CountBiNodeConnectedComponentsVisitor Visitor; + + int compNum = 0; + Visitor visitor(graph, compNum); + + DfsVisit dfs(graph, visitor); + dfs.init(); + + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + return compNum; + } + + /// \ingroup graph_properties + /// + /// \brief Find the bi-node-connected components of an undirected graph. + /// + /// This function finds the bi-node-connected components of the given + /// undirected graph. + /// + /// The bi-node-connected components are the classes of an equivalence + /// relation on the edges of a undirected graph. Two edges are in the + /// same class if they are on same circle. + /// + /// \image html node_biconnected_components.png + /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth + /// + /// \param graph The undirected graph. + /// \retval compMap A writable edge map. The values will be set from 0 + /// to the number of the bi-node-connected components minus one. Each + /// value of the map will be set exactly once, and the values of a + /// certain component will be set continuously. + /// \return The number of bi-node-connected components. + /// + /// \see biNodeConnected(), countBiNodeConnectedComponents() + template + int biNodeConnectedComponents(const Graph& graph, + EdgeMap& compMap) { + checkConcept(); + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Edge Edge; + checkConcept, EdgeMap>(); + + using namespace _connectivity_bits; + + typedef BiNodeConnectedComponentsVisitor Visitor; + + int compNum = 0; + Visitor visitor(graph, compMap, compNum); + + DfsVisit dfs(graph, visitor); + dfs.init(); + + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + return compNum; + } + + /// \ingroup graph_properties + /// + /// \brief Find the bi-node-connected cut nodes in an undirected graph. + /// + /// This function finds the bi-node-connected cut nodes in the given + /// undirected graph. + /// + /// The bi-node-connected components are the classes of an equivalence + /// relation on the edges of a undirected graph. Two edges are in the + /// same class if they are on same circle. + /// The bi-node-connected components are separted by the cut nodes of + /// the components. + /// + /// \param graph The undirected graph. + /// \retval cutMap A writable node map. The values will be set to + /// \c true for the nodes that separate two or more components + /// (exactly once for each cut node), and will not be changed for + /// other nodes. + /// \return The number of the cut nodes. + /// + /// \see biNodeConnected(), biNodeConnectedComponents() + template + int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) { + checkConcept(); + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + checkConcept, NodeMap>(); + + using namespace _connectivity_bits; + + typedef BiNodeConnectedCutNodesVisitor Visitor; + + int cutNum = 0; + Visitor visitor(graph, cutMap, cutNum); + + DfsVisit dfs(graph, visitor); + dfs.init(); + + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + return cutNum; + } + + namespace _connectivity_bits { + + template + class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Edge Edge; + + CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum) + : _graph(graph), _compNum(compNum), + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {} + + void start(const Node& node) { + _predMap.set(node, INVALID); + } + + void reach(const Node& node) { + _numMap.set(node, _num); + _retMap.set(node, _num); + ++_num; + } + + void leave(const Node& node) { + if (_numMap[node] <= _retMap[node]) { + ++_compNum; + } + } + + void discover(const Arc& edge) { + _predMap.set(_graph.target(edge), edge); + } + + void examine(const Arc& edge) { + if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) { + return; + } + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + } + + void backtrack(const Arc& edge) { + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + } + + private: + const Digraph& _graph; + int& _compNum; + + typename Digraph::template NodeMap _numMap; + typename Digraph::template NodeMap _retMap; + typename Digraph::template NodeMap _predMap; + int _num; + }; + + template + class BiEdgeConnectedComponentsVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Edge Edge; + + BiEdgeConnectedComponentsVisitor(const Digraph& graph, + NodeMap& compMap, int &compNum) + : _graph(graph), _compMap(compMap), _compNum(compNum), + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {} + + void start(const Node& node) { + _predMap.set(node, INVALID); + } + + void reach(const Node& node) { + _numMap.set(node, _num); + _retMap.set(node, _num); + _nodeStack.push(node); + ++_num; + } + + void leave(const Node& node) { + if (_numMap[node] <= _retMap[node]) { + while (_nodeStack.top() != node) { + _compMap.set(_nodeStack.top(), _compNum); + _nodeStack.pop(); + } + _compMap.set(node, _compNum); + _nodeStack.pop(); + ++_compNum; + } + } + + void discover(const Arc& edge) { + _predMap.set(_graph.target(edge), edge); + } + + void examine(const Arc& edge) { + if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) { + return; + } + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + } + + void backtrack(const Arc& edge) { + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + } + + private: + const Digraph& _graph; + NodeMap& _compMap; + int& _compNum; + + typename Digraph::template NodeMap _numMap; + typename Digraph::template NodeMap _retMap; + typename Digraph::template NodeMap _predMap; + std::stack _nodeStack; + int _num; + }; + + + template + class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Edge Edge; + + BiEdgeConnectedCutEdgesVisitor(const Digraph& graph, + ArcMap& cutMap, int &cutNum) + : _graph(graph), _cutMap(cutMap), _cutNum(cutNum), + _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {} + + void start(const Node& node) { + _predMap[node] = INVALID; + } + + void reach(const Node& node) { + _numMap.set(node, _num); + _retMap.set(node, _num); + ++_num; + } + + void leave(const Node& node) { + if (_numMap[node] <= _retMap[node]) { + if (_predMap[node] != INVALID) { + _cutMap.set(_predMap[node], true); + ++_cutNum; + } + } + } + + void discover(const Arc& edge) { + _predMap.set(_graph.target(edge), edge); + } + + void examine(const Arc& edge) { + if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) { + return; + } + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + } + + void backtrack(const Arc& edge) { + if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) { + _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]); + } + } + + private: + const Digraph& _graph; + ArcMap& _cutMap; + int& _cutNum; + + typename Digraph::template NodeMap _numMap; + typename Digraph::template NodeMap _retMap; + typename Digraph::template NodeMap _predMap; + int _num; + }; + } + + template + int countBiEdgeConnectedComponents(const Graph& graph); + + /// \ingroup graph_properties + /// + /// \brief Check whether an undirected graph is bi-edge-connected. + /// + /// This function checks whether the given undirected graph is + /// bi-edge-connected, i.e. any two nodes are connected with at least + /// two edge-disjoint paths. + /// + /// \return \c true if the graph is bi-edge-connected. + /// \note By definition, the empty graph is bi-edge-connected. + /// + /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents() + template + bool biEdgeConnected(const Graph& graph) { + return countBiEdgeConnectedComponents(graph) <= 1; + } + + /// \ingroup graph_properties + /// + /// \brief Count the number of bi-edge-connected components of an + /// undirected graph. + /// + /// This function counts the number of bi-edge-connected components of + /// the given undirected graph. + /// + /// The bi-edge-connected components are the classes of an equivalence + /// relation on the nodes of an undirected graph. Two nodes are in the + /// same class if they are connected with at least two edge-disjoint + /// paths. + /// + /// \return The number of bi-edge-connected components. + /// + /// \see biEdgeConnected(), biEdgeConnectedComponents() + template + int countBiEdgeConnectedComponents(const Graph& graph) { + checkConcept(); + typedef typename Graph::NodeIt NodeIt; + + using namespace _connectivity_bits; + + typedef CountBiEdgeConnectedComponentsVisitor Visitor; + + int compNum = 0; + Visitor visitor(graph, compNum); + + DfsVisit dfs(graph, visitor); + dfs.init(); + + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + return compNum; + } + + /// \ingroup graph_properties + /// + /// \brief Find the bi-edge-connected components of an undirected graph. + /// + /// This function finds the bi-edge-connected components of the given + /// undirected graph. + /// + /// The bi-edge-connected components are the classes of an equivalence + /// relation on the nodes of an undirected graph. Two nodes are in the + /// same class if they are connected with at least two edge-disjoint + /// paths. + /// + /// \image html edge_biconnected_components.png + /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth + /// + /// \param graph The undirected graph. + /// \retval compMap A writable node map. The values will be set from 0 to + /// the number of the bi-edge-connected components minus one. Each value + /// of the map will be set exactly once, and the values of a certain + /// component will be set continuously. + /// \return The number of bi-edge-connected components. + /// + /// \see biEdgeConnected(), countBiEdgeConnectedComponents() + template + int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) { + checkConcept(); + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Node Node; + checkConcept, NodeMap>(); + + using namespace _connectivity_bits; + + typedef BiEdgeConnectedComponentsVisitor Visitor; + + int compNum = 0; + Visitor visitor(graph, compMap, compNum); + + DfsVisit dfs(graph, visitor); + dfs.init(); + + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + return compNum; + } + + /// \ingroup graph_properties + /// + /// \brief Find the bi-edge-connected cut edges in an undirected graph. + /// + /// This function finds the bi-edge-connected cut edges in the given + /// undirected graph. + /// + /// The bi-edge-connected components are the classes of an equivalence + /// relation on the nodes of an undirected graph. Two nodes are in the + /// same class if they are connected with at least two edge-disjoint + /// paths. + /// The bi-edge-connected components are separted by the cut edges of + /// the components. + /// + /// \param graph The undirected graph. + /// \retval cutMap A writable edge map. The values will be set to \c true + /// for the cut edges (exactly once for each cut edge), and will not be + /// changed for other edges. + /// \return The number of cut edges. + /// + /// \see biEdgeConnected(), biEdgeConnectedComponents() + template + int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) { + checkConcept(); + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Edge Edge; + checkConcept, EdgeMap>(); + + using namespace _connectivity_bits; + + typedef BiEdgeConnectedCutEdgesVisitor Visitor; + + int cutNum = 0; + Visitor visitor(graph, cutMap, cutNum); + + DfsVisit dfs(graph, visitor); + dfs.init(); + + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + return cutNum; + } + + + namespace _connectivity_bits { + + template + class TopologicalSortVisitor : public DfsVisitor { + public: + typedef typename Digraph::Node Node; + typedef typename Digraph::Arc edge; + + TopologicalSortVisitor(IntNodeMap& order, int num) + : _order(order), _num(num) {} + + void leave(const Node& node) { + _order.set(node, --_num); + } + + private: + IntNodeMap& _order; + int _num; + }; + + } + + /// \ingroup graph_properties + /// + /// \brief Check whether a digraph is DAG. + /// + /// This function checks whether the given digraph is DAG, i.e. + /// \e Directed \e Acyclic \e Graph. + /// \return \c true if there is no directed cycle in the digraph. + /// \see acyclic() + template + bool dag(const Digraph& digraph) { + + checkConcept(); + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + + typedef typename Digraph::template NodeMap ProcessedMap; + + typename Dfs::template SetProcessedMap:: + Create dfs(digraph); + + ProcessedMap processed(digraph); + dfs.processedMap(processed); + + dfs.init(); + for (NodeIt it(digraph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + while (!dfs.emptyQueue()) { + Arc arc = dfs.nextArc(); + Node target = digraph.target(arc); + if (dfs.reached(target) && !processed[target]) { + return false; + } + dfs.processNextArc(); + } + } + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Sort the nodes of a DAG into topolgical order. + /// + /// This function sorts the nodes of the given acyclic digraph (DAG) + /// into topolgical order. + /// + /// \param digraph The digraph, which must be DAG. + /// \retval order A writable node map. The values will be set from 0 to + /// the number of the nodes in the digraph minus one. Each value of the + /// map will be set exactly once, and the values will be set descending + /// order. + /// + /// \see dag(), checkedTopologicalSort() + template + void topologicalSort(const Digraph& digraph, NodeMap& order) { + using namespace _connectivity_bits; + + checkConcept(); + checkConcept, NodeMap>(); + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + + TopologicalSortVisitor + visitor(order, countNodes(digraph)); + + DfsVisit > + dfs(digraph, visitor); + + dfs.init(); + for (NodeIt it(digraph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + dfs.start(); + } + } + } + + /// \ingroup graph_properties + /// + /// \brief Sort the nodes of a DAG into topolgical order. + /// + /// This function sorts the nodes of the given acyclic digraph (DAG) + /// into topolgical order and also checks whether the given digraph + /// is DAG. + /// + /// \param digraph The digraph. + /// \retval order A readable and writable node map. The values will be + /// set from 0 to the number of the nodes in the digraph minus one. + /// Each value of the map will be set exactly once, and the values will + /// be set descending order. + /// \return \c false if the digraph is not DAG. + /// + /// \see dag(), topologicalSort() + template + bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) { + using namespace _connectivity_bits; + + checkConcept(); + checkConcept, + NodeMap>(); + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + + for (NodeIt it(digraph); it != INVALID; ++it) { + order.set(it, -1); + } + + TopologicalSortVisitor + visitor(order, countNodes(digraph)); + + DfsVisit > + dfs(digraph, visitor); + + dfs.init(); + for (NodeIt it(digraph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + while (!dfs.emptyQueue()) { + Arc arc = dfs.nextArc(); + Node target = digraph.target(arc); + if (dfs.reached(target) && order[target] == -1) { + return false; + } + dfs.processNextArc(); + } + } + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Check whether an undirected graph is acyclic. + /// + /// This function checks whether the given undirected graph is acyclic. + /// \return \c true if there is no cycle in the graph. + /// \see dag() + template + bool acyclic(const Graph& graph) { + checkConcept(); + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Arc Arc; + Dfs dfs(graph); + dfs.init(); + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + dfs.addSource(it); + while (!dfs.emptyQueue()) { + Arc arc = dfs.nextArc(); + Node source = graph.source(arc); + Node target = graph.target(arc); + if (dfs.reached(target) && + dfs.predArc(source) != graph.oppositeArc(arc)) { + return false; + } + dfs.processNextArc(); + } + } + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Check whether an undirected graph is tree. + /// + /// This function checks whether the given undirected graph is tree. + /// \return \c true if the graph is acyclic and connected. + /// \see acyclic(), connected() + template + bool tree(const Graph& graph) { + checkConcept(); + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Arc Arc; + if (NodeIt(graph) == INVALID) return true; + Dfs dfs(graph); + dfs.init(); + dfs.addSource(NodeIt(graph)); + while (!dfs.emptyQueue()) { + Arc arc = dfs.nextArc(); + Node source = graph.source(arc); + Node target = graph.target(arc); + if (dfs.reached(target) && + dfs.predArc(source) != graph.oppositeArc(arc)) { + return false; + } + dfs.processNextArc(); + } + for (NodeIt it(graph); it != INVALID; ++it) { + if (!dfs.reached(it)) { + return false; + } + } + return true; + } + + namespace _connectivity_bits { + + template + class BipartiteVisitor : public BfsVisitor { + public: + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Node Node; + + BipartiteVisitor(const Digraph& graph, bool& bipartite) + : _graph(graph), _part(graph), _bipartite(bipartite) {} + + void start(const Node& node) { + _part[node] = true; + } + void discover(const Arc& edge) { + _part.set(_graph.target(edge), !_part[_graph.source(edge)]); + } + void examine(const Arc& edge) { + _bipartite = _bipartite && + _part[_graph.target(edge)] != _part[_graph.source(edge)]; + } + + private: + + const Digraph& _graph; + typename Digraph::template NodeMap _part; + bool& _bipartite; + }; + + template + class BipartitePartitionsVisitor : public BfsVisitor { + public: + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Node Node; + + BipartitePartitionsVisitor(const Digraph& graph, + PartMap& part, bool& bipartite) + : _graph(graph), _part(part), _bipartite(bipartite) {} + + void start(const Node& node) { + _part.set(node, true); + } + void discover(const Arc& edge) { + _part.set(_graph.target(edge), !_part[_graph.source(edge)]); + } + void examine(const Arc& edge) { + _bipartite = _bipartite && + _part[_graph.target(edge)] != _part[_graph.source(edge)]; + } + + private: + + const Digraph& _graph; + PartMap& _part; + bool& _bipartite; + }; + } + + /// \ingroup graph_properties + /// + /// \brief Check whether an undirected graph is bipartite. + /// + /// The function checks whether the given undirected graph is bipartite. + /// \return \c true if the graph is bipartite. + /// + /// \see bipartitePartitions() + template + bool bipartite(const Graph &graph){ + using namespace _connectivity_bits; + + checkConcept(); + + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::ArcIt ArcIt; + + bool bipartite = true; + + BipartiteVisitor + visitor(graph, bipartite); + BfsVisit > + bfs(graph, visitor); + bfs.init(); + for(NodeIt it(graph); it != INVALID; ++it) { + if(!bfs.reached(it)){ + bfs.addSource(it); + while (!bfs.emptyQueue()) { + bfs.processNextNode(); + if (!bipartite) return false; + } + } + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Find the bipartite partitions of an undirected graph. + /// + /// This function checks whether the given undirected graph is bipartite + /// and gives back the bipartite partitions. + /// + /// \image html bipartite_partitions.png + /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth + /// + /// \param graph The undirected graph. + /// \retval partMap A writable node map of \c bool (or convertible) value + /// type. The values will be set to \c true for one component and + /// \c false for the other one. + /// \return \c true if the graph is bipartite, \c false otherwise. + /// + /// \see bipartite() + template + bool bipartitePartitions(const Graph &graph, NodeMap &partMap){ + using namespace _connectivity_bits; + + checkConcept(); + checkConcept, NodeMap>(); + + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::ArcIt ArcIt; + + bool bipartite = true; + + BipartitePartitionsVisitor + visitor(graph, partMap, bipartite); + BfsVisit > + bfs(graph, visitor); + bfs.init(); + for(NodeIt it(graph); it != INVALID; ++it) { + if(!bfs.reached(it)){ + bfs.addSource(it); + while (!bfs.emptyQueue()) { + bfs.processNextNode(); + if (!bipartite) return false; + } + } + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Check whether the given graph contains no loop arcs/edges. + /// + /// This function returns \c true if there are no loop arcs/edges in + /// the given graph. It works for both directed and undirected graphs. + template + bool loopFree(const Graph& graph) { + for (typename Graph::ArcIt it(graph); it != INVALID; ++it) { + if (graph.source(it) == graph.target(it)) return false; + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Check whether the given graph contains no parallel arcs/edges. + /// + /// This function returns \c true if there are no parallel arcs/edges in + /// the given graph. It works for both directed and undirected graphs. + template + bool parallelFree(const Graph& graph) { + typename Graph::template NodeMap reached(graph, 0); + int cnt = 1; + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) { + for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) { + if (reached[graph.target(a)] == cnt) return false; + reached[graph.target(a)] = cnt; + } + ++cnt; + } + return true; + } + + /// \ingroup graph_properties + /// + /// \brief Check whether the given graph is simple. + /// + /// This function returns \c true if the given graph is simple, i.e. + /// it contains no loop arcs/edges and no parallel arcs/edges. + /// The function works for both directed and undirected graphs. + /// \see loopFree(), parallelFree() + template + bool simpleGraph(const Graph& graph) { + typename Graph::template NodeMap reached(graph, 0); + int cnt = 1; + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) { + reached[n] = cnt; + for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) { + if (reached[graph.target(a)] == cnt) return false; + reached[graph.target(a)] = cnt; + } + ++cnt; + } + return true; + } + +} //namespace lemon + +#endif //LEMON_CONNECTIVITY_H diff --git a/lemon/lemon/core.h b/lemon/lemon/core.h new file mode 100644 index 0000000..30c3b4e --- /dev/null +++ b/lemon/lemon/core.h @@ -0,0 +1,1868 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CORE_H +#define LEMON_CORE_H + +#include +#include + +#include +#include +#include +#include + +// Disable the following warnings when compiling with MSVC: +// C4250: 'class1' : inherits 'class2::member' via dominance +// C4355: 'this' : used in base member initializer list +// C4503: 'function' : decorated name length exceeded, name was truncated +// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning) +// C4996: 'function': was declared deprecated +#ifdef _MSC_VER +#pragma warning( disable : 4250 4355 4503 4800 4996 ) +#endif + +///\file +///\brief LEMON core utilities. +/// +///This header file contains core utilities for LEMON. +///It is automatically included by all graph types, therefore it usually +///do not have to be included directly. + +namespace lemon { + + /// \brief Dummy type to make it easier to create invalid iterators. + /// + /// Dummy type to make it easier to create invalid iterators. + /// See \ref INVALID for the usage. + struct Invalid { + public: + bool operator==(Invalid) { return true; } + bool operator!=(Invalid) { return false; } + bool operator< (Invalid) { return false; } + }; + + /// \brief Invalid iterators. + /// + /// \ref Invalid is a global type that converts to each iterator + /// in such a way that the value of the target iterator will be invalid. +#ifdef LEMON_ONLY_TEMPLATES + const Invalid INVALID = Invalid(); +#else + extern const Invalid INVALID; +#endif + + /// \addtogroup gutils + /// @{ + + ///Create convenience typedefs for the digraph types and iterators + + ///This \c \#define creates convenient type definitions for the following + ///types of \c Digraph: \c Node, \c NodeIt, \c Arc, \c ArcIt, \c InArcIt, + ///\c OutArcIt, \c BoolNodeMap, \c IntNodeMap, \c DoubleNodeMap, + ///\c BoolArcMap, \c IntArcMap, \c DoubleArcMap. + /// + ///\note If the graph type is a dependent type, ie. the graph type depend + ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS() + ///macro. +#define DIGRAPH_TYPEDEFS(Digraph) \ + typedef Digraph::Node Node; \ + typedef Digraph::NodeIt NodeIt; \ + typedef Digraph::Arc Arc; \ + typedef Digraph::ArcIt ArcIt; \ + typedef Digraph::InArcIt InArcIt; \ + typedef Digraph::OutArcIt OutArcIt; \ + typedef Digraph::NodeMap BoolNodeMap; \ + typedef Digraph::NodeMap IntNodeMap; \ + typedef Digraph::NodeMap DoubleNodeMap; \ + typedef Digraph::ArcMap BoolArcMap; \ + typedef Digraph::ArcMap IntArcMap; \ + typedef Digraph::ArcMap DoubleArcMap + + ///Create convenience typedefs for the digraph types and iterators + + ///\see DIGRAPH_TYPEDEFS + /// + ///\note Use this macro, if the graph type is a dependent type, + ///ie. the graph type depend on a template parameter. +#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph) \ + typedef typename Digraph::Node Node; \ + typedef typename Digraph::NodeIt NodeIt; \ + typedef typename Digraph::Arc Arc; \ + typedef typename Digraph::ArcIt ArcIt; \ + typedef typename Digraph::InArcIt InArcIt; \ + typedef typename Digraph::OutArcIt OutArcIt; \ + typedef typename Digraph::template NodeMap BoolNodeMap; \ + typedef typename Digraph::template NodeMap IntNodeMap; \ + typedef typename Digraph::template NodeMap DoubleNodeMap; \ + typedef typename Digraph::template ArcMap BoolArcMap; \ + typedef typename Digraph::template ArcMap IntArcMap; \ + typedef typename Digraph::template ArcMap DoubleArcMap + + ///Create convenience typedefs for the graph types and iterators + + ///This \c \#define creates the same convenient type definitions as defined + ///by \ref DIGRAPH_TYPEDEFS(Graph) and six more, namely it creates + ///\c Edge, \c EdgeIt, \c IncEdgeIt, \c BoolEdgeMap, \c IntEdgeMap, + ///\c DoubleEdgeMap. + /// + ///\note If the graph type is a dependent type, ie. the graph type depend + ///on a template parameter, then use \c TEMPLATE_GRAPH_TYPEDEFS() + ///macro. +#define GRAPH_TYPEDEFS(Graph) \ + DIGRAPH_TYPEDEFS(Graph); \ + typedef Graph::Edge Edge; \ + typedef Graph::EdgeIt EdgeIt; \ + typedef Graph::IncEdgeIt IncEdgeIt; \ + typedef Graph::EdgeMap BoolEdgeMap; \ + typedef Graph::EdgeMap IntEdgeMap; \ + typedef Graph::EdgeMap DoubleEdgeMap + + ///Create convenience typedefs for the graph types and iterators + + ///\see GRAPH_TYPEDEFS + /// + ///\note Use this macro, if the graph type is a dependent type, + ///ie. the graph type depend on a template parameter. +#define TEMPLATE_GRAPH_TYPEDEFS(Graph) \ + TEMPLATE_DIGRAPH_TYPEDEFS(Graph); \ + typedef typename Graph::Edge Edge; \ + typedef typename Graph::EdgeIt EdgeIt; \ + typedef typename Graph::IncEdgeIt IncEdgeIt; \ + typedef typename Graph::template EdgeMap BoolEdgeMap; \ + typedef typename Graph::template EdgeMap IntEdgeMap; \ + typedef typename Graph::template EdgeMap DoubleEdgeMap + + /// \brief Function to count the items in a graph. + /// + /// This function counts the items (nodes, arcs etc.) in a graph. + /// The complexity of the function is linear because + /// it iterates on all of the items. + template + inline int countItems(const Graph& g) { + typedef typename ItemSetTraits::ItemIt ItemIt; + int num = 0; + for (ItemIt it(g); it != INVALID; ++it) { + ++num; + } + return num; + } + + // Node counting: + + namespace _core_bits { + + template + struct CountNodesSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; + + template + struct CountNodesSelector< + Graph, typename + enable_if::type> + { + static int count(const Graph &g) { + return g.nodeNum(); + } + }; + } + + /// \brief Function to count the nodes in the graph. + /// + /// This function counts the nodes in the graph. + /// The complexity of the function is O(n), but for some + /// graph structures it is specialized to run in O(1). + /// + /// \note If the graph contains a \c nodeNum() member function and a + /// \c NodeNumTag tag then this function calls directly the member + /// function to query the cardinality of the node set. + template + inline int countNodes(const Graph& g) { + return _core_bits::CountNodesSelector::count(g); + } + + // Arc counting: + + namespace _core_bits { + + template + struct CountArcsSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; + + template + struct CountArcsSelector< + Graph, + typename enable_if::type> + { + static int count(const Graph &g) { + return g.arcNum(); + } + }; + } + + /// \brief Function to count the arcs in the graph. + /// + /// This function counts the arcs in the graph. + /// The complexity of the function is O(m), but for some + /// graph structures it is specialized to run in O(1). + /// + /// \note If the graph contains a \c arcNum() member function and a + /// \c ArcNumTag tag then this function calls directly the member + /// function to query the cardinality of the arc set. + template + inline int countArcs(const Graph& g) { + return _core_bits::CountArcsSelector::count(g); + } + + // Edge counting: + + namespace _core_bits { + + template + struct CountEdgesSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; + + template + struct CountEdgesSelector< + Graph, + typename enable_if::type> + { + static int count(const Graph &g) { + return g.edgeNum(); + } + }; + } + + /// \brief Function to count the edges in the graph. + /// + /// This function counts the edges in the graph. + /// The complexity of the function is O(m), but for some + /// graph structures it is specialized to run in O(1). + /// + /// \note If the graph contains a \c edgeNum() member function and a + /// \c EdgeNumTag tag then this function calls directly the member + /// function to query the cardinality of the edge set. + template + inline int countEdges(const Graph& g) { + return _core_bits::CountEdgesSelector::count(g); + + } + + + template + inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) { + int num = 0; + for (DegIt it(_g, _n); it != INVALID; ++it) { + ++num; + } + return num; + } + + /// \brief Function to count the number of the out-arcs from node \c n. + /// + /// This function counts the number of the out-arcs from node \c n + /// in the graph \c g. + template + inline int countOutArcs(const Graph& g, const typename Graph::Node& n) { + return countNodeDegree(g, n); + } + + /// \brief Function to count the number of the in-arcs to node \c n. + /// + /// This function counts the number of the in-arcs to node \c n + /// in the graph \c g. + template + inline int countInArcs(const Graph& g, const typename Graph::Node& n) { + return countNodeDegree(g, n); + } + + /// \brief Function to count the number of the inc-edges to node \c n. + /// + /// This function counts the number of the inc-edges to node \c n + /// in the undirected graph \c g. + template + inline int countIncEdges(const Graph& g, const typename Graph::Node& n) { + return countNodeDegree(g, n); + } + + namespace _core_bits { + + template + class MapCopyBase { + public: + virtual void copy(const Digraph& from, const RefMap& refMap) = 0; + + virtual ~MapCopyBase() {} + }; + + template + class MapCopy : public MapCopyBase { + public: + + MapCopy(const FromMap& map, ToMap& tmap) + : _map(map), _tmap(tmap) {} + + virtual void copy(const Digraph& digraph, const RefMap& refMap) { + typedef typename ItemSetTraits::ItemIt ItemIt; + for (ItemIt it(digraph); it != INVALID; ++it) { + _tmap.set(refMap[it], _map[it]); + } + } + + private: + const FromMap& _map; + ToMap& _tmap; + }; + + template + class ItemCopy : public MapCopyBase { + public: + + ItemCopy(const Item& item, It& it) : _item(item), _it(it) {} + + virtual void copy(const Digraph&, const RefMap& refMap) { + _it = refMap[_item]; + } + + private: + Item _item; + It& _it; + }; + + template + class RefCopy : public MapCopyBase { + public: + + RefCopy(Ref& map) : _map(map) {} + + virtual void copy(const Digraph& digraph, const RefMap& refMap) { + typedef typename ItemSetTraits::ItemIt ItemIt; + for (ItemIt it(digraph); it != INVALID; ++it) { + _map.set(it, refMap[it]); + } + } + + private: + Ref& _map; + }; + + template + class CrossRefCopy : public MapCopyBase { + public: + + CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {} + + virtual void copy(const Digraph& digraph, const RefMap& refMap) { + typedef typename ItemSetTraits::ItemIt ItemIt; + for (ItemIt it(digraph); it != INVALID; ++it) { + _cmap.set(refMap[it], it); + } + } + + private: + CrossRef& _cmap; + }; + + template + struct DigraphCopySelector { + template + static void copy(const From& from, Digraph &to, + NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) { + to.clear(); + for (typename From::NodeIt it(from); it != INVALID; ++it) { + nodeRefMap[it] = to.addNode(); + } + for (typename From::ArcIt it(from); it != INVALID; ++it) { + arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)], + nodeRefMap[from.target(it)]); + } + } + }; + + template + struct DigraphCopySelector< + Digraph, + typename enable_if::type> + { + template + static void copy(const From& from, Digraph &to, + NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) { + to.build(from, nodeRefMap, arcRefMap); + } + }; + + template + struct GraphCopySelector { + template + static void copy(const From& from, Graph &to, + NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { + to.clear(); + for (typename From::NodeIt it(from); it != INVALID; ++it) { + nodeRefMap[it] = to.addNode(); + } + for (typename From::EdgeIt it(from); it != INVALID; ++it) { + edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)], + nodeRefMap[from.v(it)]); + } + } + }; + + template + struct GraphCopySelector< + Graph, + typename enable_if::type> + { + template + static void copy(const From& from, Graph &to, + NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { + to.build(from, nodeRefMap, edgeRefMap); + } + }; + + } + + /// \brief Class to copy a digraph. + /// + /// Class to copy a digraph to another digraph (duplicate a digraph). The + /// simplest way of using it is through the \c digraphCopy() function. + /// + /// This class not only make a copy of a digraph, but it can create + /// references and cross references between the nodes and arcs of + /// the two digraphs, and it can copy maps to use with the newly created + /// digraph. + /// + /// To make a copy from a digraph, first an instance of DigraphCopy + /// should be created, then the data belongs to the digraph should + /// assigned to copy. In the end, the \c run() member should be + /// called. + /// + /// The next code copies a digraph with several data: + ///\code + /// DigraphCopy cg(orig_graph, new_graph); + /// // Create references for the nodes + /// OrigGraph::NodeMap nr(orig_graph); + /// cg.nodeRef(nr); + /// // Create cross references (inverse) for the arcs + /// NewGraph::ArcMap acr(new_graph); + /// cg.arcCrossRef(acr); + /// // Copy an arc map + /// OrigGraph::ArcMap oamap(orig_graph); + /// NewGraph::ArcMap namap(new_graph); + /// cg.arcMap(oamap, namap); + /// // Copy a node + /// OrigGraph::Node on; + /// NewGraph::Node nn; + /// cg.node(on, nn); + /// // Execute copying + /// cg.run(); + ///\endcode + template + class DigraphCopy { + private: + + typedef typename From::Node Node; + typedef typename From::NodeIt NodeIt; + typedef typename From::Arc Arc; + typedef typename From::ArcIt ArcIt; + + typedef typename To::Node TNode; + typedef typename To::Arc TArc; + + typedef typename From::template NodeMap NodeRefMap; + typedef typename From::template ArcMap ArcRefMap; + + public: + + /// \brief Constructor of DigraphCopy. + /// + /// Constructor of DigraphCopy for copying the content of the + /// \c from digraph into the \c to digraph. + DigraphCopy(const From& from, To& to) + : _from(from), _to(to) {} + + /// \brief Destructor of DigraphCopy + /// + /// Destructor of DigraphCopy. + ~DigraphCopy() { + for (int i = 0; i < int(_node_maps.size()); ++i) { + delete _node_maps[i]; + } + for (int i = 0; i < int(_arc_maps.size()); ++i) { + delete _arc_maps[i]; + } + + } + + /// \brief Copy the node references into the given map. + /// + /// This function copies the node references into the given map. + /// The parameter should be a map, whose key type is the Node type of + /// the source digraph, while the value type is the Node type of the + /// destination digraph. + template + DigraphCopy& nodeRef(NodeRef& map) { + _node_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the node cross references into the given map. + /// + /// This function copies the node cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Node type of the destination digraph, while the value type is + /// the Node type of the source digraph. + template + DigraphCopy& nodeCrossRef(NodeCrossRef& map) { + _node_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given node map. + /// + /// This function makes a copy of the given node map for the newly + /// created digraph. + /// The key type of the new map \c tmap should be the Node type of the + /// destination digraph, and the key type of the original map \c map + /// should be the Node type of the source digraph. + template + DigraphCopy& nodeMap(const FromMap& map, ToMap& tmap) { + _node_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given node. + /// + /// This function makes a copy of the given node. + DigraphCopy& node(const Node& node, TNode& tnode) { + _node_maps.push_back(new _core_bits::ItemCopy(node, tnode)); + return *this; + } + + /// \brief Copy the arc references into the given map. + /// + /// This function copies the arc references into the given map. + /// The parameter should be a map, whose key type is the Arc type of + /// the source digraph, while the value type is the Arc type of the + /// destination digraph. + template + DigraphCopy& arcRef(ArcRef& map) { + _arc_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the arc cross references into the given map. + /// + /// This function copies the arc cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Arc type of the destination digraph, while the value type is + /// the Arc type of the source digraph. + template + DigraphCopy& arcCrossRef(ArcCrossRef& map) { + _arc_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given arc map. + /// + /// This function makes a copy of the given arc map for the newly + /// created digraph. + /// The key type of the new map \c tmap should be the Arc type of the + /// destination digraph, and the key type of the original map \c map + /// should be the Arc type of the source digraph. + template + DigraphCopy& arcMap(const FromMap& map, ToMap& tmap) { + _arc_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given arc. + /// + /// This function makes a copy of the given arc. + DigraphCopy& arc(const Arc& arc, TArc& tarc) { + _arc_maps.push_back(new _core_bits::ItemCopy(arc, tarc)); + return *this; + } + + /// \brief Execute copying. + /// + /// This function executes the copying of the digraph along with the + /// copying of the assigned data. + void run() { + NodeRefMap nodeRefMap(_from); + ArcRefMap arcRefMap(_from); + _core_bits::DigraphCopySelector:: + copy(_from, _to, nodeRefMap, arcRefMap); + for (int i = 0; i < int(_node_maps.size()); ++i) { + _node_maps[i]->copy(_from, nodeRefMap); + } + for (int i = 0; i < int(_arc_maps.size()); ++i) { + _arc_maps[i]->copy(_from, arcRefMap); + } + } + + protected: + + const From& _from; + To& _to; + + std::vector<_core_bits::MapCopyBase* > + _node_maps; + + std::vector<_core_bits::MapCopyBase* > + _arc_maps; + + }; + + /// \brief Copy a digraph to another digraph. + /// + /// This function copies a digraph to another digraph. + /// The complete usage of it is detailed in the DigraphCopy class, but + /// a short example shows a basic work: + ///\code + /// digraphCopy(src, trg).nodeRef(nr).arcCrossRef(acr).run(); + ///\endcode + /// + /// After the copy the \c nr map will contain the mapping from the + /// nodes of the \c from digraph to the nodes of the \c to digraph and + /// \c acr will contain the mapping from the arcs of the \c to digraph + /// to the arcs of the \c from digraph. + /// + /// \see DigraphCopy + template + DigraphCopy digraphCopy(const From& from, To& to) { + return DigraphCopy(from, to); + } + + /// \brief Class to copy a graph. + /// + /// Class to copy a graph to another graph (duplicate a graph). The + /// simplest way of using it is through the \c graphCopy() function. + /// + /// This class not only make a copy of a graph, but it can create + /// references and cross references between the nodes, edges and arcs of + /// the two graphs, and it can copy maps for using with the newly created + /// graph. + /// + /// To make a copy from a graph, first an instance of GraphCopy + /// should be created, then the data belongs to the graph should + /// assigned to copy. In the end, the \c run() member should be + /// called. + /// + /// The next code copies a graph with several data: + ///\code + /// GraphCopy cg(orig_graph, new_graph); + /// // Create references for the nodes + /// OrigGraph::NodeMap nr(orig_graph); + /// cg.nodeRef(nr); + /// // Create cross references (inverse) for the edges + /// NewGraph::EdgeMap ecr(new_graph); + /// cg.edgeCrossRef(ecr); + /// // Copy an edge map + /// OrigGraph::EdgeMap oemap(orig_graph); + /// NewGraph::EdgeMap nemap(new_graph); + /// cg.edgeMap(oemap, nemap); + /// // Copy a node + /// OrigGraph::Node on; + /// NewGraph::Node nn; + /// cg.node(on, nn); + /// // Execute copying + /// cg.run(); + ///\endcode + template + class GraphCopy { + private: + + typedef typename From::Node Node; + typedef typename From::NodeIt NodeIt; + typedef typename From::Arc Arc; + typedef typename From::ArcIt ArcIt; + typedef typename From::Edge Edge; + typedef typename From::EdgeIt EdgeIt; + + typedef typename To::Node TNode; + typedef typename To::Arc TArc; + typedef typename To::Edge TEdge; + + typedef typename From::template NodeMap NodeRefMap; + typedef typename From::template EdgeMap EdgeRefMap; + + struct ArcRefMap { + ArcRefMap(const From& from, const To& to, + const EdgeRefMap& edge_ref, const NodeRefMap& node_ref) + : _from(from), _to(to), + _edge_ref(edge_ref), _node_ref(node_ref) {} + + typedef typename From::Arc Key; + typedef typename To::Arc Value; + + Value operator[](const Key& key) const { + bool forward = _from.u(key) != _from.v(key) ? + _node_ref[_from.source(key)] == + _to.source(_to.direct(_edge_ref[key], true)) : + _from.direction(key); + return _to.direct(_edge_ref[key], forward); + } + + const From& _from; + const To& _to; + const EdgeRefMap& _edge_ref; + const NodeRefMap& _node_ref; + }; + + public: + + /// \brief Constructor of GraphCopy. + /// + /// Constructor of GraphCopy for copying the content of the + /// \c from graph into the \c to graph. + GraphCopy(const From& from, To& to) + : _from(from), _to(to) {} + + /// \brief Destructor of GraphCopy + /// + /// Destructor of GraphCopy. + ~GraphCopy() { + for (int i = 0; i < int(_node_maps.size()); ++i) { + delete _node_maps[i]; + } + for (int i = 0; i < int(_arc_maps.size()); ++i) { + delete _arc_maps[i]; + } + for (int i = 0; i < int(_edge_maps.size()); ++i) { + delete _edge_maps[i]; + } + } + + /// \brief Copy the node references into the given map. + /// + /// This function copies the node references into the given map. + /// The parameter should be a map, whose key type is the Node type of + /// the source graph, while the value type is the Node type of the + /// destination graph. + template + GraphCopy& nodeRef(NodeRef& map) { + _node_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the node cross references into the given map. + /// + /// This function copies the node cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Node type of the destination graph, while the value type is + /// the Node type of the source graph. + template + GraphCopy& nodeCrossRef(NodeCrossRef& map) { + _node_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given node map. + /// + /// This function makes a copy of the given node map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Node type of the + /// destination graph, and the key type of the original map \c map + /// should be the Node type of the source graph. + template + GraphCopy& nodeMap(const FromMap& map, ToMap& tmap) { + _node_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given node. + /// + /// This function makes a copy of the given node. + GraphCopy& node(const Node& node, TNode& tnode) { + _node_maps.push_back(new _core_bits::ItemCopy(node, tnode)); + return *this; + } + + /// \brief Copy the arc references into the given map. + /// + /// This function copies the arc references into the given map. + /// The parameter should be a map, whose key type is the Arc type of + /// the source graph, while the value type is the Arc type of the + /// destination graph. + template + GraphCopy& arcRef(ArcRef& map) { + _arc_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the arc cross references into the given map. + /// + /// This function copies the arc cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Arc type of the destination graph, while the value type is + /// the Arc type of the source graph. + template + GraphCopy& arcCrossRef(ArcCrossRef& map) { + _arc_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given arc map. + /// + /// This function makes a copy of the given arc map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Arc type of the + /// destination graph, and the key type of the original map \c map + /// should be the Arc type of the source graph. + template + GraphCopy& arcMap(const FromMap& map, ToMap& tmap) { + _arc_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given arc. + /// + /// This function makes a copy of the given arc. + GraphCopy& arc(const Arc& arc, TArc& tarc) { + _arc_maps.push_back(new _core_bits::ItemCopy(arc, tarc)); + return *this; + } + + /// \brief Copy the edge references into the given map. + /// + /// This function copies the edge references into the given map. + /// The parameter should be a map, whose key type is the Edge type of + /// the source graph, while the value type is the Edge type of the + /// destination graph. + template + GraphCopy& edgeRef(EdgeRef& map) { + _edge_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the edge cross references into the given map. + /// + /// This function copies the edge cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Edge type of the destination graph, while the value type is + /// the Edge type of the source graph. + template + GraphCopy& edgeCrossRef(EdgeCrossRef& map) { + _edge_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given edge map. + /// + /// This function makes a copy of the given edge map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Edge type of the + /// destination graph, and the key type of the original map \c map + /// should be the Edge type of the source graph. + template + GraphCopy& edgeMap(const FromMap& map, ToMap& tmap) { + _edge_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given edge. + /// + /// This function makes a copy of the given edge. + GraphCopy& edge(const Edge& edge, TEdge& tedge) { + _edge_maps.push_back(new _core_bits::ItemCopy(edge, tedge)); + return *this; + } + + /// \brief Execute copying. + /// + /// This function executes the copying of the graph along with the + /// copying of the assigned data. + void run() { + NodeRefMap nodeRefMap(_from); + EdgeRefMap edgeRefMap(_from); + ArcRefMap arcRefMap(_from, _to, edgeRefMap, nodeRefMap); + _core_bits::GraphCopySelector:: + copy(_from, _to, nodeRefMap, edgeRefMap); + for (int i = 0; i < int(_node_maps.size()); ++i) { + _node_maps[i]->copy(_from, nodeRefMap); + } + for (int i = 0; i < int(_edge_maps.size()); ++i) { + _edge_maps[i]->copy(_from, edgeRefMap); + } + for (int i = 0; i < int(_arc_maps.size()); ++i) { + _arc_maps[i]->copy(_from, arcRefMap); + } + } + + private: + + const From& _from; + To& _to; + + std::vector<_core_bits::MapCopyBase* > + _node_maps; + + std::vector<_core_bits::MapCopyBase* > + _arc_maps; + + std::vector<_core_bits::MapCopyBase* > + _edge_maps; + + }; + + /// \brief Copy a graph to another graph. + /// + /// This function copies a graph to another graph. + /// The complete usage of it is detailed in the GraphCopy class, + /// but a short example shows a basic work: + ///\code + /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run(); + ///\endcode + /// + /// After the copy the \c nr map will contain the mapping from the + /// nodes of the \c from graph to the nodes of the \c to graph and + /// \c ecr will contain the mapping from the edges of the \c to graph + /// to the edges of the \c from graph. + /// + /// \see GraphCopy + template + GraphCopy + graphCopy(const From& from, To& to) { + return GraphCopy(from, to); + } + + namespace _core_bits { + + template + struct FindArcSelector { + typedef typename Graph::Node Node; + typedef typename Graph::Arc Arc; + static Arc find(const Graph &g, Node u, Node v, Arc e) { + if (e == INVALID) { + g.firstOut(e, u); + } else { + g.nextOut(e); + } + while (e != INVALID && g.target(e) != v) { + g.nextOut(e); + } + return e; + } + }; + + template + struct FindArcSelector< + Graph, + typename enable_if::type> + { + typedef typename Graph::Node Node; + typedef typename Graph::Arc Arc; + static Arc find(const Graph &g, Node u, Node v, Arc prev) { + return g.findArc(u, v, prev); + } + }; + } + + /// \brief Find an arc between two nodes of a digraph. + /// + /// This function finds an arc from node \c u to node \c v in the + /// digraph \c g. + /// + /// If \c prev is \ref INVALID (this is the default value), then + /// it finds the first arc from \c u to \c v. Otherwise it looks for + /// the next arc from \c u to \c v after \c prev. + /// \return The found arc or \ref INVALID if there is no such an arc. + /// + /// Thus you can iterate through each arc from \c u to \c v as it follows. + ///\code + /// for(Arc e = findArc(g,u,v); e != INVALID; e = findArc(g,u,v,e)) { + /// ... + /// } + ///\endcode + /// + /// \note \ref ConArcIt provides iterator interface for the same + /// functionality. + /// + ///\sa ConArcIt + ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp + template + inline typename Graph::Arc + findArc(const Graph &g, typename Graph::Node u, typename Graph::Node v, + typename Graph::Arc prev = INVALID) { + return _core_bits::FindArcSelector::find(g, u, v, prev); + } + + /// \brief Iterator for iterating on parallel arcs connecting the same nodes. + /// + /// Iterator for iterating on parallel arcs connecting the same nodes. It is + /// a higher level interface for the \ref findArc() function. You can + /// use it the following way: + ///\code + /// for (ConArcIt it(g, src, trg); it != INVALID; ++it) { + /// ... + /// } + ///\endcode + /// + ///\sa findArc() + ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp + template + class ConArcIt : public GR::Arc { + typedef typename GR::Arc Parent; + + public: + + typedef typename GR::Arc Arc; + typedef typename GR::Node Node; + + /// \brief Constructor. + /// + /// Construct a new ConArcIt iterating on the arcs that + /// connects nodes \c u and \c v. + ConArcIt(const GR& g, Node u, Node v) : _graph(g) { + Parent::operator=(findArc(_graph, u, v)); + } + + /// \brief Constructor. + /// + /// Construct a new ConArcIt that continues the iterating from arc \c a. + ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {} + + /// \brief Increment operator. + /// + /// It increments the iterator and gives back the next arc. + ConArcIt& operator++() { + Parent::operator=(findArc(_graph, _graph.source(*this), + _graph.target(*this), *this)); + return *this; + } + private: + const GR& _graph; + }; + + namespace _core_bits { + + template + struct FindEdgeSelector { + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + static Edge find(const Graph &g, Node u, Node v, Edge e) { + bool b; + if (u != v) { + if (e == INVALID) { + g.firstInc(e, b, u); + } else { + b = g.u(e) == u; + g.nextInc(e, b); + } + while (e != INVALID && (b ? g.v(e) : g.u(e)) != v) { + g.nextInc(e, b); + } + } else { + if (e == INVALID) { + g.firstInc(e, b, u); + } else { + b = true; + g.nextInc(e, b); + } + while (e != INVALID && (!b || g.v(e) != v)) { + g.nextInc(e, b); + } + } + return e; + } + }; + + template + struct FindEdgeSelector< + Graph, + typename enable_if::type> + { + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + static Edge find(const Graph &g, Node u, Node v, Edge prev) { + return g.findEdge(u, v, prev); + } + }; + } + + /// \brief Find an edge between two nodes of a graph. + /// + /// This function finds an edge from node \c u to node \c v in graph \c g. + /// If node \c u and node \c v is equal then each loop edge + /// will be enumerated once. + /// + /// If \c prev is \ref INVALID (this is the default value), then + /// it finds the first edge from \c u to \c v. Otherwise it looks for + /// the next edge from \c u to \c v after \c prev. + /// \return The found edge or \ref INVALID if there is no such an edge. + /// + /// Thus you can iterate through each edge between \c u and \c v + /// as it follows. + ///\code + /// for(Edge e = findEdge(g,u,v); e != INVALID; e = findEdge(g,u,v,e)) { + /// ... + /// } + ///\endcode + /// + /// \note \ref ConEdgeIt provides iterator interface for the same + /// functionality. + /// + ///\sa ConEdgeIt + template + inline typename Graph::Edge + findEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v, + typename Graph::Edge p = INVALID) { + return _core_bits::FindEdgeSelector::find(g, u, v, p); + } + + /// \brief Iterator for iterating on parallel edges connecting the same nodes. + /// + /// Iterator for iterating on parallel edges connecting the same nodes. + /// It is a higher level interface for the findEdge() function. You can + /// use it the following way: + ///\code + /// for (ConEdgeIt it(g, u, v); it != INVALID; ++it) { + /// ... + /// } + ///\endcode + /// + ///\sa findEdge() + template + class ConEdgeIt : public GR::Edge { + typedef typename GR::Edge Parent; + + public: + + typedef typename GR::Edge Edge; + typedef typename GR::Node Node; + + /// \brief Constructor. + /// + /// Construct a new ConEdgeIt iterating on the edges that + /// connects nodes \c u and \c v. + ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) { + Parent::operator=(findEdge(_graph, _u, _v)); + } + + /// \brief Constructor. + /// + /// Construct a new ConEdgeIt that continues iterating from edge \c e. + ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {} + + /// \brief Increment operator. + /// + /// It increments the iterator and gives back the next edge. + ConEdgeIt& operator++() { + Parent::operator=(findEdge(_graph, _u, _v, *this)); + return *this; + } + private: + const GR& _graph; + Node _u, _v; + }; + + + ///Dynamic arc look-up between given endpoints. + + ///Using this class, you can find an arc in a digraph from a given + ///source to a given target in amortized time O(logd), + ///where d is the out-degree of the source node. + /// + ///It is possible to find \e all parallel arcs between two nodes with + ///the \c operator() member. + /// + ///This is a dynamic data structure. Consider to use \ref ArcLookUp or + ///\ref AllArcLookUp if your digraph is not changed so frequently. + /// + ///This class uses a self-adjusting binary search tree, the Splay tree + ///of Sleator and Tarjan to guarantee the logarithmic amortized + ///time bound for arc look-ups. This class also guarantees the + ///optimal time bound in a constant factor for any distribution of + ///queries. + /// + ///\tparam GR The type of the underlying digraph. + /// + ///\sa ArcLookUp + ///\sa AllArcLookUp + template + class DynArcLookUp + : protected ItemSetTraits::ItemNotifier::ObserverBase + { + typedef typename ItemSetTraits + ::ItemNotifier::ObserverBase Parent; + + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + public: + + /// The Digraph type + typedef GR Digraph; + + protected: + + class AutoNodeMap : public ItemSetTraits::template Map::Type + { + typedef typename ItemSetTraits::template Map::Type Parent; + + public: + + AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {} + + virtual void add(const Node& node) { + Parent::add(node); + Parent::set(node, INVALID); + } + + virtual void add(const std::vector& nodes) { + Parent::add(nodes); + for (int i = 0; i < int(nodes.size()); ++i) { + Parent::set(nodes[i], INVALID); + } + } + + virtual void build() { + Parent::build(); + Node it; + typename Parent::Notifier* nf = Parent::notifier(); + for (nf->first(it); it != INVALID; nf->next(it)) { + Parent::set(it, INVALID); + } + } + }; + + class ArcLess { + const Digraph &g; + public: + ArcLess(const Digraph &_g) : g(_g) {} + bool operator()(Arc a,Arc b) const + { + return g.target(a) _parent; + typename Digraph::template ArcMap _left; + typename Digraph::template ArcMap _right; + + public: + + ///Constructor + + ///Constructor. + /// + ///It builds up the search database. + DynArcLookUp(const Digraph &g) + : _g(g),_head(g),_parent(g),_left(g),_right(g) + { + Parent::attach(_g.notifier(typename Digraph::Arc())); + refresh(); + } + + protected: + + virtual void add(const Arc& arc) { + insert(arc); + } + + virtual void add(const std::vector& arcs) { + for (int i = 0; i < int(arcs.size()); ++i) { + insert(arcs[i]); + } + } + + virtual void erase(const Arc& arc) { + remove(arc); + } + + virtual void erase(const std::vector& arcs) { + for (int i = 0; i < int(arcs.size()); ++i) { + remove(arcs[i]); + } + } + + virtual void build() { + refresh(); + } + + virtual void clear() { + for(NodeIt n(_g);n!=INVALID;++n) { + _head[n] = INVALID; + } + } + + void insert(Arc arc) { + Node s = _g.source(arc); + Node t = _g.target(arc); + _left[arc] = INVALID; + _right[arc] = INVALID; + + Arc e = _head[s]; + if (e == INVALID) { + _head[s] = arc; + _parent[arc] = INVALID; + return; + } + while (true) { + if (t < _g.target(e)) { + if (_left[e] == INVALID) { + _left[e] = arc; + _parent[arc] = e; + splay(arc); + return; + } else { + e = _left[e]; + } + } else { + if (_right[e] == INVALID) { + _right[e] = arc; + _parent[arc] = e; + splay(arc); + return; + } else { + e = _right[e]; + } + } + } + } + + void remove(Arc arc) { + if (_left[arc] == INVALID) { + if (_right[arc] != INVALID) { + _parent[_right[arc]] = _parent[arc]; + } + if (_parent[arc] != INVALID) { + if (_left[_parent[arc]] == arc) { + _left[_parent[arc]] = _right[arc]; + } else { + _right[_parent[arc]] = _right[arc]; + } + } else { + _head[_g.source(arc)] = _right[arc]; + } + } else if (_right[arc] == INVALID) { + _parent[_left[arc]] = _parent[arc]; + if (_parent[arc] != INVALID) { + if (_left[_parent[arc]] == arc) { + _left[_parent[arc]] = _left[arc]; + } else { + _right[_parent[arc]] = _left[arc]; + } + } else { + _head[_g.source(arc)] = _left[arc]; + } + } else { + Arc e = _left[arc]; + if (_right[e] != INVALID) { + e = _right[e]; + while (_right[e] != INVALID) { + e = _right[e]; + } + Arc s = _parent[e]; + _right[_parent[e]] = _left[e]; + if (_left[e] != INVALID) { + _parent[_left[e]] = _parent[e]; + } + + _left[e] = _left[arc]; + _parent[_left[arc]] = e; + _right[e] = _right[arc]; + _parent[_right[arc]] = e; + + _parent[e] = _parent[arc]; + if (_parent[arc] != INVALID) { + if (_left[_parent[arc]] == arc) { + _left[_parent[arc]] = e; + } else { + _right[_parent[arc]] = e; + } + } + splay(s); + } else { + _right[e] = _right[arc]; + _parent[_right[arc]] = e; + _parent[e] = _parent[arc]; + + if (_parent[arc] != INVALID) { + if (_left[_parent[arc]] == arc) { + _left[_parent[arc]] = e; + } else { + _right[_parent[arc]] = e; + } + } else { + _head[_g.source(arc)] = e; + } + } + } + } + + Arc refreshRec(std::vector &v,int a,int b) + { + int m=(a+b)/2; + Arc me=v[m]; + if (a < m) { + Arc left = refreshRec(v,a,m-1); + _left[me] = left; + _parent[left] = me; + } else { + _left[me] = INVALID; + } + if (m < b) { + Arc right = refreshRec(v,m+1,b); + _right[me] = right; + _parent[right] = me; + } else { + _right[me] = INVALID; + } + return me; + } + + void refresh() { + for(NodeIt n(_g);n!=INVALID;++n) { + std::vector v; + for(OutArcIt a(_g,n);a!=INVALID;++a) v.push_back(a); + if (!v.empty()) { + std::sort(v.begin(),v.end(),ArcLess(_g)); + Arc head = refreshRec(v,0,v.size()-1); + _head[n] = head; + _parent[head] = INVALID; + } + else _head[n] = INVALID; + } + } + + void zig(Arc v) { + Arc w = _parent[v]; + _parent[v] = _parent[w]; + _parent[w] = v; + _left[w] = _right[v]; + _right[v] = w; + if (_parent[v] != INVALID) { + if (_right[_parent[v]] == w) { + _right[_parent[v]] = v; + } else { + _left[_parent[v]] = v; + } + } + if (_left[w] != INVALID){ + _parent[_left[w]] = w; + } + } + + void zag(Arc v) { + Arc w = _parent[v]; + _parent[v] = _parent[w]; + _parent[w] = v; + _right[w] = _left[v]; + _left[v] = w; + if (_parent[v] != INVALID){ + if (_left[_parent[v]] == w) { + _left[_parent[v]] = v; + } else { + _right[_parent[v]] = v; + } + } + if (_right[w] != INVALID){ + _parent[_right[w]] = w; + } + } + + void splay(Arc v) { + while (_parent[v] != INVALID) { + if (v == _left[_parent[v]]) { + if (_parent[_parent[v]] == INVALID) { + zig(v); + } else { + if (_parent[v] == _left[_parent[_parent[v]]]) { + zig(_parent[v]); + zig(v); + } else { + zig(v); + zag(v); + } + } + } else { + if (_parent[_parent[v]] == INVALID) { + zag(v); + } else { + if (_parent[v] == _left[_parent[_parent[v]]]) { + zag(v); + zig(v); + } else { + zag(_parent[v]); + zag(v); + } + } + } + } + _head[_g.source(v)] = v; + } + + + public: + + ///Find an arc between two nodes. + + ///Find an arc between two nodes. + ///\param s The source node. + ///\param t The target node. + ///\param p The previous arc between \c s and \c t. It it is INVALID or + ///not given, the operator finds the first appropriate arc. + ///\return An arc from \c s to \c t after \c p or + ///\ref INVALID if there is no more. + /// + ///For example, you can count the number of arcs from \c u to \c v in the + ///following way. + ///\code + ///DynArcLookUp ae(g); + ///... + ///int n = 0; + ///for(Arc a = ae(u,v); a != INVALID; a = ae(u,v,a)) n++; + ///\endcode + /// + ///Finding the arcs take at most O(logd) + ///amortized time, specifically, the time complexity of the lookups + ///is equal to the optimal search tree implementation for the + ///current query distribution in a constant factor. + /// + ///\note This is a dynamic data structure, therefore the data + ///structure is updated after each graph alteration. Thus although + ///this data structure is theoretically faster than \ref ArcLookUp + ///and \ref AllArcLookUp, it often provides worse performance than + ///them. + Arc operator()(Node s, Node t, Arc p = INVALID) const { + if (p == INVALID) { + Arc a = _head[s]; + if (a == INVALID) return INVALID; + Arc r = INVALID; + while (true) { + if (_g.target(a) < t) { + if (_right[a] == INVALID) { + const_cast(*this).splay(a); + return r; + } else { + a = _right[a]; + } + } else { + if (_g.target(a) == t) { + r = a; + } + if (_left[a] == INVALID) { + const_cast(*this).splay(a); + return r; + } else { + a = _left[a]; + } + } + } + } else { + Arc a = p; + if (_right[a] != INVALID) { + a = _right[a]; + while (_left[a] != INVALID) { + a = _left[a]; + } + const_cast(*this).splay(a); + } else { + while (_parent[a] != INVALID && _right[_parent[a]] == a) { + a = _parent[a]; + } + if (_parent[a] == INVALID) { + return INVALID; + } else { + a = _parent[a]; + const_cast(*this).splay(a); + } + } + if (_g.target(a) == t) return a; + else return INVALID; + } + } + + }; + + ///Fast arc look-up between given endpoints. + + ///Using this class, you can find an arc in a digraph from a given + ///source to a given target in time O(logd), + ///where d is the out-degree of the source node. + /// + ///It is not possible to find \e all parallel arcs between two nodes. + ///Use \ref AllArcLookUp for this purpose. + /// + ///\warning This class is static, so you should call refresh() (or at + ///least refresh(Node)) to refresh this data structure whenever the + ///digraph changes. This is a time consuming (superlinearly proportional + ///(O(m logm)) to the number of arcs). + /// + ///\tparam GR The type of the underlying digraph. + /// + ///\sa DynArcLookUp + ///\sa AllArcLookUp + template + class ArcLookUp + { + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + public: + + /// The Digraph type + typedef GR Digraph; + + protected: + const Digraph &_g; + typename Digraph::template NodeMap _head; + typename Digraph::template ArcMap _left; + typename Digraph::template ArcMap _right; + + class ArcLess { + const Digraph &g; + public: + ArcLess(const Digraph &_g) : g(_g) {} + bool operator()(Arc a,Arc b) const + { + return g.target(a) &v,int a,int b) + { + int m=(a+b)/2; + Arc me=v[m]; + _left[me] = aO(d logd), where d + ///is the number of the outgoing arcs of \c n. + void refresh(Node n) + { + std::vector v; + for(OutArcIt e(_g,n);e!=INVALID;++e) v.push_back(e); + if(v.size()) { + std::sort(v.begin(),v.end(),ArcLess(_g)); + _head[n]=refreshRec(v,0,v.size()-1); + } + else _head[n]=INVALID; + } + ///Refresh the full data structure. + + ///Build up the full search database. In fact, it simply calls + ///\ref refresh(Node) "refresh(n)" for each node \c n. + /// + ///It runs in time O(m logD), where m is + ///the number of the arcs in the digraph and D is the maximum + ///out-degree of the digraph. + void refresh() + { + for(NodeIt n(_g);n!=INVALID;++n) refresh(n); + } + + ///Find an arc between two nodes. + + ///Find an arc between two nodes in time O(logd), + ///where d is the number of outgoing arcs of \c s. + ///\param s The source node. + ///\param t The target node. + ///\return An arc from \c s to \c t if there exists, + ///\ref INVALID otherwise. + /// + ///\warning If you change the digraph, refresh() must be called before using + ///this operator. If you change the outgoing arcs of + ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough. + Arc operator()(Node s, Node t) const + { + Arc e; + for(e=_head[s]; + e!=INVALID&&_g.target(e)!=t; + e = t < _g.target(e)?_left[e]:_right[e]) ; + return e; + } + + }; + + ///Fast look-up of all arcs between given endpoints. + + ///This class is the same as \ref ArcLookUp, with the addition + ///that it makes it possible to find all parallel arcs between given + ///endpoints. + /// + ///\warning This class is static, so you should call refresh() (or at + ///least refresh(Node)) to refresh this data structure whenever the + ///digraph changes. This is a time consuming (superlinearly proportional + ///(O(m logm)) to the number of arcs). + /// + ///\tparam GR The type of the underlying digraph. + /// + ///\sa DynArcLookUp + ///\sa ArcLookUp + template + class AllArcLookUp : public ArcLookUp + { + using ArcLookUp::_g; + using ArcLookUp::_right; + using ArcLookUp::_left; + using ArcLookUp::_head; + + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + typename GR::template ArcMap _next; + + Arc refreshNext(Arc head,Arc next=INVALID) + { + if(head==INVALID) return next; + else { + next=refreshNext(_right[head],next); + _next[head]=( next!=INVALID && _g.target(next)==_g.target(head)) + ? next : INVALID; + return refreshNext(_left[head],head); + } + } + + void refreshNext() + { + for(NodeIt n(_g);n!=INVALID;++n) refreshNext(_head[n]); + } + + public: + + /// The Digraph type + typedef GR Digraph; + + ///Constructor + + ///Constructor. + /// + ///It builds up the search database, which remains valid until the digraph + ///changes. + AllArcLookUp(const Digraph &g) : ArcLookUp(g), _next(g) {refreshNext();} + + ///Refresh the data structure at a node. + + ///Build up the search database of node \c n. + /// + ///It runs in time O(d logd), where d is + ///the number of the outgoing arcs of \c n. + void refresh(Node n) + { + ArcLookUp::refresh(n); + refreshNext(_head[n]); + } + + ///Refresh the full data structure. + + ///Build up the full search database. In fact, it simply calls + ///\ref refresh(Node) "refresh(n)" for each node \c n. + /// + ///It runs in time O(m logD), where m is + ///the number of the arcs in the digraph and D is the maximum + ///out-degree of the digraph. + void refresh() + { + for(NodeIt n(_g);n!=INVALID;++n) refresh(_head[n]); + } + + ///Find an arc between two nodes. + + ///Find an arc between two nodes. + ///\param s The source node. + ///\param t The target node. + ///\param prev The previous arc between \c s and \c t. It it is INVALID or + ///not given, the operator finds the first appropriate arc. + ///\return An arc from \c s to \c t after \c prev or + ///\ref INVALID if there is no more. + /// + ///For example, you can count the number of arcs from \c u to \c v in the + ///following way. + ///\code + ///AllArcLookUp ae(g); + ///... + ///int n = 0; + ///for(Arc a = ae(u,v); a != INVALID; a=ae(u,v,a)) n++; + ///\endcode + /// + ///Finding the first arc take O(logd) time, + ///where d is the number of outgoing arcs of \c s. Then the + ///consecutive arcs are found in constant time. + /// + ///\warning If you change the digraph, refresh() must be called before using + ///this operator. If you change the outgoing arcs of + ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough. + /// +#ifdef DOXYGEN + Arc operator()(Node s, Node t, Arc prev=INVALID) const {} +#else + using ArcLookUp::operator() ; + Arc operator()(Node s, Node t, Arc prev) const + { + return prev==INVALID?(*this)(s,t):_next[prev]; + } +#endif + + }; + + /// @} + +} //namespace lemon + +#endif diff --git a/lemon/lemon/cost_scaling.h b/lemon/lemon/cost_scaling.h new file mode 100644 index 0000000..afd3dde --- /dev/null +++ b/lemon/lemon/cost_scaling.h @@ -0,0 +1,1316 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_COST_SCALING_H +#define LEMON_COST_SCALING_H + +/// \ingroup min_cost_flow_algs +/// \file +/// \brief Cost scaling algorithm for finding a minimum cost flow. + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \brief Default traits class of CostScaling algorithm. + /// + /// Default traits class of CostScaling algorithm. + /// \tparam GR Digraph type. + /// \tparam V The number type used for flow amounts, capacity bounds + /// and supply values. By default it is \c int. + /// \tparam C The number type used for costs and potentials. + /// By default it is the same as \c V. +#ifdef DOXYGEN + template +#else + template < typename GR, typename V = int, typename C = V, + bool integer = std::numeric_limits::is_integer > +#endif + struct CostScalingDefaultTraits + { + /// The type of the digraph + typedef GR Digraph; + /// The type of the flow amounts, capacity bounds and supply values + typedef V Value; + /// The type of the arc costs + typedef C Cost; + + /// \brief The large cost type used for internal computations + /// + /// The large cost type used for internal computations. + /// It is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + /// \c Cost must be convertible to \c LargeCost. + typedef double LargeCost; + }; + + // Default traits class for integer cost types + template + struct CostScalingDefaultTraits + { + typedef GR Digraph; + typedef V Value; + typedef C Cost; +#ifdef LEMON_HAVE_LONG_LONG + typedef long long LargeCost; +#else + typedef long LargeCost; +#endif + }; + + + /// \addtogroup min_cost_flow_algs + /// @{ + + /// \brief Implementation of the Cost Scaling algorithm for + /// finding a \ref min_cost_flow "minimum cost flow". + /// + /// \ref CostScaling implements a cost scaling algorithm that performs + /// push/augment and relabel operations for finding a \ref min_cost_flow + /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation, + /// \ref goldberg97efficient, \ref bunnagel98efficient. + /// It is a highly efficient primal-dual solution method, which + /// can be viewed as the generalization of the \ref Preflow + /// "preflow push-relabel" algorithm for the maximum flow problem. + /// + /// Most of the parameters of the problem (except for the digraph) + /// can be given using separate functions, and the algorithm can be + /// executed using the \ref run() function. If some parameters are not + /// specified, then default values will be used. + /// + /// \tparam GR The digraph type the algorithm runs on. + /// \tparam V The number type used for flow amounts, capacity bounds + /// and supply values in the algorithm. By default, it is \c int. + /// \tparam C The number type used for costs and potentials in the + /// algorithm. By default, it is the same as \c V. + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref CostScalingDefaultTraits + /// "CostScalingDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. + /// + /// \warning Both number types must be signed and all input data must + /// be integer. + /// \warning This algorithm does not support negative costs for such + /// arcs that have infinite upper bound. + /// + /// \note %CostScaling provides three different internal methods, + /// from which the most efficient one is used by default. + /// For more information, see \ref Method. +#ifdef DOXYGEN + template +#else + template < typename GR, typename V = int, typename C = V, + typename TR = CostScalingDefaultTraits > +#endif + class CostScaling + { + public: + + /// The type of the digraph + typedef typename TR::Digraph Digraph; + /// The type of the flow amounts, capacity bounds and supply values + typedef typename TR::Value Value; + /// The type of the arc costs + typedef typename TR::Cost Cost; + + /// \brief The large cost type + /// + /// The large cost type used for internal computations. + /// By default, it is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + typedef typename TR::LargeCost LargeCost; + + /// The \ref CostScalingDefaultTraits "traits class" of the algorithm + typedef TR Traits; + + public: + + /// \brief Problem type constants for the \c run() function. + /// + /// Enum type containing the problem type constants that can be + /// returned by the \ref run() function of the algorithm. + enum ProblemType { + /// The problem has no feasible solution (flow). + INFEASIBLE, + /// The problem has optimal solution (i.e. it is feasible and + /// bounded), and the algorithm has found optimal flow and node + /// potentials (primal and dual solutions). + OPTIMAL, + /// The digraph contains an arc of negative cost and infinite + /// upper bound. It means that the objective function is unbounded + /// on that arc, however, note that it could actually be bounded + /// over the feasible flows, but this algroithm cannot handle + /// these cases. + UNBOUNDED + }; + + /// \brief Constants for selecting the internal method. + /// + /// Enum type containing constants for selecting the internal method + /// for the \ref run() function. + /// + /// \ref CostScaling provides three internal methods that differ mainly + /// in their base operations, which are used in conjunction with the + /// relabel operation. + /// By default, the so called \ref PARTIAL_AUGMENT + /// "Partial Augment-Relabel" method is used, which proved to be + /// the most efficient and the most robust on various test inputs. + /// However, the other methods can be selected using the \ref run() + /// function with the proper parameter. + enum Method { + /// Local push operations are used, i.e. flow is moved only on one + /// admissible arc at once. + PUSH, + /// Augment operations are used, i.e. flow is moved on admissible + /// paths from a node with excess to a node with deficit. + AUGMENT, + /// Partial augment operations are used, i.e. flow is moved on + /// admissible paths started from a node with excess, but the + /// lengths of these paths are limited. This method can be viewed + /// as a combined version of the previous two operations. + PARTIAL_AUGMENT + }; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + typedef std::vector IntVector; + typedef std::vector ValueVector; + typedef std::vector CostVector; + typedef std::vector LargeCostVector; + typedef std::vector BoolVector; + // Note: vector is used instead of vector for efficiency reasons + + private: + + template + class StaticVectorMap { + public: + typedef KT Key; + typedef VT Value; + + StaticVectorMap(std::vector& v) : _v(v) {} + + const Value& operator[](const Key& key) const { + return _v[StaticDigraph::id(key)]; + } + + Value& operator[](const Key& key) { + return _v[StaticDigraph::id(key)]; + } + + void set(const Key& key, const Value& val) { + _v[StaticDigraph::id(key)] = val; + } + + private: + std::vector& _v; + }; + + typedef StaticVectorMap LargeCostNodeMap; + typedef StaticVectorMap LargeCostArcMap; + + private: + + // Data related to the underlying digraph + const GR &_graph; + int _node_num; + int _arc_num; + int _res_node_num; + int _res_arc_num; + int _root; + + // Parameters of the problem + bool _have_lower; + Value _sum_supply; + int _sup_node_num; + + // Data structures for storing the digraph + IntNodeMap _node_id; + IntArcMap _arc_idf; + IntArcMap _arc_idb; + IntVector _first_out; + BoolVector _forward; + IntVector _source; + IntVector _target; + IntVector _reverse; + + // Node and arc data + ValueVector _lower; + ValueVector _upper; + CostVector _scost; + ValueVector _supply; + + ValueVector _res_cap; + LargeCostVector _cost; + LargeCostVector _pi; + ValueVector _excess; + IntVector _next_out; + std::deque _active_nodes; + + // Data for scaling + LargeCost _epsilon; + int _alpha; + + IntVector _buckets; + IntVector _bucket_next; + IntVector _bucket_prev; + IntVector _rank; + int _max_rank; + + // Data for a StaticDigraph structure + typedef std::pair IntPair; + StaticDigraph _sgr; + std::vector _arc_vec; + std::vector _cost_vec; + LargeCostArcMap _cost_map; + LargeCostNodeMap _pi_map; + + public: + + /// \brief Constant for infinite upper bounds (capacities). + /// + /// Constant for infinite upper bounds (capacities). + /// It is \c std::numeric_limits::infinity() if available, + /// \c std::numeric_limits::max() otherwise. + const Value INF; + + public: + + /// \name Named Template Parameters + /// @{ + + template + struct SetLargeCostTraits : public Traits { + typedef T LargeCost; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c LargeCost type. + /// + /// \ref named-templ-param "Named parameter" for setting \c LargeCost + /// type, which is used for internal computations in the algorithm. + /// \c Cost must be convertible to \c LargeCost. + template + struct SetLargeCost + : public CostScaling > { + typedef CostScaling > Create; + }; + + /// @} + + protected: + + CostScaling() {} + + public: + + /// \brief Constructor. + /// + /// The constructor of the class. + /// + /// \param graph The digraph the algorithm runs on. + CostScaling(const GR& graph) : + _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph), + _cost_map(_cost_vec), _pi_map(_pi), + INF(std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max()) + { + // Check the number types + LEMON_ASSERT(std::numeric_limits::is_signed, + "The flow type of CostScaling must be signed"); + LEMON_ASSERT(std::numeric_limits::is_signed, + "The cost type of CostScaling must be signed"); + + // Reset data structures + reset(); + } + + /// \name Parameters + /// The parameters of the algorithm can be specified using these + /// functions. + + /// @{ + + /// \brief Set the lower bounds on the arcs. + /// + /// This function sets the lower bounds on the arcs. + /// If it is not used before calling \ref run(), the lower bounds + /// will be set to zero on all arcs. + /// + /// \param map An arc map storing the lower bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CostScaling& lowerMap(const LowerMap& map) { + _have_lower = true; + for (ArcIt a(_graph); a != INVALID; ++a) { + _lower[_arc_idf[a]] = map[a]; + _lower[_arc_idb[a]] = map[a]; + } + return *this; + } + + /// \brief Set the upper bounds (capacities) on the arcs. + /// + /// This function sets the upper bounds (capacities) on the arcs. + /// If it is not used before calling \ref run(), the upper bounds + /// will be set to \ref INF on all arcs (i.e. the flow value will be + /// unbounded from above). + /// + /// \param map An arc map storing the upper bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CostScaling& upperMap(const UpperMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _upper[_arc_idf[a]] = map[a]; + } + return *this; + } + + /// \brief Set the costs of the arcs. + /// + /// This function sets the costs of the arcs. + /// If it is not used before calling \ref run(), the costs + /// will be set to \c 1 on all arcs. + /// + /// \param map An arc map storing the costs. + /// Its \c Value type must be convertible to the \c Cost type + /// of the algorithm. + /// + /// \return (*this) + template + CostScaling& costMap(const CostMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _scost[_arc_idf[a]] = map[a]; + _scost[_arc_idb[a]] = -map[a]; + } + return *this; + } + + /// \brief Set the supply values of the nodes. + /// + /// This function sets the supply values of the nodes. + /// If neither this function nor \ref stSupply() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// \param map A node map storing the supply values. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CostScaling& supplyMap(const SupplyMap& map) { + for (NodeIt n(_graph); n != INVALID; ++n) { + _supply[_node_id[n]] = map[n]; + } + return *this; + } + + /// \brief Set single source and target nodes and a supply value. + /// + /// This function sets a single source node and a single target node + /// and the required flow value. + /// If neither this function nor \ref supplyMap() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// Using this function has the same effect as using \ref supplyMap() + /// with such a map in which \c k is assigned to \c s, \c -k is + /// assigned to \c t and all other nodes have zero supply value. + /// + /// \param s The source node. + /// \param t The target node. + /// \param k The required amount of flow from node \c s to node \c t + /// (i.e. the supply of \c s and the demand of \c t). + /// + /// \return (*this) + CostScaling& stSupply(const Node& s, const Node& t, Value k) { + for (int i = 0; i != _res_node_num; ++i) { + _supply[i] = 0; + } + _supply[_node_id[s]] = k; + _supply[_node_id[t]] = -k; + return *this; + } + + /// @} + + /// \name Execution control + /// The algorithm can be executed using \ref run(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// The paramters can be specified using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// For example, + /// \code + /// CostScaling cs(graph); + /// cs.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// This function can be called more than once. All the given parameters + /// are kept for the next call, unless \ref resetParams() or \ref reset() + /// is used, thus only the modified parameters have to be set again. + /// If the underlying digraph was also modified after the construction + /// of the class (or the last \ref reset() call), then the \ref reset() + /// function must be called. + /// + /// \param method The internal method that will be used in the + /// algorithm. For more information, see \ref Method. + /// \param factor The cost scaling factor. It must be larger than one. + /// + /// \return \c INFEASIBLE if no feasible flow exists, + /// \n \c OPTIMAL if the problem has optimal solution + /// (i.e. it is feasible and bounded), and the algorithm has found + /// optimal flow and node potentials (primal and dual solutions), + /// \n \c UNBOUNDED if the digraph contains an arc of negative cost + /// and infinite upper bound. It means that the objective function + /// is unbounded on that arc, however, note that it could actually be + /// bounded over the feasible flows, but this algroithm cannot handle + /// these cases. + /// + /// \see ProblemType, Method + /// \see resetParams(), reset() + ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) { + _alpha = factor; + ProblemType pt = init(); + if (pt != OPTIMAL) return pt; + start(method); + return OPTIMAL; + } + + /// \brief Reset all the parameters that have been given before. + /// + /// This function resets all the paramaters that have been given + /// before using functions \ref lowerMap(), \ref upperMap(), + /// \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// + /// It is useful for multiple \ref run() calls. Basically, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// For example, + /// \code + /// CostScaling cs(graph); + /// + /// // First run + /// cs.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// + /// // Run again with modified cost map (resetParams() is not called, + /// // so only the cost map have to be set again) + /// cost[e] += 100; + /// cs.costMap(cost).run(); + /// + /// // Run again from scratch using resetParams() + /// // (the lower bounds will be set to zero on all arcs) + /// cs.resetParams(); + /// cs.upperMap(capacity).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// \return (*this) + /// + /// \see reset(), run() + CostScaling& resetParams() { + for (int i = 0; i != _res_node_num; ++i) { + _supply[i] = 0; + } + int limit = _first_out[_root]; + for (int j = 0; j != limit; ++j) { + _lower[j] = 0; + _upper[j] = INF; + _scost[j] = _forward[j] ? 1 : -1; + } + for (int j = limit; j != _res_arc_num; ++j) { + _lower[j] = 0; + _upper[j] = INF; + _scost[j] = 0; + _scost[_reverse[j]] = 0; + } + _have_lower = false; + return *this; + } + + /// \brief Reset all the parameters that have been given before. + /// + /// This function resets all the paramaters that have been given + /// before using functions \ref lowerMap(), \ref upperMap(), + /// \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// + /// It is useful for multiple run() calls. If this function is not + /// used, all the parameters given before are kept for the next + /// \ref run() call. + /// However, the underlying digraph must not be modified after this + /// class have been constructed, since it copies and extends the graph. + /// \return (*this) + CostScaling& reset() { + // Resize vectors + _node_num = countNodes(_graph); + _arc_num = countArcs(_graph); + _res_node_num = _node_num + 1; + _res_arc_num = 2 * (_arc_num + _node_num); + _root = _node_num; + + _first_out.resize(_res_node_num + 1); + _forward.resize(_res_arc_num); + _source.resize(_res_arc_num); + _target.resize(_res_arc_num); + _reverse.resize(_res_arc_num); + + _lower.resize(_res_arc_num); + _upper.resize(_res_arc_num); + _scost.resize(_res_arc_num); + _supply.resize(_res_node_num); + + _res_cap.resize(_res_arc_num); + _cost.resize(_res_arc_num); + _pi.resize(_res_node_num); + _excess.resize(_res_node_num); + _next_out.resize(_res_node_num); + + _arc_vec.reserve(_res_arc_num); + _cost_vec.reserve(_res_arc_num); + + // Copy the graph + int i = 0, j = 0, k = 2 * _arc_num + _node_num; + for (NodeIt n(_graph); n != INVALID; ++n, ++i) { + _node_id[n] = i; + } + i = 0; + for (NodeIt n(_graph); n != INVALID; ++n, ++i) { + _first_out[i] = j; + for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) { + _arc_idf[a] = j; + _forward[j] = true; + _source[j] = i; + _target[j] = _node_id[_graph.runningNode(a)]; + } + for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) { + _arc_idb[a] = j; + _forward[j] = false; + _source[j] = i; + _target[j] = _node_id[_graph.runningNode(a)]; + } + _forward[j] = false; + _source[j] = i; + _target[j] = _root; + _reverse[j] = k; + _forward[k] = true; + _source[k] = _root; + _target[k] = i; + _reverse[k] = j; + ++j; ++k; + } + _first_out[i] = j; + _first_out[_res_node_num] = k; + for (ArcIt a(_graph); a != INVALID; ++a) { + int fi = _arc_idf[a]; + int bi = _arc_idb[a]; + _reverse[fi] = bi; + _reverse[bi] = fi; + } + + // Reset parameters + resetParams(); + return *this; + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions.\n + /// The \ref run() function must be called before using them. + + /// @{ + + /// \brief Return the total cost of the found flow. + /// + /// This function returns the total cost of the found flow. + /// Its complexity is O(e). + /// + /// \note The return type of the function can be specified as a + /// template parameter. For example, + /// \code + /// cs.totalCost(); + /// \endcode + /// It is useful if the total cost cannot be stored in the \c Cost + /// type of the algorithm, which is the default return type of the + /// function. + /// + /// \pre \ref run() must be called before using this function. + template + Number totalCost() const { + Number c = 0; + for (ArcIt a(_graph); a != INVALID; ++a) { + int i = _arc_idb[a]; + c += static_cast(_res_cap[i]) * + (-static_cast(_scost[i])); + } + return c; + } + +#ifndef DOXYGEN + Cost totalCost() const { + return totalCost(); + } +#endif + + /// \brief Return the flow on the given arc. + /// + /// This function returns the flow on the given arc. + /// + /// \pre \ref run() must be called before using this function. + Value flow(const Arc& a) const { + return _res_cap[_arc_idb[a]]; + } + + /// \brief Return the flow map (the primal solution). + /// + /// This function copies the flow value on each arc into the given + /// map. The \c Value type of the algorithm must be convertible to + /// the \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void flowMap(FlowMap &map) const { + for (ArcIt a(_graph); a != INVALID; ++a) { + map.set(a, _res_cap[_arc_idb[a]]); + } + } + + /// \brief Return the potential (dual value) of the given node. + /// + /// This function returns the potential (dual value) of the + /// given node. + /// + /// \pre \ref run() must be called before using this function. + Cost potential(const Node& n) const { + return static_cast(_pi[_node_id[n]]); + } + + /// \brief Return the potential map (the dual solution). + /// + /// This function copies the potential (dual value) of each node + /// into the given map. + /// The \c Cost type of the algorithm must be convertible to the + /// \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void potentialMap(PotentialMap &map) const { + for (NodeIt n(_graph); n != INVALID; ++n) { + map.set(n, static_cast(_pi[_node_id[n]])); + } + } + + /// @} + + private: + + // Initialize the algorithm + ProblemType init() { + if (_res_node_num <= 1) return INFEASIBLE; + + // Check the sum of supply values + _sum_supply = 0; + for (int i = 0; i != _root; ++i) { + _sum_supply += _supply[i]; + } + if (_sum_supply > 0) return INFEASIBLE; + + + // Initialize vectors + for (int i = 0; i != _res_node_num; ++i) { + _pi[i] = 0; + _excess[i] = _supply[i]; + } + + // Remove infinite upper bounds and check negative arcs + const Value MAX = std::numeric_limits::max(); + int last_out; + if (_have_lower) { + for (int i = 0; i != _root; ++i) { + last_out = _first_out[i+1]; + for (int j = _first_out[i]; j != last_out; ++j) { + if (_forward[j]) { + Value c = _scost[j] < 0 ? _upper[j] : _lower[j]; + if (c >= MAX) return UNBOUNDED; + _excess[i] -= c; + _excess[_target[j]] += c; + } + } + } + } else { + for (int i = 0; i != _root; ++i) { + last_out = _first_out[i+1]; + for (int j = _first_out[i]; j != last_out; ++j) { + if (_forward[j] && _scost[j] < 0) { + Value c = _upper[j]; + if (c >= MAX) return UNBOUNDED; + _excess[i] -= c; + _excess[_target[j]] += c; + } + } + } + } + Value ex, max_cap = 0; + for (int i = 0; i != _res_node_num; ++i) { + ex = _excess[i]; + _excess[i] = 0; + if (ex < 0) max_cap -= ex; + } + for (int j = 0; j != _res_arc_num; ++j) { + if (_upper[j] >= MAX) _upper[j] = max_cap; + } + + // Initialize the large cost vector and the epsilon parameter + _epsilon = 0; + LargeCost lc; + for (int i = 0; i != _root; ++i) { + last_out = _first_out[i+1]; + for (int j = _first_out[i]; j != last_out; ++j) { + lc = static_cast(_scost[j]) * _res_node_num * _alpha; + _cost[j] = lc; + if (lc > _epsilon) _epsilon = lc; + } + } + _epsilon /= _alpha; + + // Initialize maps for Circulation and remove non-zero lower bounds + ConstMap low(0); + typedef typename Digraph::template ArcMap ValueArcMap; + typedef typename Digraph::template NodeMap ValueNodeMap; + ValueArcMap cap(_graph), flow(_graph); + ValueNodeMap sup(_graph); + for (NodeIt n(_graph); n != INVALID; ++n) { + sup[n] = _supply[_node_id[n]]; + } + if (_have_lower) { + for (ArcIt a(_graph); a != INVALID; ++a) { + int j = _arc_idf[a]; + Value c = _lower[j]; + cap[a] = _upper[j] - c; + sup[_graph.source(a)] -= c; + sup[_graph.target(a)] += c; + } + } else { + for (ArcIt a(_graph); a != INVALID; ++a) { + cap[a] = _upper[_arc_idf[a]]; + } + } + + _sup_node_num = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if (sup[n] > 0) ++_sup_node_num; + } + + // Find a feasible flow using Circulation + Circulation, ValueArcMap, ValueNodeMap> + circ(_graph, low, cap, sup); + if (!circ.flowMap(flow).run()) return INFEASIBLE; + + // Set residual capacities and handle GEQ supply type + if (_sum_supply < 0) { + for (ArcIt a(_graph); a != INVALID; ++a) { + Value fa = flow[a]; + _res_cap[_arc_idf[a]] = cap[a] - fa; + _res_cap[_arc_idb[a]] = fa; + sup[_graph.source(a)] -= fa; + sup[_graph.target(a)] += fa; + } + for (NodeIt n(_graph); n != INVALID; ++n) { + _excess[_node_id[n]] = sup[n]; + } + for (int a = _first_out[_root]; a != _res_arc_num; ++a) { + int u = _target[a]; + int ra = _reverse[a]; + _res_cap[a] = -_sum_supply + 1; + _res_cap[ra] = -_excess[u]; + _cost[a] = 0; + _cost[ra] = 0; + _excess[u] = 0; + } + } else { + for (ArcIt a(_graph); a != INVALID; ++a) { + Value fa = flow[a]; + _res_cap[_arc_idf[a]] = cap[a] - fa; + _res_cap[_arc_idb[a]] = fa; + } + for (int a = _first_out[_root]; a != _res_arc_num; ++a) { + int ra = _reverse[a]; + _res_cap[a] = 0; + _res_cap[ra] = 0; + _cost[a] = 0; + _cost[ra] = 0; + } + } + + return OPTIMAL; + } + + // Execute the algorithm and transform the results + void start(Method method) { + // Maximum path length for partial augment + const int MAX_PATH_LENGTH = 4; + + // Initialize data structures for buckets + _max_rank = _alpha * _res_node_num; + _buckets.resize(_max_rank); + _bucket_next.resize(_res_node_num + 1); + _bucket_prev.resize(_res_node_num + 1); + _rank.resize(_res_node_num + 1); + + // Execute the algorithm + switch (method) { + case PUSH: + startPush(); + break; + case AUGMENT: + startAugment(_res_node_num - 1); + break; + case PARTIAL_AUGMENT: + startAugment(MAX_PATH_LENGTH); + break; + } + + // Compute node potentials for the original costs + _arc_vec.clear(); + _cost_vec.clear(); + for (int j = 0; j != _res_arc_num; ++j) { + if (_res_cap[j] > 0) { + _arc_vec.push_back(IntPair(_source[j], _target[j])); + _cost_vec.push_back(_scost[j]); + } + } + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); + + typename BellmanFord + ::template SetDistMap::Create bf(_sgr, _cost_map); + bf.distMap(_pi_map); + bf.init(0); + bf.start(); + + // Handle non-zero lower bounds + if (_have_lower) { + int limit = _first_out[_root]; + for (int j = 0; j != limit; ++j) { + if (!_forward[j]) _res_cap[j] += _lower[j]; + } + } + } + + // Initialize a cost scaling phase + void initPhase() { + // Saturate arcs not satisfying the optimality condition + for (int u = 0; u != _res_node_num; ++u) { + int last_out = _first_out[u+1]; + LargeCost pi_u = _pi[u]; + for (int a = _first_out[u]; a != last_out; ++a) { + int v = _target[a]; + if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) { + Value delta = _res_cap[a]; + _excess[u] -= delta; + _excess[v] += delta; + _res_cap[a] = 0; + _res_cap[_reverse[a]] += delta; + } + } + } + + // Find active nodes (i.e. nodes with positive excess) + for (int u = 0; u != _res_node_num; ++u) { + if (_excess[u] > 0) _active_nodes.push_back(u); + } + + // Initialize the next arcs + for (int u = 0; u != _res_node_num; ++u) { + _next_out[u] = _first_out[u]; + } + } + + // Early termination heuristic + bool earlyTermination() { + const double EARLY_TERM_FACTOR = 3.0; + + // Build a static residual graph + _arc_vec.clear(); + _cost_vec.clear(); + for (int j = 0; j != _res_arc_num; ++j) { + if (_res_cap[j] > 0) { + _arc_vec.push_back(IntPair(_source[j], _target[j])); + _cost_vec.push_back(_cost[j] + 1); + } + } + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); + + // Run Bellman-Ford algorithm to check if the current flow is optimal + BellmanFord bf(_sgr, _cost_map); + bf.init(0); + bool done = false; + int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num))); + for (int i = 0; i < K && !done; ++i) { + done = bf.processNextWeakRound(); + } + return done; + } + + // Global potential update heuristic + void globalUpdate() { + int bucket_end = _root + 1; + + // Initialize buckets + for (int r = 0; r != _max_rank; ++r) { + _buckets[r] = bucket_end; + } + Value total_excess = 0; + for (int i = 0; i != _res_node_num; ++i) { + if (_excess[i] < 0) { + _rank[i] = 0; + _bucket_next[i] = _buckets[0]; + _bucket_prev[_buckets[0]] = i; + _buckets[0] = i; + } else { + total_excess += _excess[i]; + _rank[i] = _max_rank; + } + } + if (total_excess == 0) return; + + // Search the buckets + int r = 0; + for ( ; r != _max_rank; ++r) { + while (_buckets[r] != bucket_end) { + // Remove the first node from the current bucket + int u = _buckets[r]; + _buckets[r] = _bucket_next[u]; + + // Search the incomming arcs of u + LargeCost pi_u = _pi[u]; + int last_out = _first_out[u+1]; + for (int a = _first_out[u]; a != last_out; ++a) { + int ra = _reverse[a]; + if (_res_cap[ra] > 0) { + int v = _source[ra]; + int old_rank_v = _rank[v]; + if (r < old_rank_v) { + // Compute the new rank of v + LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon; + int new_rank_v = old_rank_v; + if (nrc < LargeCost(_max_rank)) + new_rank_v = r + 1 + int(nrc); + + // Change the rank of v + if (new_rank_v < old_rank_v) { + _rank[v] = new_rank_v; + _next_out[v] = _first_out[v]; + + // Remove v from its old bucket + if (old_rank_v < _max_rank) { + if (_buckets[old_rank_v] == v) { + _buckets[old_rank_v] = _bucket_next[v]; + } else { + _bucket_next[_bucket_prev[v]] = _bucket_next[v]; + _bucket_prev[_bucket_next[v]] = _bucket_prev[v]; + } + } + + // Insert v to its new bucket + _bucket_next[v] = _buckets[new_rank_v]; + _bucket_prev[_buckets[new_rank_v]] = v; + _buckets[new_rank_v] = v; + } + } + } + } + + // Finish search if there are no more active nodes + if (_excess[u] > 0) { + total_excess -= _excess[u]; + if (total_excess <= 0) break; + } + } + if (total_excess <= 0) break; + } + + // Relabel nodes + for (int u = 0; u != _res_node_num; ++u) { + int k = std::min(_rank[u], r); + if (k > 0) { + _pi[u] -= _epsilon * k; + _next_out[u] = _first_out[u]; + } + } + } + + /// Execute the algorithm performing augment and relabel operations + void startAugment(int max_length) { + // Paramters for heuristics + const int EARLY_TERM_EPSILON_LIMIT = 1000; + const double GLOBAL_UPDATE_FACTOR = 3.0; + + const int global_update_freq = int(GLOBAL_UPDATE_FACTOR * + (_res_node_num + _sup_node_num * _sup_node_num)); + int next_update_limit = global_update_freq; + + int relabel_cnt = 0; + + // Perform cost scaling phases + std::vector path; + for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? + 1 : _epsilon / _alpha ) + { + // Early termination heuristic + if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) { + if (earlyTermination()) break; + } + + // Initialize current phase + initPhase(); + + // Perform partial augment and relabel operations + while (true) { + // Select an active node (FIFO selection) + while (_active_nodes.size() > 0 && + _excess[_active_nodes.front()] <= 0) { + _active_nodes.pop_front(); + } + if (_active_nodes.size() == 0) break; + int start = _active_nodes.front(); + + // Find an augmenting path from the start node + path.clear(); + int tip = start; + while (_excess[tip] >= 0 && int(path.size()) < max_length) { + int u; + LargeCost min_red_cost, rc, pi_tip = _pi[tip]; + int last_out = _first_out[tip+1]; + for (int a = _next_out[tip]; a != last_out; ++a) { + u = _target[a]; + if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) { + path.push_back(a); + _next_out[tip] = a; + tip = u; + goto next_step; + } + } + + // Relabel tip node + min_red_cost = std::numeric_limits::max(); + if (tip != start) { + int ra = _reverse[path.back()]; + min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]]; + } + for (int a = _first_out[tip]; a != last_out; ++a) { + rc = _cost[a] + pi_tip - _pi[_target[a]]; + if (_res_cap[a] > 0 && rc < min_red_cost) { + min_red_cost = rc; + } + } + _pi[tip] -= min_red_cost + _epsilon; + _next_out[tip] = _first_out[tip]; + ++relabel_cnt; + + // Step back + if (tip != start) { + tip = _source[path.back()]; + path.pop_back(); + } + + next_step: ; + } + + // Augment along the found path (as much flow as possible) + Value delta; + int pa, u, v = start; + for (int i = 0; i != int(path.size()); ++i) { + pa = path[i]; + u = v; + v = _target[pa]; + delta = std::min(_res_cap[pa], _excess[u]); + _res_cap[pa] -= delta; + _res_cap[_reverse[pa]] += delta; + _excess[u] -= delta; + _excess[v] += delta; + if (_excess[v] > 0 && _excess[v] <= delta) + _active_nodes.push_back(v); + } + + // Global update heuristic + if (relabel_cnt >= next_update_limit) { + globalUpdate(); + next_update_limit += global_update_freq; + } + } + } + } + + /// Execute the algorithm performing push and relabel operations + void startPush() { + // Paramters for heuristics + const int EARLY_TERM_EPSILON_LIMIT = 1000; + const double GLOBAL_UPDATE_FACTOR = 2.0; + + const int global_update_freq = int(GLOBAL_UPDATE_FACTOR * + (_res_node_num + _sup_node_num * _sup_node_num)); + int next_update_limit = global_update_freq; + + int relabel_cnt = 0; + + // Perform cost scaling phases + BoolVector hyper(_res_node_num, false); + LargeCostVector hyper_cost(_res_node_num); + for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ? + 1 : _epsilon / _alpha ) + { + // Early termination heuristic + if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) { + if (earlyTermination()) break; + } + + // Initialize current phase + initPhase(); + + // Perform push and relabel operations + while (_active_nodes.size() > 0) { + LargeCost min_red_cost, rc, pi_n; + Value delta; + int n, t, a, last_out = _res_arc_num; + + next_node: + // Select an active node (FIFO selection) + n = _active_nodes.front(); + last_out = _first_out[n+1]; + pi_n = _pi[n]; + + // Perform push operations if there are admissible arcs + if (_excess[n] > 0) { + for (a = _next_out[n]; a != last_out; ++a) { + if (_res_cap[a] > 0 && + _cost[a] + pi_n - _pi[_target[a]] < 0) { + delta = std::min(_res_cap[a], _excess[n]); + t = _target[a]; + + // Push-look-ahead heuristic + Value ahead = -_excess[t]; + int last_out_t = _first_out[t+1]; + LargeCost pi_t = _pi[t]; + for (int ta = _next_out[t]; ta != last_out_t; ++ta) { + if (_res_cap[ta] > 0 && + _cost[ta] + pi_t - _pi[_target[ta]] < 0) + ahead += _res_cap[ta]; + if (ahead >= delta) break; + } + if (ahead < 0) ahead = 0; + + // Push flow along the arc + if (ahead < delta && !hyper[t]) { + _res_cap[a] -= ahead; + _res_cap[_reverse[a]] += ahead; + _excess[n] -= ahead; + _excess[t] += ahead; + _active_nodes.push_front(t); + hyper[t] = true; + hyper_cost[t] = _cost[a] + pi_n - pi_t; + _next_out[n] = a; + goto next_node; + } else { + _res_cap[a] -= delta; + _res_cap[_reverse[a]] += delta; + _excess[n] -= delta; + _excess[t] += delta; + if (_excess[t] > 0 && _excess[t] <= delta) + _active_nodes.push_back(t); + } + + if (_excess[n] == 0) { + _next_out[n] = a; + goto remove_nodes; + } + } + } + _next_out[n] = a; + } + + // Relabel the node if it is still active (or hyper) + if (_excess[n] > 0 || hyper[n]) { + min_red_cost = hyper[n] ? -hyper_cost[n] : + std::numeric_limits::max(); + for (int a = _first_out[n]; a != last_out; ++a) { + rc = _cost[a] + pi_n - _pi[_target[a]]; + if (_res_cap[a] > 0 && rc < min_red_cost) { + min_red_cost = rc; + } + } + _pi[n] -= min_red_cost + _epsilon; + _next_out[n] = _first_out[n]; + hyper[n] = false; + ++relabel_cnt; + } + + // Remove nodes that are not active nor hyper + remove_nodes: + while ( _active_nodes.size() > 0 && + _excess[_active_nodes.front()] <= 0 && + !hyper[_active_nodes.front()] ) { + _active_nodes.pop_front(); + } + + // Global update heuristic + if (relabel_cnt >= next_update_limit) { + globalUpdate(); + for (int u = 0; u != _res_node_num; ++u) + hyper[u] = false; + next_update_limit += global_update_freq; + } + } + } + } + + }; //class CostScaling + + ///@} + +} //namespace lemon + +#endif //LEMON_COST_SCALING_H diff --git a/lemon/lemon/counter.h b/lemon/lemon/counter.h new file mode 100644 index 0000000..a004991 --- /dev/null +++ b/lemon/lemon/counter.h @@ -0,0 +1,249 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_COUNTER_H +#define LEMON_COUNTER_H + +#include +#include + +///\ingroup timecount +///\file +///\brief Tools for counting steps and events + +namespace lemon +{ + + template class _NoSubCounter; + + template + class _SubCounter + { + P &_parent; + std::string _title; + std::ostream &_os; + int count; + public: + + typedef _SubCounter<_SubCounter

> SubCounter; + typedef _NoSubCounter<_SubCounter

> NoSubCounter; + + _SubCounter(P &parent) + : _parent(parent), _title(), _os(std::cerr), count(0) {} + _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr) + : _parent(parent), _title(title), _os(os), count(0) {} + _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr) + : _parent(parent), _title(title), _os(os), count(0) {} + ~_SubCounter() { + _os << _title << count < + class _NoSubCounter + { + P &_parent; + public: + typedef _NoSubCounter<_NoSubCounter

> SubCounter; + typedef _NoSubCounter<_NoSubCounter

> NoSubCounter; + + _NoSubCounter(P &parent) :_parent(parent) {} + _NoSubCounter(P &parent,std::string,std::ostream &) + :_parent(parent) {} + _NoSubCounter(P &parent,std::string) + :_parent(parent) {} + _NoSubCounter(P &parent,const char *,std::ostream &) + :_parent(parent) {} + _NoSubCounter(P &parent,const char *) + :_parent(parent) {} + ~_NoSubCounter() {} + _NoSubCounter &operator++() { ++_parent; return *this;} + int operator++(int) { _parent++; return 0;} + _NoSubCounter &operator--() { --_parent; return *this;} + int operator--(int) { _parent--; return 0;} + _NoSubCounter &operator+=(int c) { _parent+=c; return *this;} + _NoSubCounter &operator-=(int c) { _parent-=c; return *this;} + operator int() {return 0;} + }; + + + /// \addtogroup timecount + /// @{ + + /// A counter class + + /// This class makes it easier to count certain events (e.g. for debug + /// reasons). + /// You can increment or decrement the counter using \c operator++, + /// \c operator--, \c operator+= and \c operator-=. You can also + /// define subcounters for the different phases of the algorithm or + /// for different types of operations. + /// A report containing the given title and the value of the counter + /// is automatically printed on destruction. + /// + /// The following example shows the usage of counters and subcounters. + /// \code + /// // Bubble sort + /// std::vector v; + /// ... + /// Counter op("Operations: "); + /// Counter::SubCounter as(op, "Assignments: "); + /// Counter::SubCounter co(op, "Comparisons: "); + /// for (int i = v.size()-1; i > 0; --i) { + /// for (int j = 0; j < i; ++j) { + /// if (v[j] > v[j+1]) { + /// T tmp = v[j]; + /// v[j] = v[j+1]; + /// v[j+1] = tmp; + /// as += 3; // three assignments + /// } + /// ++co; // one comparison + /// } + /// } + /// \endcode + /// + /// This code prints out something like that: + /// \code + /// Comparisons: 45 + /// Assignments: 57 + /// Operations: 102 + /// \endcode + /// + /// \sa NoCounter + class Counter + { + std::string _title; + std::ostream &_os; + int count; + public: + + /// SubCounter class + + /// This class can be used to setup subcounters for a \ref Counter + /// to have finer reports. A subcounter provides exactly the same + /// operations as the main \ref Counter, but it also increments and + /// decrements the value of its parent. + /// Subcounters can also have subcounters. + /// + /// The parent counter must be given as the first parameter of the + /// constructor. Apart from that a title and an \c ostream object + /// can also be given just like for the main \ref Counter. + /// + /// A report containing the given title and the value of the + /// subcounter is automatically printed on destruction. If you + /// would like to turn off this report, use \ref NoSubCounter + /// instead. + /// + /// \sa NoSubCounter + typedef _SubCounter SubCounter; + + /// SubCounter class without printing report on destruction + + /// This class can be used to setup subcounters for a \ref Counter. + /// It is the same as \ref SubCounter but it does not print report + /// on destruction. (It modifies the value of its parent, so 'No' + /// only means 'do not print'.) + /// + /// Replacing \ref SubCounter "SubCounter"s with \ref NoSubCounter + /// "NoSubCounter"s makes it possible to turn off reporting + /// subcounter values without actually removing the definitions + /// and the increment or decrement operators. + /// + /// \sa SubCounter + typedef _NoSubCounter NoSubCounter; + + /// Constructor. + Counter() : _title(), _os(std::cerr), count(0) {} + /// Constructor. + Counter(std::string title,std::ostream &os=std::cerr) + : _title(title), _os(os), count(0) {} + /// Constructor. + Counter(const char *title,std::ostream &os=std::cerr) + : _title(title), _os(os), count(0) {} + /// Destructor. Prints the given title and the value of the counter. + ~Counter() { + _os << _title << count < SubCounter; + typedef _NoSubCounter NoSubCounter; + + NoCounter() {} + NoCounter(std::string,std::ostream &) {} + NoCounter(const char *,std::ostream &) {} + NoCounter(std::string) {} + NoCounter(const char *) {} + NoCounter &operator++() { return *this; } + int operator++(int) { return 0; } + NoCounter &operator--() { return *this; } + int operator--(int) { return 0; } + NoCounter &operator+=(int) { return *this;} + NoCounter &operator-=(int) { return *this;} + void reset(int) {} + void reset() {} + operator int() {return 0;} + }; + + ///@} +} + +#endif diff --git a/lemon/lemon/cplex.cc b/lemon/lemon/cplex.cc new file mode 100644 index 0000000..2832d99 --- /dev/null +++ b/lemon/lemon/cplex.cc @@ -0,0 +1,984 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include + +#include + +extern "C" { +#include +} + + +///\file +///\brief Implementation of the LEMON-CPLEX lp solver interface. +namespace lemon { + + CplexEnv::LicenseError::LicenseError(int status) { + if (!CPXgeterrorstring(0, status, _message)) { + std::strcpy(_message, "Cplex unknown error"); + } + } + + CplexEnv::CplexEnv() { + int status; + _cnt = new int; + _env = CPXopenCPLEX(&status); + if (_env == 0) { + delete _cnt; + _cnt = 0; + throw LicenseError(status); + } + } + + CplexEnv::CplexEnv(const CplexEnv& other) { + _env = other._env; + _cnt = other._cnt; + ++(*_cnt); + } + + CplexEnv& CplexEnv::operator=(const CplexEnv& other) { + _env = other._env; + _cnt = other._cnt; + ++(*_cnt); + return *this; + } + + CplexEnv::~CplexEnv() { + --(*_cnt); + if (*_cnt == 0) { + delete _cnt; + CPXcloseCPLEX(&_env); + } + } + + CplexBase::CplexBase() : LpBase() { + int status; + _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem"); + messageLevel(MESSAGE_NOTHING); + } + + CplexBase::CplexBase(const CplexEnv& env) + : LpBase(), _env(env) { + int status; + _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem"); + messageLevel(MESSAGE_NOTHING); + } + + CplexBase::CplexBase(const CplexBase& cplex) + : LpBase() { + int status; + _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status); + rows = cplex.rows; + cols = cplex.cols; + messageLevel(MESSAGE_NOTHING); + } + + CplexBase::~CplexBase() { + CPXfreeprob(cplexEnv(),&_prob); + } + + int CplexBase::_addCol() { + int i = CPXgetnumcols(cplexEnv(), _prob); + double lb = -INF, ub = INF; + CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0); + return i; + } + + + int CplexBase::_addRow() { + int i = CPXgetnumrows(cplexEnv(), _prob); + const double ub = INF; + const char s = 'L'; + CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0); + return i; + } + + int CplexBase::_addRow(Value lb, ExprIterator b, + ExprIterator e, Value ub) { + int i = CPXgetnumrows(cplexEnv(), _prob); + if (lb == -INF) { + const char s = 'L'; + CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0); + } else if (ub == INF) { + const char s = 'G'; + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0); + } else if (lb == ub){ + const char s = 'E'; + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0); + } else { + const char s = 'R'; + double len = ub - lb; + CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0); + } + + std::vector indices; + std::vector rowlist; + std::vector values; + + for(ExprIterator it=b; it!=e; ++it) { + indices.push_back(it->first); + values.push_back(it->second); + rowlist.push_back(i); + } + + CPXchgcoeflist(cplexEnv(), _prob, values.size(), + &rowlist.front(), &indices.front(), &values.front()); + + return i; + } + + void CplexBase::_eraseCol(int i) { + CPXdelcols(cplexEnv(), _prob, i, i); + } + + void CplexBase::_eraseRow(int i) { + CPXdelrows(cplexEnv(), _prob, i, i); + } + + void CplexBase::_eraseColId(int i) { + cols.eraseIndex(i); + cols.shiftIndices(i); + } + void CplexBase::_eraseRowId(int i) { + rows.eraseIndex(i); + rows.shiftIndices(i); + } + + void CplexBase::_getColName(int col, std::string &name) const { + int size; + CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col); + if (size == 0) { + name.clear(); + return; + } + + size *= -1; + std::vector buf(size); + char *cname; + int tmp; + CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size, + &tmp, col, col); + name = cname; + } + + void CplexBase::_setColName(int col, const std::string &name) { + char *cname; + cname = const_cast(name.c_str()); + CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname); + } + + int CplexBase::_colByName(const std::string& name) const { + int index; + if (CPXgetcolindex(cplexEnv(), _prob, + const_cast(name.c_str()), &index) == 0) { + return index; + } + return -1; + } + + void CplexBase::_getRowName(int row, std::string &name) const { + int size; + CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row); + if (size == 0) { + name.clear(); + return; + } + + size *= -1; + std::vector buf(size); + char *cname; + int tmp; + CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size, + &tmp, row, row); + name = cname; + } + + void CplexBase::_setRowName(int row, const std::string &name) { + char *cname; + cname = const_cast(name.c_str()); + CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname); + } + + int CplexBase::_rowByName(const std::string& name) const { + int index; + if (CPXgetrowindex(cplexEnv(), _prob, + const_cast(name.c_str()), &index) == 0) { + return index; + } + return -1; + } + + void CplexBase::_setRowCoeffs(int i, ExprIterator b, + ExprIterator e) + { + std::vector indices; + std::vector rowlist; + std::vector values; + + for(ExprIterator it=b; it!=e; ++it) { + indices.push_back(it->first); + values.push_back(it->second); + rowlist.push_back(i); + } + + CPXchgcoeflist(cplexEnv(), _prob, values.size(), + &rowlist.front(), &indices.front(), &values.front()); + } + + void CplexBase::_getRowCoeffs(int i, InsertIterator b) const { + int tmp1, tmp2, tmp3, length; + CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i); + + length = -length; + std::vector indices(length); + std::vector values(length); + + CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, + &indices.front(), &values.front(), + length, &tmp3, i, i); + + for (int i = 0; i < length; ++i) { + *b = std::make_pair(indices[i], values[i]); + ++b; + } + } + + void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) { + std::vector indices; + std::vector collist; + std::vector values; + + for(ExprIterator it=b; it!=e; ++it) { + indices.push_back(it->first); + values.push_back(it->second); + collist.push_back(i); + } + + CPXchgcoeflist(cplexEnv(), _prob, values.size(), + &indices.front(), &collist.front(), &values.front()); + } + + void CplexBase::_getColCoeffs(int i, InsertIterator b) const { + + int tmp1, tmp2, tmp3, length; + CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i); + + length = -length; + std::vector indices(length); + std::vector values(length); + + CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, + &indices.front(), &values.front(), + length, &tmp3, i, i); + + for (int i = 0; i < length; ++i) { + *b = std::make_pair(indices[i], values[i]); + ++b; + } + + } + + void CplexBase::_setCoeff(int row, int col, Value value) { + CPXchgcoef(cplexEnv(), _prob, row, col, value); + } + + CplexBase::Value CplexBase::_getCoeff(int row, int col) const { + CplexBase::Value value; + CPXgetcoef(cplexEnv(), _prob, row, col, &value); + return value; + } + + void CplexBase::_setColLowerBound(int i, Value value) { + const char s = 'L'; + CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value); + } + + CplexBase::Value CplexBase::_getColLowerBound(int i) const { + CplexBase::Value res; + CPXgetlb(cplexEnv(), _prob, &res, i, i); + return res <= -CPX_INFBOUND ? -INF : res; + } + + void CplexBase::_setColUpperBound(int i, Value value) + { + const char s = 'U'; + CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value); + } + + CplexBase::Value CplexBase::_getColUpperBound(int i) const { + CplexBase::Value res; + CPXgetub(cplexEnv(), _prob, &res, i, i); + return res >= CPX_INFBOUND ? INF : res; + } + + CplexBase::Value CplexBase::_getRowLowerBound(int i) const { + char s; + CPXgetsense(cplexEnv(), _prob, &s, i, i); + CplexBase::Value res; + + switch (s) { + case 'G': + case 'R': + case 'E': + CPXgetrhs(cplexEnv(), _prob, &res, i, i); + return res <= -CPX_INFBOUND ? -INF : res; + default: + return -INF; + } + } + + CplexBase::Value CplexBase::_getRowUpperBound(int i) const { + char s; + CPXgetsense(cplexEnv(), _prob, &s, i, i); + CplexBase::Value res; + + switch (s) { + case 'L': + case 'E': + CPXgetrhs(cplexEnv(), _prob, &res, i, i); + return res >= CPX_INFBOUND ? INF : res; + case 'R': + CPXgetrhs(cplexEnv(), _prob, &res, i, i); + { + double rng; + CPXgetrngval(cplexEnv(), _prob, &rng, i, i); + res += rng; + } + return res >= CPX_INFBOUND ? INF : res; + default: + return INF; + } + } + + //This is easier to implement + void CplexBase::_set_row_bounds(int i, Value lb, Value ub) { + if (lb == -INF) { + const char s = 'L'; + CPXchgsense(cplexEnv(), _prob, 1, &i, &s); + CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub); + } else if (ub == INF) { + const char s = 'G'; + CPXchgsense(cplexEnv(), _prob, 1, &i, &s); + CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb); + } else if (lb == ub){ + const char s = 'E'; + CPXchgsense(cplexEnv(), _prob, 1, &i, &s); + CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb); + } else { + const char s = 'R'; + CPXchgsense(cplexEnv(), _prob, 1, &i, &s); + CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb); + double len = ub - lb; + CPXchgrngval(cplexEnv(), _prob, 1, &i, &len); + } + } + + void CplexBase::_setRowLowerBound(int i, Value lb) + { + LEMON_ASSERT(lb != INF, "Invalid bound"); + _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i)); + } + + void CplexBase::_setRowUpperBound(int i, Value ub) + { + + LEMON_ASSERT(ub != -INF, "Invalid bound"); + _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub); + } + + void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e) + { + std::vector indices; + std::vector values; + for(ExprIterator it=b; it!=e; ++it) { + indices.push_back(it->first); + values.push_back(it->second); + } + CPXchgobj(cplexEnv(), _prob, values.size(), + &indices.front(), &values.front()); + + } + + void CplexBase::_getObjCoeffs(InsertIterator b) const + { + int num = CPXgetnumcols(cplexEnv(), _prob); + std::vector x(num); + + CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1); + for (int i = 0; i < num; ++i) { + if (x[i] != 0.0) { + *b = std::make_pair(i, x[i]); + ++b; + } + } + } + + void CplexBase::_setObjCoeff(int i, Value obj_coef) + { + CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef); + } + + CplexBase::Value CplexBase::_getObjCoeff(int i) const + { + Value x; + CPXgetobj(cplexEnv(), _prob, &x, i, i); + return x; + } + + void CplexBase::_setSense(CplexBase::Sense sense) { + switch (sense) { + case MIN: + CPXchgobjsen(cplexEnv(), _prob, CPX_MIN); + break; + case MAX: + CPXchgobjsen(cplexEnv(), _prob, CPX_MAX); + break; + } + } + + CplexBase::Sense CplexBase::_getSense() const { + switch (CPXgetobjsen(cplexEnv(), _prob)) { + case CPX_MIN: + return MIN; + case CPX_MAX: + return MAX; + default: + LEMON_ASSERT(false, "Invalid sense"); + return CplexBase::Sense(); + } + } + + void CplexBase::_clear() { + CPXfreeprob(cplexEnv(),&_prob); + int status; + _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem"); + rows.clear(); + cols.clear(); + } + + void CplexBase::_messageLevel(MessageLevel level) { + switch (level) { + case MESSAGE_NOTHING: + _message_enabled = false; + break; + case MESSAGE_ERROR: + case MESSAGE_WARNING: + case MESSAGE_NORMAL: + case MESSAGE_VERBOSE: + _message_enabled = true; + break; + } + } + + void CplexBase::_applyMessageLevel() { + CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, + _message_enabled ? CPX_ON : CPX_OFF); + } + + // CplexLp members + + CplexLp::CplexLp() + : LpBase(), LpSolver(), CplexBase() {} + + CplexLp::CplexLp(const CplexEnv& env) + : LpBase(), LpSolver(), CplexBase(env) {} + + CplexLp::CplexLp(const CplexLp& other) + : LpBase(), LpSolver(), CplexBase(other) {} + + CplexLp::~CplexLp() {} + + CplexLp* CplexLp::newSolver() const { return new CplexLp; } + CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); } + + const char* CplexLp::_solverName() const { return "CplexLp"; } + + void CplexLp::_clear_temporals() { + _col_status.clear(); + _row_status.clear(); + _primal_ray.clear(); + _dual_ray.clear(); + } + + // The routine returns zero unless an error occurred during the + // optimization. Examples of errors include exhausting available + // memory (CPXERR_NO_MEMORY) or encountering invalid data in the + // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a + // user-specified CPLEX limit, or proving the model infeasible or + // unbounded, are not considered errors. Note that a zero return + // value does not necessarily mean that a solution exists. Use query + // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain + // further information about the status of the optimization. + CplexLp::SolveExitStatus CplexLp::convertStatus(int status) { +#if CPX_VERSION >= 800 + if (status == 0) { + switch (CPXgetstat(cplexEnv(), _prob)) { + case CPX_STAT_OPTIMAL: + case CPX_STAT_INFEASIBLE: + case CPX_STAT_UNBOUNDED: + return SOLVED; + default: + return UNSOLVED; + } + } else { + return UNSOLVED; + } +#else + if (status == 0) { + //We want to exclude some cases + switch (CPXgetstat(cplexEnv(), _prob)) { + case CPX_OBJ_LIM: + case CPX_IT_LIM_FEAS: + case CPX_IT_LIM_INFEAS: + case CPX_TIME_LIM_FEAS: + case CPX_TIME_LIM_INFEAS: + return UNSOLVED; + default: + return SOLVED; + } + } else { + return UNSOLVED; + } +#endif + } + + CplexLp::SolveExitStatus CplexLp::_solve() { + _clear_temporals(); + _applyMessageLevel(); + return convertStatus(CPXlpopt(cplexEnv(), _prob)); + } + + CplexLp::SolveExitStatus CplexLp::solvePrimal() { + _clear_temporals(); + _applyMessageLevel(); + return convertStatus(CPXprimopt(cplexEnv(), _prob)); + } + + CplexLp::SolveExitStatus CplexLp::solveDual() { + _clear_temporals(); + _applyMessageLevel(); + return convertStatus(CPXdualopt(cplexEnv(), _prob)); + } + + CplexLp::SolveExitStatus CplexLp::solveBarrier() { + _clear_temporals(); + _applyMessageLevel(); + return convertStatus(CPXbaropt(cplexEnv(), _prob)); + } + + CplexLp::Value CplexLp::_getPrimal(int i) const { + Value x; + CPXgetx(cplexEnv(), _prob, &x, i, i); + return x; + } + + CplexLp::Value CplexLp::_getDual(int i) const { + Value y; + CPXgetpi(cplexEnv(), _prob, &y, i, i); + return y; + } + + CplexLp::Value CplexLp::_getPrimalValue() const { + Value objval; + CPXgetobjval(cplexEnv(), _prob, &objval); + return objval; + } + + CplexLp::VarStatus CplexLp::_getColStatus(int i) const { + if (_col_status.empty()) { + _col_status.resize(CPXgetnumcols(cplexEnv(), _prob)); + CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0); + } + switch (_col_status[i]) { + case CPX_BASIC: + return BASIC; + case CPX_FREE_SUPER: + return FREE; + case CPX_AT_LOWER: + return LOWER; + case CPX_AT_UPPER: + return UPPER; + default: + LEMON_ASSERT(false, "Wrong column status"); + return CplexLp::VarStatus(); + } + } + + CplexLp::VarStatus CplexLp::_getRowStatus(int i) const { + if (_row_status.empty()) { + _row_status.resize(CPXgetnumrows(cplexEnv(), _prob)); + CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front()); + } + switch (_row_status[i]) { + case CPX_BASIC: + return BASIC; + case CPX_AT_LOWER: + { + char s; + CPXgetsense(cplexEnv(), _prob, &s, i, i); + return s != 'L' ? LOWER : UPPER; + } + case CPX_AT_UPPER: + return UPPER; + default: + LEMON_ASSERT(false, "Wrong row status"); + return CplexLp::VarStatus(); + } + } + + CplexLp::Value CplexLp::_getPrimalRay(int i) const { + if (_primal_ray.empty()) { + _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob)); + CPXgetray(cplexEnv(), _prob, &_primal_ray.front()); + } + return _primal_ray[i]; + } + + CplexLp::Value CplexLp::_getDualRay(int i) const { + if (_dual_ray.empty()) { + + } + return _dual_ray[i]; + } + + // Cplex 7.0 status values + // This table lists the statuses, returned by the CPXgetstat() + // routine, for solutions to LP problems or mixed integer problems. If + // no solution exists, the return value is zero. + + // For Simplex, Barrier + // 1 CPX_OPTIMAL + // Optimal solution found + // 2 CPX_INFEASIBLE + // Problem infeasible + // 3 CPX_UNBOUNDED + // Problem unbounded + // 4 CPX_OBJ_LIM + // Objective limit exceeded in Phase II + // 5 CPX_IT_LIM_FEAS + // Iteration limit exceeded in Phase II + // 6 CPX_IT_LIM_INFEAS + // Iteration limit exceeded in Phase I + // 7 CPX_TIME_LIM_FEAS + // Time limit exceeded in Phase II + // 8 CPX_TIME_LIM_INFEAS + // Time limit exceeded in Phase I + // 9 CPX_NUM_BEST_FEAS + // Problem non-optimal, singularities in Phase II + // 10 CPX_NUM_BEST_INFEAS + // Problem non-optimal, singularities in Phase I + // 11 CPX_OPTIMAL_INFEAS + // Optimal solution found, unscaled infeasibilities + // 12 CPX_ABORT_FEAS + // Aborted in Phase II + // 13 CPX_ABORT_INFEAS + // Aborted in Phase I + // 14 CPX_ABORT_DUAL_INFEAS + // Aborted in barrier, dual infeasible + // 15 CPX_ABORT_PRIM_INFEAS + // Aborted in barrier, primal infeasible + // 16 CPX_ABORT_PRIM_DUAL_INFEAS + // Aborted in barrier, primal and dual infeasible + // 17 CPX_ABORT_PRIM_DUAL_FEAS + // Aborted in barrier, primal and dual feasible + // 18 CPX_ABORT_CROSSOVER + // Aborted in crossover + // 19 CPX_INForUNBD + // Infeasible or unbounded + // 20 CPX_PIVOT + // User pivot used + // + // Pending return values + // ??case CPX_ABORT_DUAL_INFEAS + // ??case CPX_ABORT_CROSSOVER + // ??case CPX_INForUNBD + // ??case CPX_PIVOT + + //Some more interesting stuff: + + // CPX_PARAM_PROBMETHOD 1062 int LPMETHOD + // 0 Automatic + // 1 Primal Simplex + // 2 Dual Simplex + // 3 Network Simplex + // 4 Standard Barrier + // Default: 0 + // Description: Method for linear optimization. + // Determines which algorithm is used when CPXlpopt() (or "optimize" + // in the Interactive Optimizer) is called. Currently the behavior of + // the "Automatic" setting is that CPLEX simply invokes the dual + // simplex method, but this capability may be expanded in the future + // so that CPLEX chooses the method based on problem characteristics +#if CPX_VERSION < 900 + void statusSwitch(CPXENVptr cplexEnv(),int& stat){ + int lpmethod; + CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod); + if (lpmethod==2){ + if (stat==CPX_UNBOUNDED){ + stat=CPX_INFEASIBLE; + } + else{ + if (stat==CPX_INFEASIBLE) + stat=CPX_UNBOUNDED; + } + } + } +#else + void statusSwitch(CPXENVptr,int&){} +#endif + + CplexLp::ProblemType CplexLp::_getPrimalType() const { + // Unboundedness not treated well: the following is from cplex 9.0 doc + // About Unboundedness + + // The treatment of models that are unbounded involves a few + // subtleties. Specifically, a declaration of unboundedness means that + // ILOG CPLEX has determined that the model has an unbounded + // ray. Given any feasible solution x with objective z, a multiple of + // the unbounded ray can be added to x to give a feasible solution + // with objective z-1 (or z+1 for maximization models). Thus, if a + // feasible solution exists, then the optimal objective is + // unbounded. Note that ILOG CPLEX has not necessarily concluded that + // a feasible solution exists. Users can call the routine CPXsolninfo + // to determine whether ILOG CPLEX has also concluded that the model + // has a feasible solution. + + int stat = CPXgetstat(cplexEnv(), _prob); +#if CPX_VERSION >= 800 + switch (stat) + { + case CPX_STAT_OPTIMAL: + return OPTIMAL; + case CPX_STAT_UNBOUNDED: + return UNBOUNDED; + case CPX_STAT_INFEASIBLE: + return INFEASIBLE; + default: + return UNDEFINED; + } +#else + statusSwitch(cplexEnv(),stat); + //CPXgetstat(cplexEnv(), _prob); + switch (stat) { + case 0: + return UNDEFINED; //Undefined + case CPX_OPTIMAL://Optimal + return OPTIMAL; + case CPX_UNBOUNDED://Unbounded + return INFEASIBLE;//In case of dual simplex + //return UNBOUNDED; + case CPX_INFEASIBLE://Infeasible + // case CPX_IT_LIM_INFEAS: + // case CPX_TIME_LIM_INFEAS: + // case CPX_NUM_BEST_INFEAS: + // case CPX_OPTIMAL_INFEAS: + // case CPX_ABORT_INFEAS: + // case CPX_ABORT_PRIM_INFEAS: + // case CPX_ABORT_PRIM_DUAL_INFEAS: + return UNBOUNDED;//In case of dual simplex + //return INFEASIBLE; + // case CPX_OBJ_LIM: + // case CPX_IT_LIM_FEAS: + // case CPX_TIME_LIM_FEAS: + // case CPX_NUM_BEST_FEAS: + // case CPX_ABORT_FEAS: + // case CPX_ABORT_PRIM_DUAL_FEAS: + // return FEASIBLE; + default: + return UNDEFINED; //Everything else comes here + //FIXME error + } +#endif + } + + // Cplex 9.0 status values + // CPX_STAT_ABORT_DUAL_OBJ_LIM + // CPX_STAT_ABORT_IT_LIM + // CPX_STAT_ABORT_OBJ_LIM + // CPX_STAT_ABORT_PRIM_OBJ_LIM + // CPX_STAT_ABORT_TIME_LIM + // CPX_STAT_ABORT_USER + // CPX_STAT_FEASIBLE_RELAXED + // CPX_STAT_INFEASIBLE + // CPX_STAT_INForUNBD + // CPX_STAT_NUM_BEST + // CPX_STAT_OPTIMAL + // CPX_STAT_OPTIMAL_FACE_UNBOUNDED + // CPX_STAT_OPTIMAL_INFEAS + // CPX_STAT_OPTIMAL_RELAXED + // CPX_STAT_UNBOUNDED + + CplexLp::ProblemType CplexLp::_getDualType() const { + int stat = CPXgetstat(cplexEnv(), _prob); +#if CPX_VERSION >= 800 + switch (stat) { + case CPX_STAT_OPTIMAL: + return OPTIMAL; + case CPX_STAT_UNBOUNDED: + return INFEASIBLE; + default: + return UNDEFINED; + } +#else + statusSwitch(cplexEnv(),stat); + switch (stat) { + case 0: + return UNDEFINED; //Undefined + case CPX_OPTIMAL://Optimal + return OPTIMAL; + case CPX_UNBOUNDED: + return INFEASIBLE; + default: + return UNDEFINED; //Everything else comes here + //FIXME error + } +#endif + } + + // CplexMip members + + CplexMip::CplexMip() + : LpBase(), MipSolver(), CplexBase() { + +#if CPX_VERSION < 800 + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP); +#else + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MILP); +#endif + } + + CplexMip::CplexMip(const CplexEnv& env) + : LpBase(), MipSolver(), CplexBase(env) { + +#if CPX_VERSION < 800 + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MIP); +#else + CPXchgprobtype(cplexEnv(), _prob, CPXPROB_MILP); +#endif + + } + + CplexMip::CplexMip(const CplexMip& other) + : LpBase(), MipSolver(), CplexBase(other) {} + + CplexMip::~CplexMip() {} + + CplexMip* CplexMip::newSolver() const { return new CplexMip; } + CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); } + + const char* CplexMip::_solverName() const { return "CplexMip"; } + + void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) { + + // Note If a variable is to be changed to binary, a call to CPXchgbds + // should also be made to change the bounds to 0 and 1. + + switch (col_type){ + case INTEGER: { + const char t = 'I'; + CPXchgctype (cplexEnv(), _prob, 1, &i, &t); + } break; + case REAL: { + const char t = 'C'; + CPXchgctype (cplexEnv(), _prob, 1, &i, &t); + } break; + default: + break; + } + } + + CplexMip::ColTypes CplexMip::_getColType(int i) const { + char t; + CPXgetctype (cplexEnv(), _prob, &t, i, i); + switch (t) { + case 'I': + return INTEGER; + case 'C': + return REAL; + default: + LEMON_ASSERT(false, "Invalid column type"); + return ColTypes(); + } + + } + + CplexMip::SolveExitStatus CplexMip::_solve() { + int status; + _applyMessageLevel(); + status = CPXmipopt (cplexEnv(), _prob); + if (status==0) + return SOLVED; + else + return UNSOLVED; + + } + + + CplexMip::ProblemType CplexMip::_getType() const { + + int stat = CPXgetstat(cplexEnv(), _prob); + + //Fortunately, MIP statuses did not change for cplex 8.0 + switch (stat) { + case CPXMIP_OPTIMAL: + // Optimal integer solution has been found. + case CPXMIP_OPTIMAL_TOL: + // Optimal soluton with the tolerance defined by epgap or epagap has + // been found. + return OPTIMAL; + //This also exists in later issues + // case CPXMIP_UNBOUNDED: + //return UNBOUNDED; + case CPXMIP_INFEASIBLE: + return INFEASIBLE; + default: + return UNDEFINED; + } + //Unboundedness not treated well: the following is from cplex 9.0 doc + // About Unboundedness + + // The treatment of models that are unbounded involves a few + // subtleties. Specifically, a declaration of unboundedness means that + // ILOG CPLEX has determined that the model has an unbounded + // ray. Given any feasible solution x with objective z, a multiple of + // the unbounded ray can be added to x to give a feasible solution + // with objective z-1 (or z+1 for maximization models). Thus, if a + // feasible solution exists, then the optimal objective is + // unbounded. Note that ILOG CPLEX has not necessarily concluded that + // a feasible solution exists. Users can call the routine CPXsolninfo + // to determine whether ILOG CPLEX has also concluded that the model + // has a feasible solution. + } + + CplexMip::Value CplexMip::_getSol(int i) const { + Value x; + CPXgetmipx(cplexEnv(), _prob, &x, i, i); + return x; + } + + CplexMip::Value CplexMip::_getSolValue() const { + Value objval; + CPXgetmipobjval(cplexEnv(), _prob, &objval); + return objval; + } + +} //namespace lemon + diff --git a/lemon/lemon/cplex.h b/lemon/lemon/cplex.h new file mode 100644 index 0000000..ceda6a4 --- /dev/null +++ b/lemon/lemon/cplex.h @@ -0,0 +1,277 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CPLEX_H +#define LEMON_CPLEX_H + +///\file +///\brief Header of the LEMON-CPLEX lp solver interface. + +#include + +struct cpxenv; +struct cpxlp; + +namespace lemon { + + /// \brief Reference counted wrapper around cpxenv pointer + /// + /// The cplex uses environment object which is responsible for + /// checking the proper license usage. This class provides a simple + /// interface for share the environment object between different + /// problems. + class CplexEnv { + friend class CplexBase; + private: + cpxenv* _env; + mutable int* _cnt; + + public: + + /// \brief This exception is thrown when the license check is not + /// sufficient + class LicenseError : public Exception { + friend class CplexEnv; + private: + + LicenseError(int status); + char _message[510]; + + public: + + /// The short error message + virtual const char* what() const throw() { + return _message; + } + }; + + /// Constructor + CplexEnv(); + /// Shallow copy constructor + CplexEnv(const CplexEnv&); + /// Shallow assignement + CplexEnv& operator=(const CplexEnv&); + /// Destructor + virtual ~CplexEnv(); + + protected: + + cpxenv* cplexEnv() { return _env; } + const cpxenv* cplexEnv() const { return _env; } + }; + + /// \brief Base interface for the CPLEX LP and MIP solver + /// + /// This class implements the common interface of the CPLEX LP and + /// MIP solvers. + /// \ingroup lp_group + class CplexBase : virtual public LpBase { + protected: + + CplexEnv _env; + cpxlp* _prob; + + CplexBase(); + CplexBase(const CplexEnv&); + CplexBase(const CplexBase &); + virtual ~CplexBase(); + + virtual int _addCol(); + virtual int _addRow(); + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u); + + virtual void _eraseCol(int i); + virtual void _eraseRow(int i); + + virtual void _eraseColId(int i); + virtual void _eraseRowId(int i); + + virtual void _getColName(int col, std::string& name) const; + virtual void _setColName(int col, const std::string& name); + virtual int _colByName(const std::string& name) const; + + virtual void _getRowName(int row, std::string& name) const; + virtual void _setRowName(int row, const std::string& name); + virtual int _rowByName(const std::string& name) const; + + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getRowCoeffs(int i, InsertIterator b) const; + + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getColCoeffs(int i, InsertIterator b) const; + + virtual void _setCoeff(int row, int col, Value value); + virtual Value _getCoeff(int row, int col) const; + + virtual void _setColLowerBound(int i, Value value); + virtual Value _getColLowerBound(int i) const; + + virtual void _setColUpperBound(int i, Value value); + virtual Value _getColUpperBound(int i) const; + + private: + void _set_row_bounds(int i, Value lb, Value ub); + protected: + + virtual void _setRowLowerBound(int i, Value value); + virtual Value _getRowLowerBound(int i) const; + + virtual void _setRowUpperBound(int i, Value value); + virtual Value _getRowUpperBound(int i) const; + + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e); + virtual void _getObjCoeffs(InsertIterator b) const; + + virtual void _setObjCoeff(int i, Value obj_coef); + virtual Value _getObjCoeff(int i) const; + + virtual void _setSense(Sense sense); + virtual Sense _getSense() const; + + virtual void _clear(); + + virtual void _messageLevel(MessageLevel level); + void _applyMessageLevel(); + + bool _message_enabled; + + public: + + /// Returns the used \c CplexEnv instance + const CplexEnv& env() const { return _env; } + + /// \brief Returns the const cpxenv pointer + /// + /// \note The cpxenv might be destructed with the solver. + const cpxenv* cplexEnv() const { return _env.cplexEnv(); } + + /// \brief Returns the const cpxenv pointer + /// + /// \note The cpxenv might be destructed with the solver. + cpxenv* cplexEnv() { return _env.cplexEnv(); } + + /// Returns the cplex problem object + cpxlp* cplexLp() { return _prob; } + /// Returns the cplex problem object + const cpxlp* cplexLp() const { return _prob; } + + }; + + /// \brief Interface for the CPLEX LP solver + /// + /// This class implements an interface for the CPLEX LP solver. + ///\ingroup lp_group + class CplexLp : public LpSolver, public CplexBase { + public: + /// \e + CplexLp(); + /// \e + CplexLp(const CplexEnv&); + /// \e + CplexLp(const CplexLp&); + /// \e + virtual ~CplexLp(); + + /// \e + virtual CplexLp* cloneSolver() const; + /// \e + virtual CplexLp* newSolver() const; + + private: + + // these values cannot retrieved element by element + mutable std::vector _col_status; + mutable std::vector _row_status; + + mutable std::vector _primal_ray; + mutable std::vector _dual_ray; + + void _clear_temporals(); + + SolveExitStatus convertStatus(int status); + + protected: + + virtual const char* _solverName() const; + + virtual SolveExitStatus _solve(); + virtual Value _getPrimal(int i) const; + virtual Value _getDual(int i) const; + virtual Value _getPrimalValue() const; + + virtual VarStatus _getColStatus(int i) const; + virtual VarStatus _getRowStatus(int i) const; + + virtual Value _getPrimalRay(int i) const; + virtual Value _getDualRay(int i) const; + + virtual ProblemType _getPrimalType() const; + virtual ProblemType _getDualType() const; + + public: + + /// Solve with primal simplex method + SolveExitStatus solvePrimal(); + + /// Solve with dual simplex method + SolveExitStatus solveDual(); + + /// Solve with barrier method + SolveExitStatus solveBarrier(); + + }; + + /// \brief Interface for the CPLEX MIP solver + /// + /// This class implements an interface for the CPLEX MIP solver. + ///\ingroup lp_group + class CplexMip : public MipSolver, public CplexBase { + public: + /// \e + CplexMip(); + /// \e + CplexMip(const CplexEnv&); + /// \e + CplexMip(const CplexMip&); + /// \e + virtual ~CplexMip(); + + /// \e + virtual CplexMip* cloneSolver() const; + /// \e + virtual CplexMip* newSolver() const; + + protected: + + + virtual const char* _solverName() const; + + virtual ColTypes _getColType(int col) const; + virtual void _setColType(int col, ColTypes col_type); + + virtual SolveExitStatus _solve(); + virtual ProblemType _getType() const; + virtual Value _getSol(int i) const; + virtual Value _getSolValue() const; + + }; + +} //END OF NAMESPACE LEMON + +#endif //LEMON_CPLEX_H + diff --git a/lemon/lemon/cycle_canceling.h b/lemon/lemon/cycle_canceling.h new file mode 100644 index 0000000..850fb20 --- /dev/null +++ b/lemon/lemon/cycle_canceling.h @@ -0,0 +1,1170 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_CYCLE_CANCELING_H +#define LEMON_CYCLE_CANCELING_H + +/// \ingroup min_cost_flow_algs +/// \file +/// \brief Cycle-canceling algorithms for finding a minimum cost flow. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \addtogroup min_cost_flow_algs + /// @{ + + /// \brief Implementation of cycle-canceling algorithms for + /// finding a \ref min_cost_flow "minimum cost flow". + /// + /// \ref CycleCanceling implements three different cycle-canceling + /// algorithms for finding a \ref min_cost_flow "minimum cost flow" + /// \ref amo93networkflows, \ref klein67primal, + /// \ref goldberg89cyclecanceling. + /// The most efficent one (both theoretically and practically) + /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm, + /// thus it is the default method. + /// It is strongly polynomial, but in practice, it is typically much + /// slower than the scaling algorithms and NetworkSimplex. + /// + /// Most of the parameters of the problem (except for the digraph) + /// can be given using separate functions, and the algorithm can be + /// executed using the \ref run() function. If some parameters are not + /// specified, then default values will be used. + /// + /// \tparam GR The digraph type the algorithm runs on. + /// \tparam V The number type used for flow amounts, capacity bounds + /// and supply values in the algorithm. By default, it is \c int. + /// \tparam C The number type used for costs and potentials in the + /// algorithm. By default, it is the same as \c V. + /// + /// \warning Both number types must be signed and all input data must + /// be integer. + /// \warning This algorithm does not support negative costs for such + /// arcs that have infinite upper bound. + /// + /// \note For more information about the three available methods, + /// see \ref Method. +#ifdef DOXYGEN + template +#else + template +#endif + class CycleCanceling + { + public: + + /// The type of the digraph + typedef GR Digraph; + /// The type of the flow amounts, capacity bounds and supply values + typedef V Value; + /// The type of the arc costs + typedef C Cost; + + public: + + /// \brief Problem type constants for the \c run() function. + /// + /// Enum type containing the problem type constants that can be + /// returned by the \ref run() function of the algorithm. + enum ProblemType { + /// The problem has no feasible solution (flow). + INFEASIBLE, + /// The problem has optimal solution (i.e. it is feasible and + /// bounded), and the algorithm has found optimal flow and node + /// potentials (primal and dual solutions). + OPTIMAL, + /// The digraph contains an arc of negative cost and infinite + /// upper bound. It means that the objective function is unbounded + /// on that arc, however, note that it could actually be bounded + /// over the feasible flows, but this algroithm cannot handle + /// these cases. + UNBOUNDED + }; + + /// \brief Constants for selecting the used method. + /// + /// Enum type containing constants for selecting the used method + /// for the \ref run() function. + /// + /// \ref CycleCanceling provides three different cycle-canceling + /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" + /// is used, which proved to be the most efficient and the most robust + /// on various test inputs. + /// However, the other methods can be selected using the \ref run() + /// function with the proper parameter. + enum Method { + /// A simple cycle-canceling method, which uses the + /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration + /// number for detecting negative cycles in the residual network. + SIMPLE_CYCLE_CANCELING, + /// The "Minimum Mean Cycle-Canceling" algorithm, which is a + /// well-known strongly polynomial method + /// \ref goldberg89cyclecanceling. It improves along a + /// \ref min_mean_cycle "minimum mean cycle" in each iteration. + /// Its running time complexity is O(n2m3log(n)). + MINIMUM_MEAN_CYCLE_CANCELING, + /// The "Cancel And Tighten" algorithm, which can be viewed as an + /// improved version of the previous method + /// \ref goldberg89cyclecanceling. + /// It is faster both in theory and in practice, its running time + /// complexity is O(n2m2log(n)). + CANCEL_AND_TIGHTEN + }; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + typedef std::vector IntVector; + typedef std::vector DoubleVector; + typedef std::vector ValueVector; + typedef std::vector CostVector; + typedef std::vector BoolVector; + // Note: vector is used instead of vector for efficiency reasons + + private: + + template + class StaticVectorMap { + public: + typedef KT Key; + typedef VT Value; + + StaticVectorMap(std::vector& v) : _v(v) {} + + const Value& operator[](const Key& key) const { + return _v[StaticDigraph::id(key)]; + } + + Value& operator[](const Key& key) { + return _v[StaticDigraph::id(key)]; + } + + void set(const Key& key, const Value& val) { + _v[StaticDigraph::id(key)] = val; + } + + private: + std::vector& _v; + }; + + typedef StaticVectorMap CostNodeMap; + typedef StaticVectorMap CostArcMap; + + private: + + + // Data related to the underlying digraph + const GR &_graph; + int _node_num; + int _arc_num; + int _res_node_num; + int _res_arc_num; + int _root; + + // Parameters of the problem + bool _have_lower; + Value _sum_supply; + + // Data structures for storing the digraph + IntNodeMap _node_id; + IntArcMap _arc_idf; + IntArcMap _arc_idb; + IntVector _first_out; + BoolVector _forward; + IntVector _source; + IntVector _target; + IntVector _reverse; + + // Node and arc data + ValueVector _lower; + ValueVector _upper; + CostVector _cost; + ValueVector _supply; + + ValueVector _res_cap; + CostVector _pi; + + // Data for a StaticDigraph structure + typedef std::pair IntPair; + StaticDigraph _sgr; + std::vector _arc_vec; + std::vector _cost_vec; + IntVector _id_vec; + CostArcMap _cost_map; + CostNodeMap _pi_map; + + public: + + /// \brief Constant for infinite upper bounds (capacities). + /// + /// Constant for infinite upper bounds (capacities). + /// It is \c std::numeric_limits::infinity() if available, + /// \c std::numeric_limits::max() otherwise. + const Value INF; + + public: + + /// \brief Constructor. + /// + /// The constructor of the class. + /// + /// \param graph The digraph the algorithm runs on. + CycleCanceling(const GR& graph) : + _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph), + _cost_map(_cost_vec), _pi_map(_pi), + INF(std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max()) + { + // Check the number types + LEMON_ASSERT(std::numeric_limits::is_signed, + "The flow type of CycleCanceling must be signed"); + LEMON_ASSERT(std::numeric_limits::is_signed, + "The cost type of CycleCanceling must be signed"); + + // Reset data structures + reset(); + } + + /// \name Parameters + /// The parameters of the algorithm can be specified using these + /// functions. + + /// @{ + + /// \brief Set the lower bounds on the arcs. + /// + /// This function sets the lower bounds on the arcs. + /// If it is not used before calling \ref run(), the lower bounds + /// will be set to zero on all arcs. + /// + /// \param map An arc map storing the lower bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CycleCanceling& lowerMap(const LowerMap& map) { + _have_lower = true; + for (ArcIt a(_graph); a != INVALID; ++a) { + _lower[_arc_idf[a]] = map[a]; + _lower[_arc_idb[a]] = map[a]; + } + return *this; + } + + /// \brief Set the upper bounds (capacities) on the arcs. + /// + /// This function sets the upper bounds (capacities) on the arcs. + /// If it is not used before calling \ref run(), the upper bounds + /// will be set to \ref INF on all arcs (i.e. the flow value will be + /// unbounded from above). + /// + /// \param map An arc map storing the upper bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CycleCanceling& upperMap(const UpperMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _upper[_arc_idf[a]] = map[a]; + } + return *this; + } + + /// \brief Set the costs of the arcs. + /// + /// This function sets the costs of the arcs. + /// If it is not used before calling \ref run(), the costs + /// will be set to \c 1 on all arcs. + /// + /// \param map An arc map storing the costs. + /// Its \c Value type must be convertible to the \c Cost type + /// of the algorithm. + /// + /// \return (*this) + template + CycleCanceling& costMap(const CostMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _cost[_arc_idf[a]] = map[a]; + _cost[_arc_idb[a]] = -map[a]; + } + return *this; + } + + /// \brief Set the supply values of the nodes. + /// + /// This function sets the supply values of the nodes. + /// If neither this function nor \ref stSupply() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// \param map A node map storing the supply values. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + CycleCanceling& supplyMap(const SupplyMap& map) { + for (NodeIt n(_graph); n != INVALID; ++n) { + _supply[_node_id[n]] = map[n]; + } + return *this; + } + + /// \brief Set single source and target nodes and a supply value. + /// + /// This function sets a single source node and a single target node + /// and the required flow value. + /// If neither this function nor \ref supplyMap() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// Using this function has the same effect as using \ref supplyMap() + /// with such a map in which \c k is assigned to \c s, \c -k is + /// assigned to \c t and all other nodes have zero supply value. + /// + /// \param s The source node. + /// \param t The target node. + /// \param k The required amount of flow from node \c s to node \c t + /// (i.e. the supply of \c s and the demand of \c t). + /// + /// \return (*this) + CycleCanceling& stSupply(const Node& s, const Node& t, Value k) { + for (int i = 0; i != _res_node_num; ++i) { + _supply[i] = 0; + } + _supply[_node_id[s]] = k; + _supply[_node_id[t]] = -k; + return *this; + } + + /// @} + + /// \name Execution control + /// The algorithm can be executed using \ref run(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// The paramters can be specified using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// For example, + /// \code + /// CycleCanceling cc(graph); + /// cc.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// This function can be called more than once. All the given parameters + /// are kept for the next call, unless \ref resetParams() or \ref reset() + /// is used, thus only the modified parameters have to be set again. + /// If the underlying digraph was also modified after the construction + /// of the class (or the last \ref reset() call), then the \ref reset() + /// function must be called. + /// + /// \param method The cycle-canceling method that will be used. + /// For more information, see \ref Method. + /// + /// \return \c INFEASIBLE if no feasible flow exists, + /// \n \c OPTIMAL if the problem has optimal solution + /// (i.e. it is feasible and bounded), and the algorithm has found + /// optimal flow and node potentials (primal and dual solutions), + /// \n \c UNBOUNDED if the digraph contains an arc of negative cost + /// and infinite upper bound. It means that the objective function + /// is unbounded on that arc, however, note that it could actually be + /// bounded over the feasible flows, but this algroithm cannot handle + /// these cases. + /// + /// \see ProblemType, Method + /// \see resetParams(), reset() + ProblemType run(Method method = CANCEL_AND_TIGHTEN) { + ProblemType pt = init(); + if (pt != OPTIMAL) return pt; + start(method); + return OPTIMAL; + } + + /// \brief Reset all the parameters that have been given before. + /// + /// This function resets all the paramaters that have been given + /// before using functions \ref lowerMap(), \ref upperMap(), + /// \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// + /// It is useful for multiple \ref run() calls. Basically, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// For example, + /// \code + /// CycleCanceling cs(graph); + /// + /// // First run + /// cc.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// + /// // Run again with modified cost map (resetParams() is not called, + /// // so only the cost map have to be set again) + /// cost[e] += 100; + /// cc.costMap(cost).run(); + /// + /// // Run again from scratch using resetParams() + /// // (the lower bounds will be set to zero on all arcs) + /// cc.resetParams(); + /// cc.upperMap(capacity).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// \return (*this) + /// + /// \see reset(), run() + CycleCanceling& resetParams() { + for (int i = 0; i != _res_node_num; ++i) { + _supply[i] = 0; + } + int limit = _first_out[_root]; + for (int j = 0; j != limit; ++j) { + _lower[j] = 0; + _upper[j] = INF; + _cost[j] = _forward[j] ? 1 : -1; + } + for (int j = limit; j != _res_arc_num; ++j) { + _lower[j] = 0; + _upper[j] = INF; + _cost[j] = 0; + _cost[_reverse[j]] = 0; + } + _have_lower = false; + return *this; + } + + /// \brief Reset the internal data structures and all the parameters + /// that have been given before. + /// + /// This function resets the internal data structures and all the + /// paramaters that have been given before using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// + /// It is useful for multiple \ref run() calls. Basically, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// See \ref resetParams() for examples. + /// + /// \return (*this) + /// + /// \see resetParams(), run() + CycleCanceling& reset() { + // Resize vectors + _node_num = countNodes(_graph); + _arc_num = countArcs(_graph); + _res_node_num = _node_num + 1; + _res_arc_num = 2 * (_arc_num + _node_num); + _root = _node_num; + + _first_out.resize(_res_node_num + 1); + _forward.resize(_res_arc_num); + _source.resize(_res_arc_num); + _target.resize(_res_arc_num); + _reverse.resize(_res_arc_num); + + _lower.resize(_res_arc_num); + _upper.resize(_res_arc_num); + _cost.resize(_res_arc_num); + _supply.resize(_res_node_num); + + _res_cap.resize(_res_arc_num); + _pi.resize(_res_node_num); + + _arc_vec.reserve(_res_arc_num); + _cost_vec.reserve(_res_arc_num); + _id_vec.reserve(_res_arc_num); + + // Copy the graph + int i = 0, j = 0, k = 2 * _arc_num + _node_num; + for (NodeIt n(_graph); n != INVALID; ++n, ++i) { + _node_id[n] = i; + } + i = 0; + for (NodeIt n(_graph); n != INVALID; ++n, ++i) { + _first_out[i] = j; + for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) { + _arc_idf[a] = j; + _forward[j] = true; + _source[j] = i; + _target[j] = _node_id[_graph.runningNode(a)]; + } + for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) { + _arc_idb[a] = j; + _forward[j] = false; + _source[j] = i; + _target[j] = _node_id[_graph.runningNode(a)]; + } + _forward[j] = false; + _source[j] = i; + _target[j] = _root; + _reverse[j] = k; + _forward[k] = true; + _source[k] = _root; + _target[k] = i; + _reverse[k] = j; + ++j; ++k; + } + _first_out[i] = j; + _first_out[_res_node_num] = k; + for (ArcIt a(_graph); a != INVALID; ++a) { + int fi = _arc_idf[a]; + int bi = _arc_idb[a]; + _reverse[fi] = bi; + _reverse[bi] = fi; + } + + // Reset parameters + resetParams(); + return *this; + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions.\n + /// The \ref run() function must be called before using them. + + /// @{ + + /// \brief Return the total cost of the found flow. + /// + /// This function returns the total cost of the found flow. + /// Its complexity is O(e). + /// + /// \note The return type of the function can be specified as a + /// template parameter. For example, + /// \code + /// cc.totalCost(); + /// \endcode + /// It is useful if the total cost cannot be stored in the \c Cost + /// type of the algorithm, which is the default return type of the + /// function. + /// + /// \pre \ref run() must be called before using this function. + template + Number totalCost() const { + Number c = 0; + for (ArcIt a(_graph); a != INVALID; ++a) { + int i = _arc_idb[a]; + c += static_cast(_res_cap[i]) * + (-static_cast(_cost[i])); + } + return c; + } + +#ifndef DOXYGEN + Cost totalCost() const { + return totalCost(); + } +#endif + + /// \brief Return the flow on the given arc. + /// + /// This function returns the flow on the given arc. + /// + /// \pre \ref run() must be called before using this function. + Value flow(const Arc& a) const { + return _res_cap[_arc_idb[a]]; + } + + /// \brief Return the flow map (the primal solution). + /// + /// This function copies the flow value on each arc into the given + /// map. The \c Value type of the algorithm must be convertible to + /// the \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void flowMap(FlowMap &map) const { + for (ArcIt a(_graph); a != INVALID; ++a) { + map.set(a, _res_cap[_arc_idb[a]]); + } + } + + /// \brief Return the potential (dual value) of the given node. + /// + /// This function returns the potential (dual value) of the + /// given node. + /// + /// \pre \ref run() must be called before using this function. + Cost potential(const Node& n) const { + return static_cast(_pi[_node_id[n]]); + } + + /// \brief Return the potential map (the dual solution). + /// + /// This function copies the potential (dual value) of each node + /// into the given map. + /// The \c Cost type of the algorithm must be convertible to the + /// \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void potentialMap(PotentialMap &map) const { + for (NodeIt n(_graph); n != INVALID; ++n) { + map.set(n, static_cast(_pi[_node_id[n]])); + } + } + + /// @} + + private: + + // Initialize the algorithm + ProblemType init() { + if (_res_node_num <= 1) return INFEASIBLE; + + // Check the sum of supply values + _sum_supply = 0; + for (int i = 0; i != _root; ++i) { + _sum_supply += _supply[i]; + } + if (_sum_supply > 0) return INFEASIBLE; + + + // Initialize vectors + for (int i = 0; i != _res_node_num; ++i) { + _pi[i] = 0; + } + ValueVector excess(_supply); + + // Remove infinite upper bounds and check negative arcs + const Value MAX = std::numeric_limits::max(); + int last_out; + if (_have_lower) { + for (int i = 0; i != _root; ++i) { + last_out = _first_out[i+1]; + for (int j = _first_out[i]; j != last_out; ++j) { + if (_forward[j]) { + Value c = _cost[j] < 0 ? _upper[j] : _lower[j]; + if (c >= MAX) return UNBOUNDED; + excess[i] -= c; + excess[_target[j]] += c; + } + } + } + } else { + for (int i = 0; i != _root; ++i) { + last_out = _first_out[i+1]; + for (int j = _first_out[i]; j != last_out; ++j) { + if (_forward[j] && _cost[j] < 0) { + Value c = _upper[j]; + if (c >= MAX) return UNBOUNDED; + excess[i] -= c; + excess[_target[j]] += c; + } + } + } + } + Value ex, max_cap = 0; + for (int i = 0; i != _res_node_num; ++i) { + ex = excess[i]; + if (ex < 0) max_cap -= ex; + } + for (int j = 0; j != _res_arc_num; ++j) { + if (_upper[j] >= MAX) _upper[j] = max_cap; + } + + // Initialize maps for Circulation and remove non-zero lower bounds + ConstMap low(0); + typedef typename Digraph::template ArcMap ValueArcMap; + typedef typename Digraph::template NodeMap ValueNodeMap; + ValueArcMap cap(_graph), flow(_graph); + ValueNodeMap sup(_graph); + for (NodeIt n(_graph); n != INVALID; ++n) { + sup[n] = _supply[_node_id[n]]; + } + if (_have_lower) { + for (ArcIt a(_graph); a != INVALID; ++a) { + int j = _arc_idf[a]; + Value c = _lower[j]; + cap[a] = _upper[j] - c; + sup[_graph.source(a)] -= c; + sup[_graph.target(a)] += c; + } + } else { + for (ArcIt a(_graph); a != INVALID; ++a) { + cap[a] = _upper[_arc_idf[a]]; + } + } + + // Find a feasible flow using Circulation + Circulation, ValueArcMap, ValueNodeMap> + circ(_graph, low, cap, sup); + if (!circ.flowMap(flow).run()) return INFEASIBLE; + + // Set residual capacities and handle GEQ supply type + if (_sum_supply < 0) { + for (ArcIt a(_graph); a != INVALID; ++a) { + Value fa = flow[a]; + _res_cap[_arc_idf[a]] = cap[a] - fa; + _res_cap[_arc_idb[a]] = fa; + sup[_graph.source(a)] -= fa; + sup[_graph.target(a)] += fa; + } + for (NodeIt n(_graph); n != INVALID; ++n) { + excess[_node_id[n]] = sup[n]; + } + for (int a = _first_out[_root]; a != _res_arc_num; ++a) { + int u = _target[a]; + int ra = _reverse[a]; + _res_cap[a] = -_sum_supply + 1; + _res_cap[ra] = -excess[u]; + _cost[a] = 0; + _cost[ra] = 0; + } + } else { + for (ArcIt a(_graph); a != INVALID; ++a) { + Value fa = flow[a]; + _res_cap[_arc_idf[a]] = cap[a] - fa; + _res_cap[_arc_idb[a]] = fa; + } + for (int a = _first_out[_root]; a != _res_arc_num; ++a) { + int ra = _reverse[a]; + _res_cap[a] = 1; + _res_cap[ra] = 0; + _cost[a] = 0; + _cost[ra] = 0; + } + } + + return OPTIMAL; + } + + // Build a StaticDigraph structure containing the current + // residual network + void buildResidualNetwork() { + _arc_vec.clear(); + _cost_vec.clear(); + _id_vec.clear(); + for (int j = 0; j != _res_arc_num; ++j) { + if (_res_cap[j] > 0) { + _arc_vec.push_back(IntPair(_source[j], _target[j])); + _cost_vec.push_back(_cost[j]); + _id_vec.push_back(j); + } + } + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); + } + + // Execute the algorithm and transform the results + void start(Method method) { + // Execute the algorithm + switch (method) { + case SIMPLE_CYCLE_CANCELING: + startSimpleCycleCanceling(); + break; + case MINIMUM_MEAN_CYCLE_CANCELING: + startMinMeanCycleCanceling(); + break; + case CANCEL_AND_TIGHTEN: + startCancelAndTighten(); + break; + } + + // Compute node potentials + if (method != SIMPLE_CYCLE_CANCELING) { + buildResidualNetwork(); + typename BellmanFord + ::template SetDistMap::Create bf(_sgr, _cost_map); + bf.distMap(_pi_map); + bf.init(0); + bf.start(); + } + + // Handle non-zero lower bounds + if (_have_lower) { + int limit = _first_out[_root]; + for (int j = 0; j != limit; ++j) { + if (!_forward[j]) _res_cap[j] += _lower[j]; + } + } + } + + // Execute the "Simple Cycle Canceling" method + void startSimpleCycleCanceling() { + // Constants for computing the iteration limits + const int BF_FIRST_LIMIT = 2; + const double BF_LIMIT_FACTOR = 1.5; + + typedef StaticVectorMap FilterMap; + typedef FilterArcs ResDigraph; + typedef StaticVectorMap PredMap; + typedef typename BellmanFord + ::template SetDistMap + ::template SetPredMap::Create BF; + + // Build the residual network + _arc_vec.clear(); + _cost_vec.clear(); + for (int j = 0; j != _res_arc_num; ++j) { + _arc_vec.push_back(IntPair(_source[j], _target[j])); + _cost_vec.push_back(_cost[j]); + } + _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end()); + + FilterMap filter_map(_res_cap); + ResDigraph rgr(_sgr, filter_map); + std::vector cycle; + std::vector pred(_res_arc_num); + PredMap pred_map(pred); + BF bf(rgr, _cost_map); + bf.distMap(_pi_map).predMap(pred_map); + + int length_bound = BF_FIRST_LIMIT; + bool optimal = false; + while (!optimal) { + bf.init(0); + int iter_num = 0; + bool cycle_found = false; + while (!cycle_found) { + // Perform some iterations of the Bellman-Ford algorithm + int curr_iter_num = iter_num + length_bound <= _node_num ? + length_bound : _node_num - iter_num; + iter_num += curr_iter_num; + int real_iter_num = curr_iter_num; + for (int i = 0; i < curr_iter_num; ++i) { + if (bf.processNextWeakRound()) { + real_iter_num = i; + break; + } + } + if (real_iter_num < curr_iter_num) { + // Optimal flow is found + optimal = true; + break; + } else { + // Search for node disjoint negative cycles + std::vector state(_res_node_num, 0); + int id = 0; + for (int u = 0; u != _res_node_num; ++u) { + if (state[u] != 0) continue; + ++id; + int v = u; + for (; v != -1 && state[v] == 0; v = pred[v] == INVALID ? + -1 : rgr.id(rgr.source(pred[v]))) { + state[v] = id; + } + if (v != -1 && state[v] == id) { + // A negative cycle is found + cycle_found = true; + cycle.clear(); + StaticDigraph::Arc a = pred[v]; + Value d, delta = _res_cap[rgr.id(a)]; + cycle.push_back(rgr.id(a)); + while (rgr.id(rgr.source(a)) != v) { + a = pred_map[rgr.source(a)]; + d = _res_cap[rgr.id(a)]; + if (d < delta) delta = d; + cycle.push_back(rgr.id(a)); + } + + // Augment along the cycle + for (int i = 0; i < int(cycle.size()); ++i) { + int j = cycle[i]; + _res_cap[j] -= delta; + _res_cap[_reverse[j]] += delta; + } + } + } + } + + // Increase iteration limit if no cycle is found + if (!cycle_found) { + length_bound = static_cast(length_bound * BF_LIMIT_FACTOR); + } + } + } + } + + // Execute the "Minimum Mean Cycle Canceling" method + void startMinMeanCycleCanceling() { + typedef SimplePath SPath; + typedef typename SPath::ArcIt SPathArcIt; + typedef typename HowardMmc + ::template SetPath::Create MMC; + + SPath cycle; + MMC mmc(_sgr, _cost_map); + mmc.cycle(cycle); + buildResidualNetwork(); + while (mmc.findCycleMean() && mmc.cycleCost() < 0) { + // Find the cycle + mmc.findCycle(); + + // Compute delta value + Value delta = INF; + for (SPathArcIt a(cycle); a != INVALID; ++a) { + Value d = _res_cap[_id_vec[_sgr.id(a)]]; + if (d < delta) delta = d; + } + + // Augment along the cycle + for (SPathArcIt a(cycle); a != INVALID; ++a) { + int j = _id_vec[_sgr.id(a)]; + _res_cap[j] -= delta; + _res_cap[_reverse[j]] += delta; + } + + // Rebuild the residual network + buildResidualNetwork(); + } + } + + // Execute the "Cancel And Tighten" method + void startCancelAndTighten() { + // Constants for the min mean cycle computations + const double LIMIT_FACTOR = 1.0; + const int MIN_LIMIT = 5; + + // Contruct auxiliary data vectors + DoubleVector pi(_res_node_num, 0.0); + IntVector level(_res_node_num); + BoolVector reached(_res_node_num); + BoolVector processed(_res_node_num); + IntVector pred_node(_res_node_num); + IntVector pred_arc(_res_node_num); + std::vector stack(_res_node_num); + std::vector proc_vector(_res_node_num); + + // Initialize epsilon + double epsilon = 0; + for (int a = 0; a != _res_arc_num; ++a) { + if (_res_cap[a] > 0 && -_cost[a] > epsilon) + epsilon = -_cost[a]; + } + + // Start phases + Tolerance tol; + tol.epsilon(1e-6); + int limit = int(LIMIT_FACTOR * std::sqrt(double(_res_node_num))); + if (limit < MIN_LIMIT) limit = MIN_LIMIT; + int iter = limit; + while (epsilon * _res_node_num >= 1) { + // Find and cancel cycles in the admissible network using DFS + for (int u = 0; u != _res_node_num; ++u) { + reached[u] = false; + processed[u] = false; + } + int stack_head = -1; + int proc_head = -1; + for (int start = 0; start != _res_node_num; ++start) { + if (reached[start]) continue; + + // New start node + reached[start] = true; + pred_arc[start] = -1; + pred_node[start] = -1; + + // Find the first admissible outgoing arc + double p = pi[start]; + int a = _first_out[start]; + int last_out = _first_out[start+1]; + for (; a != last_out && (_res_cap[a] == 0 || + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ; + if (a == last_out) { + processed[start] = true; + proc_vector[++proc_head] = start; + continue; + } + stack[++stack_head] = a; + + while (stack_head >= 0) { + int sa = stack[stack_head]; + int u = _source[sa]; + int v = _target[sa]; + + if (!reached[v]) { + // A new node is reached + reached[v] = true; + pred_node[v] = u; + pred_arc[v] = sa; + p = pi[v]; + a = _first_out[v]; + last_out = _first_out[v+1]; + for (; a != last_out && (_res_cap[a] == 0 || + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ; + stack[++stack_head] = a == last_out ? -1 : a; + } else { + if (!processed[v]) { + // A cycle is found + int n, w = u; + Value d, delta = _res_cap[sa]; + for (n = u; n != v; n = pred_node[n]) { + d = _res_cap[pred_arc[n]]; + if (d <= delta) { + delta = d; + w = pred_node[n]; + } + } + + // Augment along the cycle + _res_cap[sa] -= delta; + _res_cap[_reverse[sa]] += delta; + for (n = u; n != v; n = pred_node[n]) { + int pa = pred_arc[n]; + _res_cap[pa] -= delta; + _res_cap[_reverse[pa]] += delta; + } + for (n = u; stack_head > 0 && n != w; n = pred_node[n]) { + --stack_head; + reached[n] = false; + } + u = w; + } + v = u; + + // Find the next admissible outgoing arc + p = pi[v]; + a = stack[stack_head] + 1; + last_out = _first_out[v+1]; + for (; a != last_out && (_res_cap[a] == 0 || + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ; + stack[stack_head] = a == last_out ? -1 : a; + } + + while (stack_head >= 0 && stack[stack_head] == -1) { + processed[v] = true; + proc_vector[++proc_head] = v; + if (--stack_head >= 0) { + // Find the next admissible outgoing arc + v = _source[stack[stack_head]]; + p = pi[v]; + a = stack[stack_head] + 1; + last_out = _first_out[v+1]; + for (; a != last_out && (_res_cap[a] == 0 || + !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ; + stack[stack_head] = a == last_out ? -1 : a; + } + } + } + } + + // Tighten potentials and epsilon + if (--iter > 0) { + for (int u = 0; u != _res_node_num; ++u) { + level[u] = 0; + } + for (int i = proc_head; i > 0; --i) { + int u = proc_vector[i]; + double p = pi[u]; + int l = level[u] + 1; + int last_out = _first_out[u+1]; + for (int a = _first_out[u]; a != last_out; ++a) { + int v = _target[a]; + if (_res_cap[a] > 0 && tol.negative(_cost[a] + p - pi[v]) && + l > level[v]) level[v] = l; + } + } + + // Modify potentials + double q = std::numeric_limits::max(); + for (int u = 0; u != _res_node_num; ++u) { + int lu = level[u]; + double p, pu = pi[u]; + int last_out = _first_out[u+1]; + for (int a = _first_out[u]; a != last_out; ++a) { + if (_res_cap[a] == 0) continue; + int v = _target[a]; + int ld = lu - level[v]; + if (ld > 0) { + p = (_cost[a] + pu - pi[v] + epsilon) / (ld + 1); + if (p < q) q = p; + } + } + } + for (int u = 0; u != _res_node_num; ++u) { + pi[u] -= q * level[u]; + } + + // Modify epsilon + epsilon = 0; + for (int u = 0; u != _res_node_num; ++u) { + double curr, pu = pi[u]; + int last_out = _first_out[u+1]; + for (int a = _first_out[u]; a != last_out; ++a) { + if (_res_cap[a] == 0) continue; + curr = _cost[a] + pu - pi[_target[a]]; + if (-curr > epsilon) epsilon = -curr; + } + } + } else { + typedef HowardMmc MMC; + typedef typename BellmanFord + ::template SetDistMap::Create BF; + + // Set epsilon to the minimum cycle mean + buildResidualNetwork(); + MMC mmc(_sgr, _cost_map); + mmc.findCycleMean(); + epsilon = -mmc.cycleMean(); + Cost cycle_cost = mmc.cycleCost(); + int cycle_size = mmc.cycleSize(); + + // Compute feasible potentials for the current epsilon + for (int i = 0; i != int(_cost_vec.size()); ++i) { + _cost_vec[i] = cycle_size * _cost_vec[i] - cycle_cost; + } + BF bf(_sgr, _cost_map); + bf.distMap(_pi_map); + bf.init(0); + bf.start(); + for (int u = 0; u != _res_node_num; ++u) { + pi[u] = static_cast(_pi[u]) / cycle_size; + } + + iter = limit; + } + } + } + + }; //class CycleCanceling + + ///@} + +} //namespace lemon + +#endif //LEMON_CYCLE_CANCELING_H diff --git a/lemon/lemon/dfs.h b/lemon/lemon/dfs.h new file mode 100644 index 0000000..625a094 --- /dev/null +++ b/lemon/lemon/dfs.h @@ -0,0 +1,1636 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_DFS_H +#define LEMON_DFS_H + +///\ingroup search +///\file +///\brief DFS algorithm. + +#include +#include +#include +#include +#include +#include + +namespace lemon { + + ///Default traits class of Dfs class. + + ///Default traits class of Dfs class. + ///\tparam GR Digraph type. + template + struct DfsDefaultTraits + { + ///The type of the digraph the algorithm runs on. + typedef GR Digraph; + + ///\brief The type of the map that stores the predecessor + ///arcs of the %DFS paths. + /// + ///The type of the map that stores the predecessor + ///arcs of the %DFS paths. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap PredMap; + ///Instantiates a \c PredMap. + + ///This function instantiates a \ref PredMap. + ///\param g is the digraph, to which we would like to define the + ///\ref PredMap. + static PredMap *createPredMap(const Digraph &g) + { + return new PredMap(g); + } + + ///The type of the map that indicates which nodes are processed. + + ///The type of the map that indicates which nodes are processed. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + ///By default, it is a NullMap. + typedef NullMap ProcessedMap; + ///Instantiates a \c ProcessedMap. + + ///This function instantiates a \ref ProcessedMap. + ///\param g is the digraph, to which + ///we would like to define the \ref ProcessedMap. +#ifdef DOXYGEN + static ProcessedMap *createProcessedMap(const Digraph &g) +#else + static ProcessedMap *createProcessedMap(const Digraph &) +#endif + { + return new ProcessedMap(); + } + + ///The type of the map that indicates which nodes are reached. + + ///The type of the map that indicates which nodes are reached. + ///It must conform to + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + typedef typename Digraph::template NodeMap ReachedMap; + ///Instantiates a \c ReachedMap. + + ///This function instantiates a \ref ReachedMap. + ///\param g is the digraph, to which + ///we would like to define the \ref ReachedMap. + static ReachedMap *createReachedMap(const Digraph &g) + { + return new ReachedMap(g); + } + + ///The type of the map that stores the distances of the nodes. + + ///The type of the map that stores the distances of the nodes. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap DistMap; + ///Instantiates a \c DistMap. + + ///This function instantiates a \ref DistMap. + ///\param g is the digraph, to which we would like to define the + ///\ref DistMap. + static DistMap *createDistMap(const Digraph &g) + { + return new DistMap(g); + } + }; + + ///%DFS algorithm class. + + ///\ingroup search + ///This class provides an efficient implementation of the %DFS algorithm. + /// + ///There is also a \ref dfs() "function-type interface" for the DFS + ///algorithm, which is convenient in the simplier cases and it can be + ///used easier. + /// + ///\tparam GR The type of the digraph the algorithm runs on. + ///The default type is \ref ListDigraph. + ///\tparam TR The traits class that defines various types used by the + ///algorithm. By default, it is \ref DfsDefaultTraits + ///"DfsDefaultTraits". + ///In most cases, this parameter should not be set directly, + ///consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template > +#endif + class Dfs { + public: + + ///The type of the digraph the algorithm runs on. + typedef typename TR::Digraph Digraph; + + ///\brief The type of the map that stores the predecessor arcs of the + ///DFS paths. + typedef typename TR::PredMap PredMap; + ///The type of the map that stores the distances of the nodes. + typedef typename TR::DistMap DistMap; + ///The type of the map that indicates which nodes are reached. + typedef typename TR::ReachedMap ReachedMap; + ///The type of the map that indicates which nodes are processed. + typedef typename TR::ProcessedMap ProcessedMap; + ///The type of the paths. + typedef PredMapPath Path; + + ///The \ref DfsDefaultTraits "traits class" of the algorithm. + typedef TR Traits; + + private: + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + //Pointer to the underlying digraph. + const Digraph *G; + //Pointer to the map of predecessor arcs. + PredMap *_pred; + //Indicates if _pred is locally allocated (true) or not. + bool local_pred; + //Pointer to the map of distances. + DistMap *_dist; + //Indicates if _dist is locally allocated (true) or not. + bool local_dist; + //Pointer to the map of reached status of the nodes. + ReachedMap *_reached; + //Indicates if _reached is locally allocated (true) or not. + bool local_reached; + //Pointer to the map of processed status of the nodes. + ProcessedMap *_processed; + //Indicates if _processed is locally allocated (true) or not. + bool local_processed; + + std::vector _stack; + int _stack_head; + + //Creates the maps if necessary. + void create_maps() + { + if(!_pred) { + local_pred = true; + _pred = Traits::createPredMap(*G); + } + if(!_dist) { + local_dist = true; + _dist = Traits::createDistMap(*G); + } + if(!_reached) { + local_reached = true; + _reached = Traits::createReachedMap(*G); + } + if(!_processed) { + local_processed = true; + _processed = Traits::createProcessedMap(*G); + } + } + + protected: + + Dfs() {} + + public: + + typedef Dfs Create; + + ///\name Named Template Parameters + + ///@{ + + template + struct SetPredMapTraits : public Traits { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) + { + LEMON_ASSERT(false, "PredMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c PredMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c PredMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetPredMap : public Dfs > { + typedef Dfs > Create; + }; + + template + struct SetDistMapTraits : public Traits { + typedef T DistMap; + static DistMap *createDistMap(const Digraph &) + { + LEMON_ASSERT(false, "DistMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c DistMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c DistMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetDistMap : public Dfs< Digraph, SetDistMapTraits > { + typedef Dfs > Create; + }; + + template + struct SetReachedMapTraits : public Traits { + typedef T ReachedMap; + static ReachedMap *createReachedMap(const Digraph &) + { + LEMON_ASSERT(false, "ReachedMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ReachedMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ReachedMap type. + ///It must conform to + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + template + struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits > { + typedef Dfs< Digraph, SetReachedMapTraits > Create; + }; + + template + struct SetProcessedMapTraits : public Traits { + typedef T ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &) + { + LEMON_ASSERT(false, "ProcessedMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits > { + typedef Dfs< Digraph, SetProcessedMapTraits > Create; + }; + + struct SetStandardProcessedMapTraits : public Traits { + typedef typename Digraph::template NodeMap ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &g) + { + return new ProcessedMap(g); + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type to be Digraph::NodeMap. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type to be Digraph::NodeMap. + ///If you don't set it explicitly, it will be automatically allocated. + struct SetStandardProcessedMap : + public Dfs< Digraph, SetStandardProcessedMapTraits > { + typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create; + }; + + ///@} + + public: + + ///Constructor. + + ///Constructor. + ///\param g The digraph the algorithm runs on. + Dfs(const Digraph &g) : + G(&g), + _pred(NULL), local_pred(false), + _dist(NULL), local_dist(false), + _reached(NULL), local_reached(false), + _processed(NULL), local_processed(false) + { } + + ///Destructor. + ~Dfs() + { + if(local_pred) delete _pred; + if(local_dist) delete _dist; + if(local_reached) delete _reached; + if(local_processed) delete _processed; + } + + ///Sets the map that stores the predecessor arcs. + + ///Sets the map that stores the predecessor arcs. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Dfs &predMap(PredMap &m) + { + if(local_pred) { + delete _pred; + local_pred=false; + } + _pred = &m; + return *this; + } + + ///Sets the map that indicates which nodes are reached. + + ///Sets the map that indicates which nodes are reached. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Dfs &reachedMap(ReachedMap &m) + { + if(local_reached) { + delete _reached; + local_reached=false; + } + _reached = &m; + return *this; + } + + ///Sets the map that indicates which nodes are processed. + + ///Sets the map that indicates which nodes are processed. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Dfs &processedMap(ProcessedMap &m) + { + if(local_processed) { + delete _processed; + local_processed=false; + } + _processed = &m; + return *this; + } + + ///Sets the map that stores the distances of the nodes. + + ///Sets the map that stores the distances of the nodes calculated by + ///the algorithm. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Dfs &distMap(DistMap &m) + { + if(local_dist) { + delete _dist; + local_dist=false; + } + _dist = &m; + return *this; + } + + public: + + ///\name Execution Control + ///The simplest way to execute the DFS algorithm is to use one of the + ///member functions called \ref run(Node) "run()".\n + ///If you need better control on the execution, you have to call + ///\ref init() first, then you can add a source node with \ref addSource() + ///and perform the actual computation with \ref start(). + ///This procedure can be repeated if there are nodes that have not + ///been reached. + + ///@{ + + ///\brief Initializes the internal data structures. + /// + ///Initializes the internal data structures. + void init() + { + create_maps(); + _stack.resize(countNodes(*G)); + _stack_head=-1; + for ( NodeIt u(*G) ; u!=INVALID ; ++u ) { + _pred->set(u,INVALID); + _reached->set(u,false); + _processed->set(u,false); + } + } + + ///Adds a new source node. + + ///Adds a new source node to the set of nodes to be processed. + /// + ///\pre The stack must be empty. Otherwise the algorithm gives + ///wrong results. (One of the outgoing arcs of all the source nodes + ///except for the last one will not be visited and distances will + ///also be wrong.) + void addSource(Node s) + { + LEMON_DEBUG(emptyQueue(), "The stack is not empty."); + if(!(*_reached)[s]) + { + _reached->set(s,true); + _pred->set(s,INVALID); + OutArcIt e(*G,s); + if(e!=INVALID) { + _stack[++_stack_head]=e; + _dist->set(s,_stack_head); + } + else { + _processed->set(s,true); + _dist->set(s,0); + } + } + } + + ///Processes the next arc. + + ///Processes the next arc. + /// + ///\return The processed arc. + /// + ///\pre The stack must not be empty. + Arc processNextArc() + { + Node m; + Arc e=_stack[_stack_head]; + if(!(*_reached)[m=G->target(e)]) { + _pred->set(m,e); + _reached->set(m,true); + ++_stack_head; + _stack[_stack_head] = OutArcIt(*G, m); + _dist->set(m,_stack_head); + } + else { + m=G->source(e); + ++_stack[_stack_head]; + } + while(_stack_head>=0 && _stack[_stack_head]==INVALID) { + _processed->set(m,true); + --_stack_head; + if(_stack_head>=0) { + m=G->source(_stack[_stack_head]); + ++_stack[_stack_head]; + } + } + return e; + } + + ///Next arc to be processed. + + ///Next arc to be processed. + /// + ///\return The next arc to be processed or \c INVALID if the stack + ///is empty. + OutArcIt nextArc() const + { + return _stack_head>=0?_stack[_stack_head]:INVALID; + } + + ///Returns \c false if there are nodes to be processed. + + ///Returns \c false if there are nodes to be processed + ///in the queue (stack). + bool emptyQueue() const { return _stack_head<0; } + + ///Returns the number of the nodes to be processed. + + ///Returns the number of the nodes to be processed + ///in the queue (stack). + int queueSize() const { return _stack_head+1; } + + ///Executes the algorithm. + + ///Executes the algorithm. + /// + ///This method runs the %DFS algorithm from the root node + ///in order to compute the DFS path to each node. + /// + /// The algorithm computes + ///- the %DFS tree, + ///- the distance of each node from the root in the %DFS tree. + /// + ///\pre init() must be called and a root node should be + ///added with addSource() before using this function. + /// + ///\note d.start() is just a shortcut of the following code. + ///\code + /// while ( !d.emptyQueue() ) { + /// d.processNextArc(); + /// } + ///\endcode + void start() + { + while ( !emptyQueue() ) processNextArc(); + } + + ///Executes the algorithm until the given target node is reached. + + ///Executes the algorithm until the given target node is reached. + /// + ///This method runs the %DFS algorithm from the root node + ///in order to compute the DFS path to \c t. + /// + ///The algorithm computes + ///- the %DFS path to \c t, + ///- the distance of \c t from the root in the %DFS tree. + /// + ///\pre init() must be called and a root node should be + ///added with addSource() before using this function. + void start(Node t) + { + while ( !emptyQueue() && !(*_reached)[t] ) + processNextArc(); + } + + ///Executes the algorithm until a condition is met. + + ///Executes the algorithm until a condition is met. + /// + ///This method runs the %DFS algorithm from the root node + ///until an arc \c a with am[a] true is found. + /// + ///\param am A \c bool (or convertible) arc map. The algorithm + ///will stop when it reaches an arc \c a with am[a] true. + /// + ///\return The reached arc \c a with am[a] true or + ///\c INVALID if no such arc was found. + /// + ///\pre init() must be called and a root node should be + ///added with addSource() before using this function. + /// + ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map, + ///not a node map. + template + Arc start(const ArcBoolMap &am) + { + while ( !emptyQueue() && !am[_stack[_stack_head]] ) + processNextArc(); + return emptyQueue() ? INVALID : _stack[_stack_head]; + } + + ///Runs the algorithm from the given source node. + + ///This method runs the %DFS algorithm from node \c s + ///in order to compute the DFS path to each node. + /// + ///The algorithm computes + ///- the %DFS tree, + ///- the distance of each node from the root in the %DFS tree. + /// + ///\note d.run(s) is just a shortcut of the following code. + ///\code + /// d.init(); + /// d.addSource(s); + /// d.start(); + ///\endcode + void run(Node s) { + init(); + addSource(s); + start(); + } + + ///Finds the %DFS path between \c s and \c t. + + ///This method runs the %DFS algorithm from node \c s + ///in order to compute the DFS path to node \c t + ///(it stops searching when \c t is processed) + /// + ///\return \c true if \c t is reachable form \c s. + /// + ///\note Apart from the return value, d.run(s,t) is + ///just a shortcut of the following code. + ///\code + /// d.init(); + /// d.addSource(s); + /// d.start(t); + ///\endcode + bool run(Node s,Node t) { + init(); + addSource(s); + start(t); + return reached(t); + } + + ///Runs the algorithm to visit all nodes in the digraph. + + ///This method runs the %DFS algorithm in order to visit all nodes + ///in the digraph. + /// + ///\note d.run() is just a shortcut of the following code. + ///\code + /// d.init(); + /// for (NodeIt n(digraph); n != INVALID; ++n) { + /// if (!d.reached(n)) { + /// d.addSource(n); + /// d.start(); + /// } + /// } + ///\endcode + void run() { + init(); + for (NodeIt it(*G); it != INVALID; ++it) { + if (!reached(it)) { + addSource(it); + start(); + } + } + } + + ///@} + + ///\name Query Functions + ///The results of the DFS algorithm can be obtained using these + ///functions.\n + ///Either \ref run(Node) "run()" or \ref start() should be called + ///before using them. + + ///@{ + + ///The DFS path to the given node. + + ///Returns the DFS path to the given node from the root(s). + /// + ///\warning \c t should be reached from the root(s). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Path path(Node t) const { return Path(*G, *_pred, t); } + + ///The distance of the given node from the root(s). + + ///Returns the distance of the given node from the root(s). + /// + ///\warning If node \c v is not reached from the root(s), then + ///the return value of this function is undefined. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + int dist(Node v) const { return (*_dist)[v]; } + + ///Returns the 'previous arc' of the %DFS tree for the given node. + + ///This function returns the 'previous arc' of the %DFS tree for the + ///node \c v, i.e. it returns the last arc of a %DFS path from a + ///root to \c v. It is \c INVALID if \c v is not reached from the + ///root(s) or if \c v is a root. + /// + ///The %DFS tree used here is equal to the %DFS tree used in + ///\ref predNode() and \ref predMap(). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Arc predArc(Node v) const { return (*_pred)[v];} + + ///Returns the 'previous node' of the %DFS tree for the given node. + + ///This function returns the 'previous node' of the %DFS + ///tree for the node \c v, i.e. it returns the last but one node + ///of a %DFS path from a root to \c v. It is \c INVALID + ///if \c v is not reached from the root(s) or if \c v is a root. + /// + ///The %DFS tree used here is equal to the %DFS tree used in + ///\ref predArc() and \ref predMap(). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID: + G->source((*_pred)[v]); } + + ///\brief Returns a const reference to the node map that stores the + ///distances of the nodes. + /// + ///Returns a const reference to the node map that stores the + ///distances of the nodes calculated by the algorithm. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + const DistMap &distMap() const { return *_dist;} + + ///\brief Returns a const reference to the node map that stores the + ///predecessor arcs. + /// + ///Returns a const reference to the node map that stores the predecessor + ///arcs, which form the DFS tree (forest). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + const PredMap &predMap() const { return *_pred;} + + ///Checks if the given node. node is reached from the root(s). + + ///Returns \c true if \c v is reached from the root(s). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + bool reached(Node v) const { return (*_reached)[v]; } + + ///@} + }; + + ///Default traits class of dfs() function. + + ///Default traits class of dfs() function. + ///\tparam GR Digraph type. + template + struct DfsWizardDefaultTraits + { + ///The type of the digraph the algorithm runs on. + typedef GR Digraph; + + ///\brief The type of the map that stores the predecessor + ///arcs of the %DFS paths. + /// + ///The type of the map that stores the predecessor + ///arcs of the %DFS paths. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap PredMap; + ///Instantiates a PredMap. + + ///This function instantiates a PredMap. + ///\param g is the digraph, to which we would like to define the + ///PredMap. + static PredMap *createPredMap(const Digraph &g) + { + return new PredMap(g); + } + + ///The type of the map that indicates which nodes are processed. + + ///The type of the map that indicates which nodes are processed. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + ///By default, it is a NullMap. + typedef NullMap ProcessedMap; + ///Instantiates a ProcessedMap. + + ///This function instantiates a ProcessedMap. + ///\param g is the digraph, to which + ///we would like to define the ProcessedMap. +#ifdef DOXYGEN + static ProcessedMap *createProcessedMap(const Digraph &g) +#else + static ProcessedMap *createProcessedMap(const Digraph &) +#endif + { + return new ProcessedMap(); + } + + ///The type of the map that indicates which nodes are reached. + + ///The type of the map that indicates which nodes are reached. + ///It must conform to + ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + typedef typename Digraph::template NodeMap ReachedMap; + ///Instantiates a ReachedMap. + + ///This function instantiates a ReachedMap. + ///\param g is the digraph, to which + ///we would like to define the ReachedMap. + static ReachedMap *createReachedMap(const Digraph &g) + { + return new ReachedMap(g); + } + + ///The type of the map that stores the distances of the nodes. + + ///The type of the map that stores the distances of the nodes. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap DistMap; + ///Instantiates a DistMap. + + ///This function instantiates a DistMap. + ///\param g is the digraph, to which we would like to define + ///the DistMap + static DistMap *createDistMap(const Digraph &g) + { + return new DistMap(g); + } + + ///The type of the DFS paths. + + ///The type of the DFS paths. + ///It must conform to the \ref concepts::Path "Path" concept. + typedef lemon::Path Path; + }; + + /// Default traits class used by DfsWizard + + /// Default traits class used by DfsWizard. + /// \tparam GR The type of the digraph. + template + class DfsWizardBase : public DfsWizardDefaultTraits + { + + typedef DfsWizardDefaultTraits Base; + protected: + //The type of the nodes in the digraph. + typedef typename Base::Digraph::Node Node; + + //Pointer to the digraph the algorithm runs on. + void *_g; + //Pointer to the map of reached nodes. + void *_reached; + //Pointer to the map of processed nodes. + void *_processed; + //Pointer to the map of predecessors arcs. + void *_pred; + //Pointer to the map of distances. + void *_dist; + //Pointer to the DFS path to the target node. + void *_path; + //Pointer to the distance of the target node. + int *_di; + + public: + /// Constructor. + + /// This constructor does not require parameters, it initiates + /// all of the attributes to \c 0. + DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0), + _dist(0), _path(0), _di(0) {} + + /// Constructor. + + /// This constructor requires one parameter, + /// others are initiated to \c 0. + /// \param g The digraph the algorithm runs on. + DfsWizardBase(const GR &g) : + _g(reinterpret_cast(const_cast(&g))), + _reached(0), _processed(0), _pred(0), _dist(0), _path(0), _di(0) {} + + }; + + /// Auxiliary class for the function-type interface of DFS algorithm. + + /// This auxiliary class is created to implement the + /// \ref dfs() "function-type interface" of \ref Dfs algorithm. + /// It does not have own \ref run(Node) "run()" method, it uses the + /// functions and features of the plain \ref Dfs. + /// + /// This class should only be used through the \ref dfs() function, + /// which makes it easier to use the algorithm. + /// + /// \tparam TR The traits class that defines various types used by the + /// algorithm. + template + class DfsWizard : public TR + { + typedef TR Base; + + typedef typename TR::Digraph Digraph; + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + typedef typename TR::PredMap PredMap; + typedef typename TR::DistMap DistMap; + typedef typename TR::ReachedMap ReachedMap; + typedef typename TR::ProcessedMap ProcessedMap; + typedef typename TR::Path Path; + + public: + + /// Constructor. + DfsWizard() : TR() {} + + /// Constructor that requires parameters. + + /// Constructor that requires parameters. + /// These parameters will be the default values for the traits class. + /// \param g The digraph the algorithm runs on. + DfsWizard(const Digraph &g) : + TR(g) {} + + ///Copy constructor + DfsWizard(const TR &b) : TR(b) {} + + ~DfsWizard() {} + + ///Runs DFS algorithm from the given source node. + + ///This method runs DFS algorithm from node \c s + ///in order to compute the DFS path to each node. + void run(Node s) + { + Dfs alg(*reinterpret_cast(Base::_g)); + if (Base::_pred) + alg.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) + alg.distMap(*reinterpret_cast(Base::_dist)); + if (Base::_reached) + alg.reachedMap(*reinterpret_cast(Base::_reached)); + if (Base::_processed) + alg.processedMap(*reinterpret_cast(Base::_processed)); + if (s!=INVALID) + alg.run(s); + else + alg.run(); + } + + ///Finds the DFS path between \c s and \c t. + + ///This method runs DFS algorithm from node \c s + ///in order to compute the DFS path to node \c t + ///(it stops searching when \c t is processed). + /// + ///\return \c true if \c t is reachable form \c s. + bool run(Node s, Node t) + { + Dfs alg(*reinterpret_cast(Base::_g)); + if (Base::_pred) + alg.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) + alg.distMap(*reinterpret_cast(Base::_dist)); + if (Base::_reached) + alg.reachedMap(*reinterpret_cast(Base::_reached)); + if (Base::_processed) + alg.processedMap(*reinterpret_cast(Base::_processed)); + alg.run(s,t); + if (Base::_path) + *reinterpret_cast(Base::_path) = alg.path(t); + if (Base::_di) + *Base::_di = alg.dist(t); + return alg.reached(t); + } + + ///Runs DFS algorithm to visit all nodes in the digraph. + + ///This method runs DFS algorithm in order to visit all nodes + ///in the digraph. + void run() + { + run(INVALID); + } + + template + struct SetPredMapBase : public Base { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) { return 0; }; + SetPredMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the predecessor map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that stores the predecessor arcs of the nodes. + template + DfsWizard > predMap(const T &t) + { + Base::_pred=reinterpret_cast(const_cast(&t)); + return DfsWizard >(*this); + } + + template + struct SetReachedMapBase : public Base { + typedef T ReachedMap; + static ReachedMap *createReachedMap(const Digraph &) { return 0; }; + SetReachedMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the reached map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that indicates which nodes are reached. + template + DfsWizard > reachedMap(const T &t) + { + Base::_reached=reinterpret_cast(const_cast(&t)); + return DfsWizard >(*this); + } + + template + struct SetDistMapBase : public Base { + typedef T DistMap; + static DistMap *createDistMap(const Digraph &) { return 0; }; + SetDistMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the distance map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that stores the distances of the nodes calculated + ///by the algorithm. + template + DfsWizard > distMap(const T &t) + { + Base::_dist=reinterpret_cast(const_cast(&t)); + return DfsWizard >(*this); + } + + template + struct SetProcessedMapBase : public Base { + typedef T ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &) { return 0; }; + SetProcessedMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-func-param "Named parameter" for setting + ///the processed map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that indicates which nodes are processed. + template + DfsWizard > processedMap(const T &t) + { + Base::_processed=reinterpret_cast(const_cast(&t)); + return DfsWizard >(*this); + } + + template + struct SetPathBase : public Base { + typedef T Path; + SetPathBase(const TR &b) : TR(b) {} + }; + ///\brief \ref named-func-param "Named parameter" + ///for getting the DFS path to the target node. + /// + ///\ref named-func-param "Named parameter" + ///for getting the DFS path to the target node. + template + DfsWizard > path(const T &t) + { + Base::_path=reinterpret_cast(const_cast(&t)); + return DfsWizard >(*this); + } + + ///\brief \ref named-func-param "Named parameter" + ///for getting the distance of the target node. + /// + ///\ref named-func-param "Named parameter" + ///for getting the distance of the target node. + DfsWizard dist(const int &d) + { + Base::_di=const_cast(&d); + return *this; + } + + }; + + ///Function-type interface for DFS algorithm. + + ///\ingroup search + ///Function-type interface for DFS algorithm. + /// + ///This function also has several \ref named-func-param "named parameters", + ///they are declared as the members of class \ref DfsWizard. + ///The following examples show how to use these parameters. + ///\code + /// // Compute the DFS tree + /// dfs(g).predMap(preds).distMap(dists).run(s); + /// + /// // Compute the DFS path from s to t + /// bool reached = dfs(g).path(p).dist(d).run(s,t); + ///\endcode + ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()" + ///to the end of the parameter list. + ///\sa DfsWizard + ///\sa Dfs + template + DfsWizard > + dfs(const GR &digraph) + { + return DfsWizard >(digraph); + } + +#ifdef DOXYGEN + /// \brief Visitor class for DFS. + /// + /// This class defines the interface of the DfsVisit events, and + /// it could be the base of a real visitor class. + template + struct DfsVisitor { + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Node Node; + /// \brief Called for the source node of the DFS. + /// + /// This function is called for the source node of the DFS. + void start(const Node& node) {} + /// \brief Called when the source node is leaved. + /// + /// This function is called when the source node is leaved. + void stop(const Node& node) {} + /// \brief Called when a node is reached first time. + /// + /// This function is called when a node is reached first time. + void reach(const Node& node) {} + /// \brief Called when an arc reaches a new node. + /// + /// This function is called when the DFS finds an arc whose target node + /// is not reached yet. + void discover(const Arc& arc) {} + /// \brief Called when an arc is examined but its target node is + /// already discovered. + /// + /// This function is called when an arc is examined but its target node is + /// already discovered. + void examine(const Arc& arc) {} + /// \brief Called when the DFS steps back from a node. + /// + /// This function is called when the DFS steps back from a node. + void leave(const Node& node) {} + /// \brief Called when the DFS steps back on an arc. + /// + /// This function is called when the DFS steps back on an arc. + void backtrack(const Arc& arc) {} + }; +#else + template + struct DfsVisitor { + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::Node Node; + void start(const Node&) {} + void stop(const Node&) {} + void reach(const Node&) {} + void discover(const Arc&) {} + void examine(const Arc&) {} + void leave(const Node&) {} + void backtrack(const Arc&) {} + + template + struct Constraints { + void constraints() { + Arc arc; + Node node; + visitor.start(node); + visitor.stop(arc); + visitor.reach(node); + visitor.discover(arc); + visitor.examine(arc); + visitor.leave(node); + visitor.backtrack(arc); + } + _Visitor& visitor; + }; + }; +#endif + + /// \brief Default traits class of DfsVisit class. + /// + /// Default traits class of DfsVisit class. + /// \tparam _Digraph The type of the digraph the algorithm runs on. + template + struct DfsVisitDefaultTraits { + + /// \brief The type of the digraph the algorithm runs on. + typedef GR Digraph; + + /// \brief The type of the map that indicates which nodes are reached. + /// + /// The type of the map that indicates which nodes are reached. + /// It must conform to the + /// \ref concepts::ReadWriteMap "ReadWriteMap" concept. + typedef typename Digraph::template NodeMap ReachedMap; + + /// \brief Instantiates a ReachedMap. + /// + /// This function instantiates a ReachedMap. + /// \param digraph is the digraph, to which + /// we would like to define the ReachedMap. + static ReachedMap *createReachedMap(const Digraph &digraph) { + return new ReachedMap(digraph); + } + + }; + + /// \ingroup search + /// + /// \brief DFS algorithm class with visitor interface. + /// + /// This class provides an efficient implementation of the DFS algorithm + /// with visitor interface. + /// + /// The DfsVisit class provides an alternative interface to the Dfs + /// class. It works with callback mechanism, the DfsVisit object calls + /// the member functions of the \c Visitor class on every DFS event. + /// + /// This interface of the DFS algorithm should be used in special cases + /// when extra actions have to be performed in connection with certain + /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs() + /// instead. + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// The default type is \ref ListDigraph. + /// The value of GR is not used directly by \ref DfsVisit, + /// it is only passed to \ref DfsVisitDefaultTraits. + /// \tparam VS The Visitor type that is used by the algorithm. + /// \ref DfsVisitor "DfsVisitor" is an empty visitor, which + /// does not observe the DFS events. If you want to observe the DFS + /// events, you should implement your own visitor class. + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref DfsVisitDefaultTraits + /// "DfsVisitDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template , + typename TR = DfsVisitDefaultTraits > +#endif + class DfsVisit { + public: + + ///The traits class. + typedef TR Traits; + + ///The type of the digraph the algorithm runs on. + typedef typename Traits::Digraph Digraph; + + ///The visitor type used by the algorithm. + typedef VS Visitor; + + ///The type of the map that indicates which nodes are reached. + typedef typename Traits::ReachedMap ReachedMap; + + private: + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + //Pointer to the underlying digraph. + const Digraph *_digraph; + //Pointer to the visitor object. + Visitor *_visitor; + //Pointer to the map of reached status of the nodes. + ReachedMap *_reached; + //Indicates if _reached is locally allocated (true) or not. + bool local_reached; + + std::vector _stack; + int _stack_head; + + //Creates the maps if necessary. + void create_maps() { + if(!_reached) { + local_reached = true; + _reached = Traits::createReachedMap(*_digraph); + } + } + + protected: + + DfsVisit() {} + + public: + + typedef DfsVisit Create; + + /// \name Named Template Parameters + + ///@{ + template + struct SetReachedMapTraits : public Traits { + typedef T ReachedMap; + static ReachedMap *createReachedMap(const Digraph &digraph) { + LEMON_ASSERT(false, "ReachedMap is not initialized"); + return 0; // ignore warnings + } + }; + /// \brief \ref named-templ-param "Named parameter" for setting + /// ReachedMap type. + /// + /// \ref named-templ-param "Named parameter" for setting ReachedMap type. + template + struct SetReachedMap : public DfsVisit< Digraph, Visitor, + SetReachedMapTraits > { + typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits > Create; + }; + ///@} + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// + /// \param digraph The digraph the algorithm runs on. + /// \param visitor The visitor object of the algorithm. + DfsVisit(const Digraph& digraph, Visitor& visitor) + : _digraph(&digraph), _visitor(&visitor), + _reached(0), local_reached(false) {} + + /// \brief Destructor. + ~DfsVisit() { + if(local_reached) delete _reached; + } + + /// \brief Sets the map that indicates which nodes are reached. + /// + /// Sets the map that indicates which nodes are reached. + /// If you don't use this function before calling \ref run(Node) "run()" + /// or \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated map, + /// of course. + /// \return (*this) + DfsVisit &reachedMap(ReachedMap &m) { + if(local_reached) { + delete _reached; + local_reached=false; + } + _reached = &m; + return *this; + } + + public: + + /// \name Execution Control + /// The simplest way to execute the DFS algorithm is to use one of the + /// member functions called \ref run(Node) "run()".\n + /// If you need better control on the execution, you have to call + /// \ref init() first, then you can add a source node with \ref addSource() + /// and perform the actual computation with \ref start(). + /// This procedure can be repeated if there are nodes that have not + /// been reached. + + /// @{ + + /// \brief Initializes the internal data structures. + /// + /// Initializes the internal data structures. + void init() { + create_maps(); + _stack.resize(countNodes(*_digraph)); + _stack_head = -1; + for (NodeIt u(*_digraph) ; u != INVALID ; ++u) { + _reached->set(u, false); + } + } + + /// \brief Adds a new source node. + /// + /// Adds a new source node to the set of nodes to be processed. + /// + /// \pre The stack must be empty. Otherwise the algorithm gives + /// wrong results. (One of the outgoing arcs of all the source nodes + /// except for the last one will not be visited and distances will + /// also be wrong.) + void addSource(Node s) + { + LEMON_DEBUG(emptyQueue(), "The stack is not empty."); + if(!(*_reached)[s]) { + _reached->set(s,true); + _visitor->start(s); + _visitor->reach(s); + Arc e; + _digraph->firstOut(e, s); + if (e != INVALID) { + _stack[++_stack_head] = e; + } else { + _visitor->leave(s); + _visitor->stop(s); + } + } + } + + /// \brief Processes the next arc. + /// + /// Processes the next arc. + /// + /// \return The processed arc. + /// + /// \pre The stack must not be empty. + Arc processNextArc() { + Arc e = _stack[_stack_head]; + Node m = _digraph->target(e); + if(!(*_reached)[m]) { + _visitor->discover(e); + _visitor->reach(m); + _reached->set(m, true); + _digraph->firstOut(_stack[++_stack_head], m); + } else { + _visitor->examine(e); + m = _digraph->source(e); + _digraph->nextOut(_stack[_stack_head]); + } + while (_stack_head>=0 && _stack[_stack_head] == INVALID) { + _visitor->leave(m); + --_stack_head; + if (_stack_head >= 0) { + _visitor->backtrack(_stack[_stack_head]); + m = _digraph->source(_stack[_stack_head]); + _digraph->nextOut(_stack[_stack_head]); + } else { + _visitor->stop(m); + } + } + return e; + } + + /// \brief Next arc to be processed. + /// + /// Next arc to be processed. + /// + /// \return The next arc to be processed or INVALID if the stack is + /// empty. + Arc nextArc() const { + return _stack_head >= 0 ? _stack[_stack_head] : INVALID; + } + + /// \brief Returns \c false if there are nodes + /// to be processed. + /// + /// Returns \c false if there are nodes + /// to be processed in the queue (stack). + bool emptyQueue() const { return _stack_head < 0; } + + /// \brief Returns the number of the nodes to be processed. + /// + /// Returns the number of the nodes to be processed in the queue (stack). + int queueSize() const { return _stack_head + 1; } + + /// \brief Executes the algorithm. + /// + /// Executes the algorithm. + /// + /// This method runs the %DFS algorithm from the root node + /// in order to compute the %DFS path to each node. + /// + /// The algorithm computes + /// - the %DFS tree, + /// - the distance of each node from the root in the %DFS tree. + /// + /// \pre init() must be called and a root node should be + /// added with addSource() before using this function. + /// + /// \note d.start() is just a shortcut of the following code. + /// \code + /// while ( !d.emptyQueue() ) { + /// d.processNextArc(); + /// } + /// \endcode + void start() { + while ( !emptyQueue() ) processNextArc(); + } + + /// \brief Executes the algorithm until the given target node is reached. + /// + /// Executes the algorithm until the given target node is reached. + /// + /// This method runs the %DFS algorithm from the root node + /// in order to compute the DFS path to \c t. + /// + /// The algorithm computes + /// - the %DFS path to \c t, + /// - the distance of \c t from the root in the %DFS tree. + /// + /// \pre init() must be called and a root node should be added + /// with addSource() before using this function. + void start(Node t) { + while ( !emptyQueue() && !(*_reached)[t] ) + processNextArc(); + } + + /// \brief Executes the algorithm until a condition is met. + /// + /// Executes the algorithm until a condition is met. + /// + /// This method runs the %DFS algorithm from the root node + /// until an arc \c a with am[a] true is found. + /// + /// \param am A \c bool (or convertible) arc map. The algorithm + /// will stop when it reaches an arc \c a with am[a] true. + /// + /// \return The reached arc \c a with am[a] true or + /// \c INVALID if no such arc was found. + /// + /// \pre init() must be called and a root node should be added + /// with addSource() before using this function. + /// + /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map, + /// not a node map. + template + Arc start(const AM &am) { + while ( !emptyQueue() && !am[_stack[_stack_head]] ) + processNextArc(); + return emptyQueue() ? INVALID : _stack[_stack_head]; + } + + /// \brief Runs the algorithm from the given source node. + /// + /// This method runs the %DFS algorithm from node \c s. + /// in order to compute the DFS path to each node. + /// + /// The algorithm computes + /// - the %DFS tree, + /// - the distance of each node from the root in the %DFS tree. + /// + /// \note d.run(s) is just a shortcut of the following code. + ///\code + /// d.init(); + /// d.addSource(s); + /// d.start(); + ///\endcode + void run(Node s) { + init(); + addSource(s); + start(); + } + + /// \brief Finds the %DFS path between \c s and \c t. + + /// This method runs the %DFS algorithm from node \c s + /// in order to compute the DFS path to node \c t + /// (it stops searching when \c t is processed). + /// + /// \return \c true if \c t is reachable form \c s. + /// + /// \note Apart from the return value, d.run(s,t) is + /// just a shortcut of the following code. + ///\code + /// d.init(); + /// d.addSource(s); + /// d.start(t); + ///\endcode + bool run(Node s,Node t) { + init(); + addSource(s); + start(t); + return reached(t); + } + + /// \brief Runs the algorithm to visit all nodes in the digraph. + + /// This method runs the %DFS algorithm in order to visit all nodes + /// in the digraph. + /// + /// \note d.run() is just a shortcut of the following code. + ///\code + /// d.init(); + /// for (NodeIt n(digraph); n != INVALID; ++n) { + /// if (!d.reached(n)) { + /// d.addSource(n); + /// d.start(); + /// } + /// } + ///\endcode + void run() { + init(); + for (NodeIt it(*_digraph); it != INVALID; ++it) { + if (!reached(it)) { + addSource(it); + start(); + } + } + } + + ///@} + + /// \name Query Functions + /// The results of the DFS algorithm can be obtained using these + /// functions.\n + /// Either \ref run(Node) "run()" or \ref start() should be called + /// before using them. + + ///@{ + + /// \brief Checks if the given node is reached from the root(s). + /// + /// Returns \c true if \c v is reached from the root(s). + /// + /// \pre Either \ref run(Node) "run()" or \ref init() + /// must be called before using this function. + bool reached(Node v) const { return (*_reached)[v]; } + + ///@} + + }; + +} //END OF NAMESPACE LEMON + +#endif diff --git a/lemon/lemon/dheap.h b/lemon/lemon/dheap.h new file mode 100644 index 0000000..a3ab625 --- /dev/null +++ b/lemon/lemon/dheap.h @@ -0,0 +1,352 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_DHEAP_H +#define LEMON_DHEAP_H + +///\ingroup heaps +///\file +///\brief D-ary heap implementation. + +#include +#include +#include + +namespace lemon { + + /// \ingroup heaps + /// + ///\brief D-ary heap data structure. + /// + /// This class implements the \e D-ary \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". + /// + /// The \ref DHeap "D-ary heap" is a generalization of the + /// \ref BinHeap "binary heap" structure, its nodes have at most + /// \c D children, instead of two. + /// \ref BinHeap and \ref QuadHeap are specialized implementations + /// of this structure for D=2 and D=4, respectively. + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam D The degree of the heap, each node have at most \e D + /// children. The default is 16. Powers of two are suggested to use + /// so that the multiplications and divisions needed to traverse the + /// nodes of the heap could be performed faster. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. + /// + ///\sa BinHeap + ///\sa FouraryHeap +#ifdef DOXYGEN + template +#else + template > +#endif + class DHeap { + public: + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + /// Functor type for comparing the priorities. + typedef CMP Compare; + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + private: + std::vector _data; + Compare _comp; + ItemIntMap &_iim; + + public: + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit DHeap(ItemIntMap &map) : _iim(map) {} + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + DHeap(ItemIntMap &map, const Compare &comp) + : _iim(map), _comp(comp) {} + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { _data.clear(); } + + private: + int parent(int i) { return (i-1)/D; } + int firstChild(int i) { return D*i+1; } + + bool less(const Pair &p1, const Pair &p2) const { + return _comp(p1.second, p2.second); + } + + void bubbleUp(int hole, Pair p) { + int par = parent(hole); + while( hole>0 && less(p,_data[par]) ) { + move(_data[par],hole); + hole = par; + par = parent(hole); + } + move(p, hole); + } + + void bubbleDown(int hole, Pair p, int length) { + if( length>1 ) { + int child = firstChild(hole); + while( child+D<=length ) { + int min=child; + for (int i=1; i0) bubbleDown(0, _data[n], n); + _data.pop_back(); + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. + void erase(const Item &i) { + int h = _iim[i]; + int n = _data.size()-1; + _iim.set(_data[h].first, POST_HEAP); + if( h=0) s=0; + return State(s); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) erase(i); + _iim[i] = st; + break; + case IN_HEAP: + break; + } + } + + /// \brief Replace an item in the heap. + /// + /// This function replaces item \c i with item \c j. + /// Item \c i must be in the heap, while \c j must be out of the heap. + /// After calling this method, item \c i will be out of the + /// heap and \c j will be in the heap with the same prioriority + /// as item \c i had before. + void replace(const Item& i, const Item& j) { + int idx=_iim[i]; + _iim.set(i, _iim[j]); + _iim.set(j, idx); + _data[idx].first=j; + } + + }; // class DHeap + +} // namespace lemon + +#endif // LEMON_DHEAP_H diff --git a/lemon/lemon/dijkstra.h b/lemon/lemon/dijkstra.h new file mode 100644 index 0000000..02b0d6d --- /dev/null +++ b/lemon/lemon/dijkstra.h @@ -0,0 +1,1303 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_DIJKSTRA_H +#define LEMON_DIJKSTRA_H + +///\ingroup shortest_path +///\file +///\brief Dijkstra algorithm. + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \brief Default operation traits for the Dijkstra algorithm class. + /// + /// This operation traits class defines all computational operations and + /// constants which are used in the Dijkstra algorithm. + template + struct DijkstraDefaultOperationTraits { + /// \e + typedef V Value; + /// \brief Gives back the zero value of the type. + static Value zero() { + return static_cast(0); + } + /// \brief Gives back the sum of the given two elements. + static Value plus(const Value& left, const Value& right) { + return left + right; + } + /// \brief Gives back true only if the first value is less than the second. + static bool less(const Value& left, const Value& right) { + return left < right; + } + }; + + ///Default traits class of Dijkstra class. + + ///Default traits class of Dijkstra class. + ///\tparam GR The type of the digraph. + ///\tparam LEN The type of the length map. + template + struct DijkstraDefaultTraits + { + ///The type of the digraph the algorithm runs on. + typedef GR Digraph; + + ///The type of the map that stores the arc lengths. + + ///The type of the map that stores the arc lengths. + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept. + typedef LEN LengthMap; + ///The type of the arc lengths. + typedef typename LEN::Value Value; + + /// Operation traits for %Dijkstra algorithm. + + /// This class defines the operations that are used in the algorithm. + /// \see DijkstraDefaultOperationTraits + typedef DijkstraDefaultOperationTraits OperationTraits; + + /// The cross reference type used by the heap. + + /// The cross reference type used by the heap. + /// Usually it is \c Digraph::NodeMap. + typedef typename Digraph::template NodeMap HeapCrossRef; + ///Instantiates a \c HeapCrossRef. + + ///This function instantiates a \ref HeapCrossRef. + /// \param g is the digraph, to which we would like to define the + /// \ref HeapCrossRef. + static HeapCrossRef *createHeapCrossRef(const Digraph &g) + { + return new HeapCrossRef(g); + } + + ///The heap type used by the %Dijkstra algorithm. + + ///The heap type used by the Dijkstra algorithm. + /// + ///\sa BinHeap + ///\sa Dijkstra + typedef BinHeap > Heap; + ///Instantiates a \c Heap. + + ///This function instantiates a \ref Heap. + static Heap *createHeap(HeapCrossRef& r) + { + return new Heap(r); + } + + ///\brief The type of the map that stores the predecessor + ///arcs of the shortest paths. + /// + ///The type of the map that stores the predecessor + ///arcs of the shortest paths. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap PredMap; + ///Instantiates a \c PredMap. + + ///This function instantiates a \ref PredMap. + ///\param g is the digraph, to which we would like to define the + ///\ref PredMap. + static PredMap *createPredMap(const Digraph &g) + { + return new PredMap(g); + } + + ///The type of the map that indicates which nodes are processed. + + ///The type of the map that indicates which nodes are processed. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + ///By default, it is a NullMap. + typedef NullMap ProcessedMap; + ///Instantiates a \c ProcessedMap. + + ///This function instantiates a \ref ProcessedMap. + ///\param g is the digraph, to which + ///we would like to define the \ref ProcessedMap. +#ifdef DOXYGEN + static ProcessedMap *createProcessedMap(const Digraph &g) +#else + static ProcessedMap *createProcessedMap(const Digraph &) +#endif + { + return new ProcessedMap(); + } + + ///The type of the map that stores the distances of the nodes. + + ///The type of the map that stores the distances of the nodes. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap DistMap; + ///Instantiates a \c DistMap. + + ///This function instantiates a \ref DistMap. + ///\param g is the digraph, to which we would like to define + ///the \ref DistMap. + static DistMap *createDistMap(const Digraph &g) + { + return new DistMap(g); + } + }; + + ///%Dijkstra algorithm class. + + /// \ingroup shortest_path + ///This class provides an efficient implementation of the %Dijkstra algorithm. + /// + ///The %Dijkstra algorithm solves the single-source shortest path problem + ///when all arc lengths are non-negative. If there are negative lengths, + ///the BellmanFord algorithm should be used instead. + /// + ///The arc lengths are passed to the algorithm using a + ///\ref concepts::ReadMap "ReadMap", + ///so it is easy to change it to any kind of length. + ///The type of the length is determined by the + ///\ref concepts::ReadMap::Value "Value" of the length map. + ///It is also possible to change the underlying priority heap. + /// + ///There is also a \ref dijkstra() "function-type interface" for the + ///%Dijkstra algorithm, which is convenient in the simplier cases and + ///it can be used easier. + /// + ///\tparam GR The type of the digraph the algorithm runs on. + ///The default type is \ref ListDigraph. + ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies + ///the lengths of the arcs. + ///It is read once for each arc, so the map may involve in + ///relatively time consuming process to compute the arc lengths if + ///it is necessary. The default map type is \ref + ///concepts::Digraph::ArcMap "GR::ArcMap". + ///\tparam TR The traits class that defines various types used by the + ///algorithm. By default, it is \ref DijkstraDefaultTraits + ///"DijkstraDefaultTraits". + ///In most cases, this parameter should not be set directly, + ///consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template , + typename TR=DijkstraDefaultTraits > +#endif + class Dijkstra { + public: + + ///The type of the digraph the algorithm runs on. + typedef typename TR::Digraph Digraph; + + ///The type of the arc lengths. + typedef typename TR::Value Value; + ///The type of the map that stores the arc lengths. + typedef typename TR::LengthMap LengthMap; + ///\brief The type of the map that stores the predecessor arcs of the + ///shortest paths. + typedef typename TR::PredMap PredMap; + ///The type of the map that stores the distances of the nodes. + typedef typename TR::DistMap DistMap; + ///The type of the map that indicates which nodes are processed. + typedef typename TR::ProcessedMap ProcessedMap; + ///The type of the paths. + typedef PredMapPath Path; + ///The cross reference type used for the current heap. + typedef typename TR::HeapCrossRef HeapCrossRef; + ///The heap type used by the algorithm. + typedef typename TR::Heap Heap; + ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class" + ///of the algorithm. + typedef typename TR::OperationTraits OperationTraits; + + ///The \ref DijkstraDefaultTraits "traits class" of the algorithm. + typedef TR Traits; + + private: + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + //Pointer to the underlying digraph. + const Digraph *G; + //Pointer to the length map. + const LengthMap *_length; + //Pointer to the map of predecessors arcs. + PredMap *_pred; + //Indicates if _pred is locally allocated (true) or not. + bool local_pred; + //Pointer to the map of distances. + DistMap *_dist; + //Indicates if _dist is locally allocated (true) or not. + bool local_dist; + //Pointer to the map of processed status of the nodes. + ProcessedMap *_processed; + //Indicates if _processed is locally allocated (true) or not. + bool local_processed; + //Pointer to the heap cross references. + HeapCrossRef *_heap_cross_ref; + //Indicates if _heap_cross_ref is locally allocated (true) or not. + bool local_heap_cross_ref; + //Pointer to the heap. + Heap *_heap; + //Indicates if _heap is locally allocated (true) or not. + bool local_heap; + + //Creates the maps if necessary. + void create_maps() + { + if(!_pred) { + local_pred = true; + _pred = Traits::createPredMap(*G); + } + if(!_dist) { + local_dist = true; + _dist = Traits::createDistMap(*G); + } + if(!_processed) { + local_processed = true; + _processed = Traits::createProcessedMap(*G); + } + if (!_heap_cross_ref) { + local_heap_cross_ref = true; + _heap_cross_ref = Traits::createHeapCrossRef(*G); + } + if (!_heap) { + local_heap = true; + _heap = Traits::createHeap(*_heap_cross_ref); + } + } + + public: + + typedef Dijkstra Create; + + ///\name Named Template Parameters + + ///@{ + + template + struct SetPredMapTraits : public Traits { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) + { + LEMON_ASSERT(false, "PredMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c PredMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c PredMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetPredMap + : public Dijkstra< Digraph, LengthMap, SetPredMapTraits > { + typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits > Create; + }; + + template + struct SetDistMapTraits : public Traits { + typedef T DistMap; + static DistMap *createDistMap(const Digraph &) + { + LEMON_ASSERT(false, "DistMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c DistMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c DistMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetDistMap + : public Dijkstra< Digraph, LengthMap, SetDistMapTraits > { + typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits > Create; + }; + + template + struct SetProcessedMapTraits : public Traits { + typedef T ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &) + { + LEMON_ASSERT(false, "ProcessedMap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + struct SetProcessedMap + : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits > { + typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits > Create; + }; + + struct SetStandardProcessedMapTraits : public Traits { + typedef typename Digraph::template NodeMap ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &g) + { + return new ProcessedMap(g); + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type to be Digraph::NodeMap. + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c ProcessedMap type to be Digraph::NodeMap. + ///If you don't set it explicitly, it will be automatically allocated. + struct SetStandardProcessedMap + : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > { + typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > + Create; + }; + + template + struct SetHeapTraits : public Traits { + typedef CR HeapCrossRef; + typedef H Heap; + static HeapCrossRef *createHeapCrossRef(const Digraph &) { + LEMON_ASSERT(false, "HeapCrossRef is not initialized"); + return 0; // ignore warnings + } + static Heap *createHeap(HeapCrossRef &) + { + LEMON_ASSERT(false, "Heap is not initialized"); + return 0; // ignore warnings + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///heap and cross reference types + /// + ///\ref named-templ-param "Named parameter" for setting heap and cross + ///reference types. If this named parameter is used, then external + ///heap and cross reference objects must be passed to the algorithm + ///using the \ref heap() function before calling \ref run(Node) "run()" + ///or \ref init(). + ///\sa SetStandardHeap + template > + struct SetHeap + : public Dijkstra< Digraph, LengthMap, SetHeapTraits > { + typedef Dijkstra< Digraph, LengthMap, SetHeapTraits > Create; + }; + + template + struct SetStandardHeapTraits : public Traits { + typedef CR HeapCrossRef; + typedef H Heap; + static HeapCrossRef *createHeapCrossRef(const Digraph &G) { + return new HeapCrossRef(G); + } + static Heap *createHeap(HeapCrossRef &R) + { + return new Heap(R); + } + }; + ///\brief \ref named-templ-param "Named parameter" for setting + ///heap and cross reference types with automatic allocation + /// + ///\ref named-templ-param "Named parameter" for setting heap and cross + ///reference types with automatic allocation. + ///They should have standard constructor interfaces to be able to + ///automatically created by the algorithm (i.e. the digraph should be + ///passed to the constructor of the cross reference and the cross + ///reference should be passed to the constructor of the heap). + ///However, external heap and cross reference objects could also be + ///passed to the algorithm using the \ref heap() function before + ///calling \ref run(Node) "run()" or \ref init(). + ///\sa SetHeap + template > + struct SetStandardHeap + : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits > { + typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits > + Create; + }; + + template + struct SetOperationTraitsTraits : public Traits { + typedef T OperationTraits; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + ///\c OperationTraits type + /// + ///\ref named-templ-param "Named parameter" for setting + ///\c OperationTraits type. + /// For more information, see \ref DijkstraDefaultOperationTraits. + template + struct SetOperationTraits + : public Dijkstra > { + typedef Dijkstra > + Create; + }; + + ///@} + + protected: + + Dijkstra() {} + + public: + + ///Constructor. + + ///Constructor. + ///\param g The digraph the algorithm runs on. + ///\param length The length map used by the algorithm. + Dijkstra(const Digraph& g, const LengthMap& length) : + G(&g), _length(&length), + _pred(NULL), local_pred(false), + _dist(NULL), local_dist(false), + _processed(NULL), local_processed(false), + _heap_cross_ref(NULL), local_heap_cross_ref(false), + _heap(NULL), local_heap(false) + { } + + ///Destructor. + ~Dijkstra() + { + if(local_pred) delete _pred; + if(local_dist) delete _dist; + if(local_processed) delete _processed; + if(local_heap_cross_ref) delete _heap_cross_ref; + if(local_heap) delete _heap; + } + + ///Sets the length map. + + ///Sets the length map. + ///\return (*this) + Dijkstra &lengthMap(const LengthMap &m) + { + _length = &m; + return *this; + } + + ///Sets the map that stores the predecessor arcs. + + ///Sets the map that stores the predecessor arcs. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Dijkstra &predMap(PredMap &m) + { + if(local_pred) { + delete _pred; + local_pred=false; + } + _pred = &m; + return *this; + } + + ///Sets the map that indicates which nodes are processed. + + ///Sets the map that indicates which nodes are processed. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Dijkstra &processedMap(ProcessedMap &m) + { + if(local_processed) { + delete _processed; + local_processed=false; + } + _processed = &m; + return *this; + } + + ///Sets the map that stores the distances of the nodes. + + ///Sets the map that stores the distances of the nodes calculated by the + ///algorithm. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), an instance will be allocated automatically. + ///The destructor deallocates this automatically allocated map, + ///of course. + ///\return (*this) + Dijkstra &distMap(DistMap &m) + { + if(local_dist) { + delete _dist; + local_dist=false; + } + _dist = &m; + return *this; + } + + ///Sets the heap and the cross reference used by algorithm. + + ///Sets the heap and the cross reference used by algorithm. + ///If you don't use this function before calling \ref run(Node) "run()" + ///or \ref init(), heap and cross reference instances will be + ///allocated automatically. + ///The destructor deallocates these automatically allocated objects, + ///of course. + ///\return (*this) + Dijkstra &heap(Heap& hp, HeapCrossRef &cr) + { + if(local_heap_cross_ref) { + delete _heap_cross_ref; + local_heap_cross_ref=false; + } + _heap_cross_ref = &cr; + if(local_heap) { + delete _heap; + local_heap=false; + } + _heap = &hp; + return *this; + } + + private: + + void finalizeNodeData(Node v,Value dst) + { + _processed->set(v,true); + _dist->set(v, dst); + } + + public: + + ///\name Execution Control + ///The simplest way to execute the %Dijkstra algorithm is to use + ///one of the member functions called \ref run(Node) "run()".\n + ///If you need better control on the execution, you have to call + ///\ref init() first, then you can add several source nodes with + ///\ref addSource(). Finally the actual path computation can be + ///performed with one of the \ref start() functions. + + ///@{ + + ///\brief Initializes the internal data structures. + /// + ///Initializes the internal data structures. + void init() + { + create_maps(); + _heap->clear(); + for ( NodeIt u(*G) ; u!=INVALID ; ++u ) { + _pred->set(u,INVALID); + _processed->set(u,false); + _heap_cross_ref->set(u,Heap::PRE_HEAP); + } + } + + ///Adds a new source node. + + ///Adds a new source node to the priority heap. + ///The optional second parameter is the initial distance of the node. + /// + ///The function checks if the node has already been added to the heap and + ///it is pushed to the heap only if either it was not in the heap + ///or the shortest path found till then is shorter than \c dst. + void addSource(Node s,Value dst=OperationTraits::zero()) + { + if(_heap->state(s) != Heap::IN_HEAP) { + _heap->push(s,dst); + } else if(OperationTraits::less((*_heap)[s], dst)) { + _heap->set(s,dst); + _pred->set(s,INVALID); + } + } + + ///Processes the next node in the priority heap + + ///Processes the next node in the priority heap. + /// + ///\return The processed node. + /// + ///\warning The priority heap must not be empty. + Node processNextNode() + { + Node v=_heap->top(); + Value oldvalue=_heap->prio(); + _heap->pop(); + finalizeNodeData(v,oldvalue); + + for(OutArcIt e(*G,v); e!=INVALID; ++e) { + Node w=G->target(e); + switch(_heap->state(w)) { + case Heap::PRE_HEAP: + _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e])); + _pred->set(w,e); + break; + case Heap::IN_HEAP: + { + Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]); + if ( OperationTraits::less(newvalue, (*_heap)[w]) ) { + _heap->decrease(w, newvalue); + _pred->set(w,e); + } + } + break; + case Heap::POST_HEAP: + break; + } + } + return v; + } + + ///The next node to be processed. + + ///Returns the next node to be processed or \c INVALID if the + ///priority heap is empty. + Node nextNode() const + { + return !_heap->empty()?_heap->top():INVALID; + } + + ///Returns \c false if there are nodes to be processed. + + ///Returns \c false if there are nodes to be processed + ///in the priority heap. + bool emptyQueue() const { return _heap->empty(); } + + ///Returns the number of the nodes to be processed. + + ///Returns the number of the nodes to be processed + ///in the priority heap. + int queueSize() const { return _heap->size(); } + + ///Executes the algorithm. + + ///Executes the algorithm. + /// + ///This method runs the %Dijkstra algorithm from the root node(s) + ///in order to compute the shortest path to each node. + /// + ///The algorithm computes + ///- the shortest path tree (forest), + ///- the distance of each node from the root(s). + /// + ///\pre init() must be called and at least one root node should be + ///added with addSource() before using this function. + /// + ///\note d.start() is just a shortcut of the following code. + ///\code + /// while ( !d.emptyQueue() ) { + /// d.processNextNode(); + /// } + ///\endcode + void start() + { + while ( !emptyQueue() ) processNextNode(); + } + + ///Executes the algorithm until the given target node is processed. + + ///Executes the algorithm until the given target node is processed. + /// + ///This method runs the %Dijkstra algorithm from the root node(s) + ///in order to compute the shortest path to \c t. + /// + ///The algorithm computes + ///- the shortest path to \c t, + ///- the distance of \c t from the root(s). + /// + ///\pre init() must be called and at least one root node should be + ///added with addSource() before using this function. + void start(Node t) + { + while ( !_heap->empty() && _heap->top()!=t ) processNextNode(); + if ( !_heap->empty() ) { + finalizeNodeData(_heap->top(),_heap->prio()); + _heap->pop(); + } + } + + ///Executes the algorithm until a condition is met. + + ///Executes the algorithm until a condition is met. + /// + ///This method runs the %Dijkstra algorithm from the root node(s) in + ///order to compute the shortest path to a node \c v with + /// nm[v] true, if such a node can be found. + /// + ///\param nm A \c bool (or convertible) node map. The algorithm + ///will stop when it reaches a node \c v with nm[v] true. + /// + ///\return The reached node \c v with nm[v] true or + ///\c INVALID if no such node was found. + /// + ///\pre init() must be called and at least one root node should be + ///added with addSource() before using this function. + template + Node start(const NodeBoolMap &nm) + { + while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode(); + if ( _heap->empty() ) return INVALID; + finalizeNodeData(_heap->top(),_heap->prio()); + return _heap->top(); + } + + ///Runs the algorithm from the given source node. + + ///This method runs the %Dijkstra algorithm from node \c s + ///in order to compute the shortest path to each node. + /// + ///The algorithm computes + ///- the shortest path tree, + ///- the distance of each node from the root. + /// + ///\note d.run(s) is just a shortcut of the following code. + ///\code + /// d.init(); + /// d.addSource(s); + /// d.start(); + ///\endcode + void run(Node s) { + init(); + addSource(s); + start(); + } + + ///Finds the shortest path between \c s and \c t. + + ///This method runs the %Dijkstra algorithm from node \c s + ///in order to compute the shortest path to node \c t + ///(it stops searching when \c t is processed). + /// + ///\return \c true if \c t is reachable form \c s. + /// + ///\note Apart from the return value, d.run(s,t) is just a + ///shortcut of the following code. + ///\code + /// d.init(); + /// d.addSource(s); + /// d.start(t); + ///\endcode + bool run(Node s,Node t) { + init(); + addSource(s); + start(t); + return (*_heap_cross_ref)[t] == Heap::POST_HEAP; + } + + ///@} + + ///\name Query Functions + ///The results of the %Dijkstra algorithm can be obtained using these + ///functions.\n + ///Either \ref run(Node) "run()" or \ref init() should be called + ///before using them. + + ///@{ + + ///The shortest path to the given node. + + ///Returns the shortest path to the given node from the root(s). + /// + ///\warning \c t should be reached from the root(s). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Path path(Node t) const { return Path(*G, *_pred, t); } + + ///The distance of the given node from the root(s). + + ///Returns the distance of the given node from the root(s). + /// + ///\warning If node \c v is not reached from the root(s), then + ///the return value of this function is undefined. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Value dist(Node v) const { return (*_dist)[v]; } + + ///\brief Returns the 'previous arc' of the shortest path tree for + ///the given node. + /// + ///This function returns the 'previous arc' of the shortest path + ///tree for the node \c v, i.e. it returns the last arc of a + ///shortest path from a root to \c v. It is \c INVALID if \c v + ///is not reached from the root(s) or if \c v is a root. + /// + ///The shortest path tree used here is equal to the shortest path + ///tree used in \ref predNode() and \ref predMap(). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Arc predArc(Node v) const { return (*_pred)[v]; } + + ///\brief Returns the 'previous node' of the shortest path tree for + ///the given node. + /// + ///This function returns the 'previous node' of the shortest path + ///tree for the node \c v, i.e. it returns the last but one node + ///of a shortest path from a root to \c v. It is \c INVALID + ///if \c v is not reached from the root(s) or if \c v is a root. + /// + ///The shortest path tree used here is equal to the shortest path + ///tree used in \ref predArc() and \ref predMap(). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID: + G->source((*_pred)[v]); } + + ///\brief Returns a const reference to the node map that stores the + ///distances of the nodes. + /// + ///Returns a const reference to the node map that stores the distances + ///of the nodes calculated by the algorithm. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + const DistMap &distMap() const { return *_dist;} + + ///\brief Returns a const reference to the node map that stores the + ///predecessor arcs. + /// + ///Returns a const reference to the node map that stores the predecessor + ///arcs, which form the shortest path tree (forest). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + const PredMap &predMap() const { return *_pred;} + + ///Checks if the given node is reached from the root(s). + + ///Returns \c true if \c v is reached from the root(s). + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + bool reached(Node v) const { return (*_heap_cross_ref)[v] != + Heap::PRE_HEAP; } + + ///Checks if a node is processed. + + ///Returns \c true if \c v is processed, i.e. the shortest + ///path to \c v has already found. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function. + bool processed(Node v) const { return (*_heap_cross_ref)[v] == + Heap::POST_HEAP; } + + ///The current distance of the given node from the root(s). + + ///Returns the current distance of the given node from the root(s). + ///It may be decreased in the following processes. + /// + ///\pre Either \ref run(Node) "run()" or \ref init() + ///must be called before using this function and + ///node \c v must be reached but not necessarily processed. + Value currentDist(Node v) const { + return processed(v) ? (*_dist)[v] : (*_heap)[v]; + } + + ///@} + }; + + + ///Default traits class of dijkstra() function. + + ///Default traits class of dijkstra() function. + ///\tparam GR The type of the digraph. + ///\tparam LEN The type of the length map. + template + struct DijkstraWizardDefaultTraits + { + ///The type of the digraph the algorithm runs on. + typedef GR Digraph; + ///The type of the map that stores the arc lengths. + + ///The type of the map that stores the arc lengths. + ///It must conform to the \ref concepts::ReadMap "ReadMap" concept. + typedef LEN LengthMap; + ///The type of the arc lengths. + typedef typename LEN::Value Value; + + /// Operation traits for Dijkstra algorithm. + + /// This class defines the operations that are used in the algorithm. + /// \see DijkstraDefaultOperationTraits + typedef DijkstraDefaultOperationTraits OperationTraits; + + /// The cross reference type used by the heap. + + /// The cross reference type used by the heap. + /// Usually it is \c Digraph::NodeMap. + typedef typename Digraph::template NodeMap HeapCrossRef; + ///Instantiates a \ref HeapCrossRef. + + ///This function instantiates a \ref HeapCrossRef. + /// \param g is the digraph, to which we would like to define the + /// HeapCrossRef. + static HeapCrossRef *createHeapCrossRef(const Digraph &g) + { + return new HeapCrossRef(g); + } + + ///The heap type used by the Dijkstra algorithm. + + ///The heap type used by the Dijkstra algorithm. + /// + ///\sa BinHeap + ///\sa Dijkstra + typedef BinHeap, + std::less > Heap; + + ///Instantiates a \ref Heap. + + ///This function instantiates a \ref Heap. + /// \param r is the HeapCrossRef which is used. + static Heap *createHeap(HeapCrossRef& r) + { + return new Heap(r); + } + + ///\brief The type of the map that stores the predecessor + ///arcs of the shortest paths. + /// + ///The type of the map that stores the predecessor + ///arcs of the shortest paths. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap PredMap; + ///Instantiates a PredMap. + + ///This function instantiates a PredMap. + ///\param g is the digraph, to which we would like to define the + ///PredMap. + static PredMap *createPredMap(const Digraph &g) + { + return new PredMap(g); + } + + ///The type of the map that indicates which nodes are processed. + + ///The type of the map that indicates which nodes are processed. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + ///By default, it is a NullMap. + typedef NullMap ProcessedMap; + ///Instantiates a ProcessedMap. + + ///This function instantiates a ProcessedMap. + ///\param g is the digraph, to which + ///we would like to define the ProcessedMap. +#ifdef DOXYGEN + static ProcessedMap *createProcessedMap(const Digraph &g) +#else + static ProcessedMap *createProcessedMap(const Digraph &) +#endif + { + return new ProcessedMap(); + } + + ///The type of the map that stores the distances of the nodes. + + ///The type of the map that stores the distances of the nodes. + ///It must conform to the \ref concepts::WriteMap "WriteMap" concept. + typedef typename Digraph::template NodeMap DistMap; + ///Instantiates a DistMap. + + ///This function instantiates a DistMap. + ///\param g is the digraph, to which we would like to define + ///the DistMap + static DistMap *createDistMap(const Digraph &g) + { + return new DistMap(g); + } + + ///The type of the shortest paths. + + ///The type of the shortest paths. + ///It must conform to the \ref concepts::Path "Path" concept. + typedef lemon::Path Path; + }; + + /// Default traits class used by DijkstraWizard + + /// Default traits class used by DijkstraWizard. + /// \tparam GR The type of the digraph. + /// \tparam LEN The type of the length map. + template + class DijkstraWizardBase : public DijkstraWizardDefaultTraits + { + typedef DijkstraWizardDefaultTraits Base; + protected: + //The type of the nodes in the digraph. + typedef typename Base::Digraph::Node Node; + + //Pointer to the digraph the algorithm runs on. + void *_g; + //Pointer to the length map. + void *_length; + //Pointer to the map of processed nodes. + void *_processed; + //Pointer to the map of predecessors arcs. + void *_pred; + //Pointer to the map of distances. + void *_dist; + //Pointer to the shortest path to the target node. + void *_path; + //Pointer to the distance of the target node. + void *_di; + + public: + /// Constructor. + + /// This constructor does not require parameters, therefore it initiates + /// all of the attributes to \c 0. + DijkstraWizardBase() : _g(0), _length(0), _processed(0), _pred(0), + _dist(0), _path(0), _di(0) {} + + /// Constructor. + + /// This constructor requires two parameters, + /// others are initiated to \c 0. + /// \param g The digraph the algorithm runs on. + /// \param l The length map. + DijkstraWizardBase(const GR &g,const LEN &l) : + _g(reinterpret_cast(const_cast(&g))), + _length(reinterpret_cast(const_cast(&l))), + _processed(0), _pred(0), _dist(0), _path(0), _di(0) {} + + }; + + /// Auxiliary class for the function-type interface of Dijkstra algorithm. + + /// This auxiliary class is created to implement the + /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm. + /// It does not have own \ref run(Node) "run()" method, it uses the + /// functions and features of the plain \ref Dijkstra. + /// + /// This class should only be used through the \ref dijkstra() function, + /// which makes it easier to use the algorithm. + /// + /// \tparam TR The traits class that defines various types used by the + /// algorithm. + template + class DijkstraWizard : public TR + { + typedef TR Base; + + typedef typename TR::Digraph Digraph; + + typedef typename Digraph::Node Node; + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::Arc Arc; + typedef typename Digraph::OutArcIt OutArcIt; + + typedef typename TR::LengthMap LengthMap; + typedef typename LengthMap::Value Value; + typedef typename TR::PredMap PredMap; + typedef typename TR::DistMap DistMap; + typedef typename TR::ProcessedMap ProcessedMap; + typedef typename TR::Path Path; + typedef typename TR::Heap Heap; + + public: + + /// Constructor. + DijkstraWizard() : TR() {} + + /// Constructor that requires parameters. + + /// Constructor that requires parameters. + /// These parameters will be the default values for the traits class. + /// \param g The digraph the algorithm runs on. + /// \param l The length map. + DijkstraWizard(const Digraph &g, const LengthMap &l) : + TR(g,l) {} + + ///Copy constructor + DijkstraWizard(const TR &b) : TR(b) {} + + ~DijkstraWizard() {} + + ///Runs Dijkstra algorithm from the given source node. + + ///This method runs %Dijkstra algorithm from the given source node + ///in order to compute the shortest path to each node. + void run(Node s) + { + Dijkstra + dijk(*reinterpret_cast(Base::_g), + *reinterpret_cast(Base::_length)); + if (Base::_pred) + dijk.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) + dijk.distMap(*reinterpret_cast(Base::_dist)); + if (Base::_processed) + dijk.processedMap(*reinterpret_cast(Base::_processed)); + dijk.run(s); + } + + ///Finds the shortest path between \c s and \c t. + + ///This method runs the %Dijkstra algorithm from node \c s + ///in order to compute the shortest path to node \c t + ///(it stops searching when \c t is processed). + /// + ///\return \c true if \c t is reachable form \c s. + bool run(Node s, Node t) + { + Dijkstra + dijk(*reinterpret_cast(Base::_g), + *reinterpret_cast(Base::_length)); + if (Base::_pred) + dijk.predMap(*reinterpret_cast(Base::_pred)); + if (Base::_dist) + dijk.distMap(*reinterpret_cast(Base::_dist)); + if (Base::_processed) + dijk.processedMap(*reinterpret_cast(Base::_processed)); + dijk.run(s,t); + if (Base::_path) + *reinterpret_cast(Base::_path) = dijk.path(t); + if (Base::_di) + *reinterpret_cast(Base::_di) = dijk.dist(t); + return dijk.reached(t); + } + + template + struct SetPredMapBase : public Base { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) { return 0; }; + SetPredMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the predecessor map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that stores the predecessor arcs of the nodes. + template + DijkstraWizard > predMap(const T &t) + { + Base::_pred=reinterpret_cast(const_cast(&t)); + return DijkstraWizard >(*this); + } + + template + struct SetDistMapBase : public Base { + typedef T DistMap; + static DistMap *createDistMap(const Digraph &) { return 0; }; + SetDistMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-templ-param "Named parameter" for setting + ///the distance map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that stores the distances of the nodes calculated + ///by the algorithm. + template + DijkstraWizard > distMap(const T &t) + { + Base::_dist=reinterpret_cast(const_cast(&t)); + return DijkstraWizard >(*this); + } + + template + struct SetProcessedMapBase : public Base { + typedef T ProcessedMap; + static ProcessedMap *createProcessedMap(const Digraph &) { return 0; }; + SetProcessedMapBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-func-param "Named parameter" for setting + ///the processed map. + /// + ///\ref named-templ-param "Named parameter" function for setting + ///the map that indicates which nodes are processed. + template + DijkstraWizard > processedMap(const T &t) + { + Base::_processed=reinterpret_cast(const_cast(&t)); + return DijkstraWizard >(*this); + } + + template + struct SetPathBase : public Base { + typedef T Path; + SetPathBase(const TR &b) : TR(b) {} + }; + + ///\brief \ref named-func-param "Named parameter" + ///for getting the shortest path to the target node. + /// + ///\ref named-func-param "Named parameter" + ///for getting the shortest path to the target node. + template + DijkstraWizard > path(const T &t) + { + Base::_path=reinterpret_cast(const_cast(&t)); + return DijkstraWizard >(*this); + } + + ///\brief \ref named-func-param "Named parameter" + ///for getting the distance of the target node. + /// + ///\ref named-func-param "Named parameter" + ///for getting the distance of the target node. + DijkstraWizard dist(const Value &d) + { + Base::_di=reinterpret_cast(const_cast(&d)); + return *this; + } + + }; + + ///Function-type interface for Dijkstra algorithm. + + /// \ingroup shortest_path + ///Function-type interface for Dijkstra algorithm. + /// + ///This function also has several \ref named-func-param "named parameters", + ///they are declared as the members of class \ref DijkstraWizard. + ///The following examples show how to use these parameters. + ///\code + /// // Compute shortest path from node s to each node + /// dijkstra(g,length).predMap(preds).distMap(dists).run(s); + /// + /// // Compute shortest path from s to t + /// bool reached = dijkstra(g,length).path(p).dist(d).run(s,t); + ///\endcode + ///\warning Don't forget to put the \ref DijkstraWizard::run(Node) "run()" + ///to the end of the parameter list. + ///\sa DijkstraWizard + ///\sa Dijkstra + template + DijkstraWizard > + dijkstra(const GR &digraph, const LEN &length) + { + return DijkstraWizard >(digraph,length); + } + +} //END OF NAMESPACE LEMON + +#endif diff --git a/lemon/lemon/dim2.h b/lemon/lemon/dim2.h new file mode 100644 index 0000000..a5882b0 --- /dev/null +++ b/lemon/lemon/dim2.h @@ -0,0 +1,725 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_DIM2_H +#define LEMON_DIM2_H + +#include + +///\ingroup geomdat +///\file +///\brief A simple two dimensional vector and a bounding box implementation + +namespace lemon { + + ///Tools for handling two dimensional coordinates + + ///This namespace is a storage of several + ///tools for handling two dimensional coordinates + namespace dim2 { + + /// \addtogroup geomdat + /// @{ + + /// Two dimensional vector (plain vector) + + /// A simple two dimensional vector (plain vector) implementation + /// with the usual vector operations. + template + class Point { + + public: + + typedef T Value; + + ///First coordinate + T x; + ///Second coordinate + T y; + + ///Default constructor + Point() {} + + ///Construct an instance from coordinates + Point(T a, T b) : x(a), y(b) { } + + ///Returns the dimension of the vector (i.e. returns 2). + + ///The dimension of the vector. + ///This function always returns 2. + int size() const { return 2; } + + ///Subscripting operator + + ///\c p[0] is \c p.x and \c p[1] is \c p.y + /// + T& operator[](int idx) { return idx == 0 ? x : y; } + + ///Const subscripting operator + + ///\c p[0] is \c p.x and \c p[1] is \c p.y + /// + const T& operator[](int idx) const { return idx == 0 ? x : y; } + + ///Conversion constructor + template Point(const Point &p) : x(p.x), y(p.y) {} + + ///Give back the square of the norm of the vector + T normSquare() const { + return x*x+y*y; + } + + ///Increment the left hand side by \c u + Point& operator +=(const Point& u) { + x += u.x; + y += u.y; + return *this; + } + + ///Decrement the left hand side by \c u + Point& operator -=(const Point& u) { + x -= u.x; + y -= u.y; + return *this; + } + + ///Multiply the left hand side with a scalar + Point& operator *=(const T &u) { + x *= u; + y *= u; + return *this; + } + + ///Divide the left hand side by a scalar + Point& operator /=(const T &u) { + x /= u; + y /= u; + return *this; + } + + ///Return the scalar product of two vectors + T operator *(const Point& u) const { + return x*u.x+y*u.y; + } + + ///Return the sum of two vectors + Point operator+(const Point &u) const { + Point b=*this; + return b+=u; + } + + ///Return the negative of the vector + Point operator-() const { + Point b=*this; + b.x=-b.x; b.y=-b.y; + return b; + } + + ///Return the difference of two vectors + Point operator-(const Point &u) const { + Point b=*this; + return b-=u; + } + + ///Return a vector multiplied by a scalar + Point operator*(const T &u) const { + Point b=*this; + return b*=u; + } + + ///Return a vector divided by a scalar + Point operator/(const T &u) const { + Point b=*this; + return b/=u; + } + + ///Test equality + bool operator==(const Point &u) const { + return (x==u.x) && (y==u.y); + } + + ///Test inequality + bool operator!=(Point u) const { + return (x!=u.x) || (y!=u.y); + } + + }; + + ///Return a Point + + ///Return a Point. + ///\relates Point + template + inline Point makePoint(const T& x, const T& y) { + return Point(x, y); + } + + ///Return a vector multiplied by a scalar + + ///Return a vector multiplied by a scalar. + ///\relates Point + template Point operator*(const T &u,const Point &x) { + return x*u; + } + + ///Read a plain vector from a stream + + ///Read a plain vector from a stream. + ///\relates Point + /// + template + inline std::istream& operator>>(std::istream &is, Point &z) { + char c; + if (is >> c) { + if (c != '(') is.putback(c); + } else { + is.clear(); + } + if (!(is >> z.x)) return is; + if (is >> c) { + if (c != ',') is.putback(c); + } else { + is.clear(); + } + if (!(is >> z.y)) return is; + if (is >> c) { + if (c != ')') is.putback(c); + } else { + is.clear(); + } + return is; + } + + ///Write a plain vector to a stream + + ///Write a plain vector to a stream. + ///\relates Point + /// + template + inline std::ostream& operator<<(std::ostream &os, const Point& z) + { + os << "(" << z.x << "," << z.y << ")"; + return os; + } + + ///Rotate by 90 degrees + + ///Returns the parameter rotated by 90 degrees in positive direction. + ///\relates Point + /// + template + inline Point rot90(const Point &z) + { + return Point(-z.y,z.x); + } + + ///Rotate by 180 degrees + + ///Returns the parameter rotated by 180 degrees. + ///\relates Point + /// + template + inline Point rot180(const Point &z) + { + return Point(-z.x,-z.y); + } + + ///Rotate by 270 degrees + + ///Returns the parameter rotated by 90 degrees in negative direction. + ///\relates Point + /// + template + inline Point rot270(const Point &z) + { + return Point(z.y,-z.x); + } + + + + /// Bounding box of plain vectors (points). + + /// A class to calculate or store the bounding box of plain vectors + /// (\ref Point "points"). + template + class Box { + Point _bottom_left, _top_right; + bool _empty; + public: + + ///Default constructor: creates an empty box + Box() { _empty = true; } + + ///Construct a box from one point + Box(Point a) { + _bottom_left = _top_right = a; + _empty = false; + } + + ///Construct a box from two points + + ///Construct a box from two points. + ///\param a The bottom left corner. + ///\param b The top right corner. + ///\warning The coordinates of the bottom left corner must be no more + ///than those of the top right one. + Box(Point a,Point b) + { + _bottom_left = a; + _top_right = b; + _empty = false; + } + + ///Construct a box from four numbers + + ///Construct a box from four numbers. + ///\param l The left side of the box. + ///\param b The bottom of the box. + ///\param r The right side of the box. + ///\param t The top of the box. + ///\warning The left side must be no more than the right side and + ///bottom must be no more than the top. + Box(T l,T b,T r,T t) + { + _bottom_left=Point(l,b); + _top_right=Point(r,t); + _empty = false; + } + + ///Return \c true if the box is empty. + + ///Return \c true if the box is empty (i.e. return \c false + ///if at least one point was added to the box or the coordinates of + ///the box were set). + /// + ///The coordinates of an empty box are not defined. + bool empty() const { + return _empty; + } + + ///Make the box empty + void clear() { + _empty = true; + } + + ///Give back the bottom left corner of the box + + ///Give back the bottom left corner of the box. + ///If the box is empty, then the return value is not defined. + Point bottomLeft() const { + return _bottom_left; + } + + ///Set the bottom left corner of the box + + ///Set the bottom left corner of the box. + ///\pre The box must not be empty. + void bottomLeft(Point p) { + _bottom_left = p; + } + + ///Give back the top right corner of the box + + ///Give back the top right corner of the box. + ///If the box is empty, then the return value is not defined. + Point topRight() const { + return _top_right; + } + + ///Set the top right corner of the box + + ///Set the top right corner of the box. + ///\pre The box must not be empty. + void topRight(Point p) { + _top_right = p; + } + + ///Give back the bottom right corner of the box + + ///Give back the bottom right corner of the box. + ///If the box is empty, then the return value is not defined. + Point bottomRight() const { + return Point(_top_right.x,_bottom_left.y); + } + + ///Set the bottom right corner of the box + + ///Set the bottom right corner of the box. + ///\pre The box must not be empty. + void bottomRight(Point p) { + _top_right.x = p.x; + _bottom_left.y = p.y; + } + + ///Give back the top left corner of the box + + ///Give back the top left corner of the box. + ///If the box is empty, then the return value is not defined. + Point topLeft() const { + return Point(_bottom_left.x,_top_right.y); + } + + ///Set the top left corner of the box + + ///Set the top left corner of the box. + ///\pre The box must not be empty. + void topLeft(Point p) { + _top_right.y = p.y; + _bottom_left.x = p.x; + } + + ///Give back the bottom of the box + + ///Give back the bottom of the box. + ///If the box is empty, then the return value is not defined. + T bottom() const { + return _bottom_left.y; + } + + ///Set the bottom of the box + + ///Set the bottom of the box. + ///\pre The box must not be empty. + void bottom(T t) { + _bottom_left.y = t; + } + + ///Give back the top of the box + + ///Give back the top of the box. + ///If the box is empty, then the return value is not defined. + T top() const { + return _top_right.y; + } + + ///Set the top of the box + + ///Set the top of the box. + ///\pre The box must not be empty. + void top(T t) { + _top_right.y = t; + } + + ///Give back the left side of the box + + ///Give back the left side of the box. + ///If the box is empty, then the return value is not defined. + T left() const { + return _bottom_left.x; + } + + ///Set the left side of the box + + ///Set the left side of the box. + ///\pre The box must not be empty. + void left(T t) { + _bottom_left.x = t; + } + + /// Give back the right side of the box + + /// Give back the right side of the box. + ///If the box is empty, then the return value is not defined. + T right() const { + return _top_right.x; + } + + ///Set the right side of the box + + ///Set the right side of the box. + ///\pre The box must not be empty. + void right(T t) { + _top_right.x = t; + } + + ///Give back the height of the box + + ///Give back the height of the box. + ///If the box is empty, then the return value is not defined. + T height() const { + return _top_right.y-_bottom_left.y; + } + + ///Give back the width of the box + + ///Give back the width of the box. + ///If the box is empty, then the return value is not defined. + T width() const { + return _top_right.x-_bottom_left.x; + } + + ///Checks whether a point is inside the box + bool inside(const Point& u) const { + if (_empty) + return false; + else { + return ( (u.x-_bottom_left.x)*(_top_right.x-u.x) >= 0 && + (u.y-_bottom_left.y)*(_top_right.y-u.y) >= 0 ); + } + } + + ///Increments the box with a point + + ///Increments the box with a point. + /// + Box& add(const Point& u){ + if (_empty) { + _bottom_left = _top_right = u; + _empty = false; + } + else { + if (_bottom_left.x > u.x) _bottom_left.x = u.x; + if (_bottom_left.y > u.y) _bottom_left.y = u.y; + if (_top_right.x < u.x) _top_right.x = u.x; + if (_top_right.y < u.y) _top_right.y = u.y; + } + return *this; + } + + ///Increments the box to contain another box + + ///Increments the box to contain another box. + /// + Box& add(const Box &u){ + if ( !u.empty() ){ + add(u._bottom_left); + add(u._top_right); + } + return *this; + } + + ///Intersection of two boxes + + ///Intersection of two boxes. + /// + Box operator&(const Box& u) const { + Box b; + if (_empty || u._empty) { + b._empty = true; + } else { + b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x); + b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y); + b._top_right.x = std::min(_top_right.x, u._top_right.x); + b._top_right.y = std::min(_top_right.y, u._top_right.y); + b._empty = b._bottom_left.x > b._top_right.x || + b._bottom_left.y > b._top_right.y; + } + return b; + } + + };//class Box + + + ///Read a box from a stream + + ///Read a box from a stream. + ///\relates Box + template + inline std::istream& operator>>(std::istream &is, Box& b) { + char c; + Point p; + if (is >> c) { + if (c != '(') is.putback(c); + } else { + is.clear(); + } + if (!(is >> p)) return is; + b.bottomLeft(p); + if (is >> c) { + if (c != ',') is.putback(c); + } else { + is.clear(); + } + if (!(is >> p)) return is; + b.topRight(p); + if (is >> c) { + if (c != ')') is.putback(c); + } else { + is.clear(); + } + return is; + } + + ///Write a box to a stream + + ///Write a box to a stream. + ///\relates Box + template + inline std::ostream& operator<<(std::ostream &os, const Box& b) + { + os << "(" << b.bottomLeft() << "," << b.topRight() << ")"; + return os; + } + + ///Map of x-coordinates of a Point-map + + ///Map of x-coordinates of a \ref Point "Point"-map. + /// + template + class XMap + { + M& _map; + public: + + typedef typename M::Value::Value Value; + typedef typename M::Key Key; + ///\e + XMap(M& map) : _map(map) {} + Value operator[](Key k) const {return _map[k].x;} + void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));} + }; + + ///Returns an XMap class + + ///This function just returns an XMap class. + ///\relates XMap + template + inline XMap xMap(M &m) + { + return XMap(m); + } + + template + inline XMap xMap(const M &m) + { + return XMap(m); + } + + ///Constant (read only) version of XMap + + ///Constant (read only) version of XMap. + /// + template + class ConstXMap + { + const M& _map; + public: + + typedef typename M::Value::Value Value; + typedef typename M::Key Key; + ///\e + ConstXMap(const M &map) : _map(map) {} + Value operator[](Key k) const {return _map[k].x;} + }; + + ///Returns a ConstXMap class + + ///This function just returns a ConstXMap class. + ///\relates ConstXMap + template + inline ConstXMap xMap(const M &m) + { + return ConstXMap(m); + } + + ///Map of y-coordinates of a Point-map + + ///Map of y-coordinates of a \ref Point "Point"-map. + /// + template + class YMap + { + M& _map; + public: + + typedef typename M::Value::Value Value; + typedef typename M::Key Key; + ///\e + YMap(M& map) : _map(map) {} + Value operator[](Key k) const {return _map[k].y;} + void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));} + }; + + ///Returns a YMap class + + ///This function just returns a YMap class. + ///\relates YMap + template + inline YMap yMap(M &m) + { + return YMap(m); + } + + template + inline YMap yMap(const M &m) + { + return YMap(m); + } + + ///Constant (read only) version of YMap + + ///Constant (read only) version of YMap. + /// + template + class ConstYMap + { + const M& _map; + public: + + typedef typename M::Value::Value Value; + typedef typename M::Key Key; + ///\e + ConstYMap(const M &map) : _map(map) {} + Value operator[](Key k) const {return _map[k].y;} + }; + + ///Returns a ConstYMap class + + ///This function just returns a ConstYMap class. + ///\relates ConstYMap + template + inline ConstYMap yMap(const M &m) + { + return ConstYMap(m); + } + + + ///\brief Map of the normSquare() of a Point-map + /// + ///Map of the \ref Point::normSquare() "normSquare()" + ///of a \ref Point "Point"-map. + template + class NormSquareMap + { + const M& _map; + public: + + typedef typename M::Value::Value Value; + typedef typename M::Key Key; + ///\e + NormSquareMap(const M &map) : _map(map) {} + Value operator[](Key k) const {return _map[k].normSquare();} + }; + + ///Returns a NormSquareMap class + + ///This function just returns a NormSquareMap class. + ///\relates NormSquareMap + template + inline NormSquareMap normSquareMap(const M &m) + { + return NormSquareMap(m); + } + + /// @} + + } //namespce dim2 + +} //namespace lemon + +#endif //LEMON_DIM2_H diff --git a/lemon/lemon/dimacs.h b/lemon/lemon/dimacs.h new file mode 100644 index 0000000..0c9e7ef --- /dev/null +++ b/lemon/lemon/dimacs.h @@ -0,0 +1,448 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_DIMACS_H +#define LEMON_DIMACS_H + +#include +#include +#include +#include +#include +#include +/// \ingroup dimacs_group +/// \file +/// \brief DIMACS file format reader. + +namespace lemon { + + /// \addtogroup dimacs_group + /// @{ + + /// DIMACS file type descriptor. + struct DimacsDescriptor + { + ///\brief DIMACS file type enum + /// + ///DIMACS file type enum. + enum Type { + NONE, ///< Undefined type. + MIN, ///< DIMACS file type for minimum cost flow problems. + MAX, ///< DIMACS file type for maximum flow problems. + SP, ///< DIMACS file type for shostest path problems. + MAT ///< DIMACS file type for plain graphs and matching problems. + }; + ///The file type + Type type; + ///The number of nodes in the graph + int nodeNum; + ///The number of edges in the graph + int edgeNum; + int lineShift; + ///Constructor. It sets the type to \c NONE. + DimacsDescriptor() : type(NONE) {} + }; + + ///Discover the type of a DIMACS file + + ///This function starts seeking the beginning of the given file for the + ///problem type and size info. + ///The found data is returned in a special struct that can be evaluated + ///and passed to the appropriate reader function. + DimacsDescriptor dimacsType(std::istream& is) + { + DimacsDescriptor r; + std::string problem,str; + char c; + r.lineShift=0; + while (is >> c) + switch(c) + { + case 'p': + if(is >> problem >> r.nodeNum >> r.edgeNum) + { + getline(is, str); + r.lineShift++; + if(problem=="min") r.type=DimacsDescriptor::MIN; + else if(problem=="max") r.type=DimacsDescriptor::MAX; + else if(problem=="sp") r.type=DimacsDescriptor::SP; + else if(problem=="mat") r.type=DimacsDescriptor::MAT; + else throw FormatError("Unknown problem type"); + return r; + } + else + { + throw FormatError("Missing or wrong problem type declaration."); + } + break; + case 'c': + getline(is, str); + r.lineShift++; + break; + default: + throw FormatError("Unknown DIMACS declaration."); + } + throw FormatError("Missing problem type declaration."); + } + + + /// \brief DIMACS minimum cost flow reader function. + /// + /// This function reads a minimum cost flow instance from DIMACS format, + /// i.e. from a DIMACS file having a line starting with + /// \code + /// p min + /// \endcode + /// At the beginning, \c g is cleared by \c g.clear(). The supply + /// amount of the nodes are written to the \c supply node map + /// (they are signed values). The lower bounds, capacities and costs + /// of the arcs are written to the \c lower, \c capacity and \c cost + /// arc maps. + /// + /// If the capacity of an arc is less than the lower bound, it will + /// be set to "infinite" instead. The actual value of "infinite" is + /// contolled by the \c infty parameter. If it is 0 (the default value), + /// \c std::numeric_limits::infinity() will be used if available, + /// \c std::numeric_limits::max() otherwise. If \c infty is set to + /// a non-zero value, that value will be used as "infinite". + /// + /// If the file type was previously evaluated by dimacsType(), then + /// the descriptor struct should be given by the \c dest parameter. + template + void readDimacsMin(std::istream& is, + Digraph &g, + LowerMap& lower, + CapacityMap& capacity, + CostMap& cost, + SupplyMap& supply, + typename CapacityMap::Value infty = 0, + DimacsDescriptor desc=DimacsDescriptor()) + { + g.clear(); + std::vector nodes; + typename Digraph::Arc e; + std::string problem, str; + char c; + int i, j; + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); + if(desc.type!=DimacsDescriptor::MIN) + throw FormatError("Problem type mismatch"); + + nodes.resize(desc.nodeNum + 1); + for (int k = 1; k <= desc.nodeNum; ++k) { + nodes[k] = g.addNode(); + supply.set(nodes[k], 0); + } + + typename SupplyMap::Value sup; + typename CapacityMap::Value low; + typename CapacityMap::Value cap; + typename CostMap::Value co; + typedef typename CapacityMap::Value Capacity; + if(infty==0) + infty = std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max(); + + while (is >> c) { + switch (c) { + case 'c': // comment line + getline(is, str); + break; + case 'n': // node definition line + is >> i >> sup; + getline(is, str); + supply.set(nodes[i], sup); + break; + case 'a': // arc definition line + is >> i >> j >> low >> cap >> co; + getline(is, str); + e = g.addArc(nodes[i], nodes[j]); + lower.set(e, low); + if (cap >= low) + capacity.set(e, cap); + else + capacity.set(e, infty); + cost.set(e, co); + break; + } + } + } + + template + void _readDimacs(std::istream& is, + Digraph &g, + CapacityMap& capacity, + typename Digraph::Node &s, + typename Digraph::Node &t, + typename CapacityMap::Value infty = 0, + DimacsDescriptor desc=DimacsDescriptor()) { + g.clear(); + s=t=INVALID; + std::vector nodes; + typename Digraph::Arc e; + char c, d; + int i, j; + typename CapacityMap::Value _cap; + std::string str; + nodes.resize(desc.nodeNum + 1); + for (int k = 1; k <= desc.nodeNum; ++k) { + nodes[k] = g.addNode(); + } + typedef typename CapacityMap::Value Capacity; + + if(infty==0) + infty = std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max(); + + while (is >> c) { + switch (c) { + case 'c': // comment line + getline(is, str); + break; + case 'n': // node definition line + if (desc.type==DimacsDescriptor::SP) { // shortest path problem + is >> i; + getline(is, str); + s = nodes[i]; + } + if (desc.type==DimacsDescriptor::MAX) { // max flow problem + is >> i >> d; + getline(is, str); + if (d == 's') s = nodes[i]; + if (d == 't') t = nodes[i]; + } + break; + case 'a': // arc definition line + if (desc.type==DimacsDescriptor::SP) { + is >> i >> j >> _cap; + getline(is, str); + e = g.addArc(nodes[i], nodes[j]); + capacity.set(e, _cap); + } + else if (desc.type==DimacsDescriptor::MAX) { + is >> i >> j >> _cap; + getline(is, str); + e = g.addArc(nodes[i], nodes[j]); + if (_cap >= 0) + capacity.set(e, _cap); + else + capacity.set(e, infty); + } + else { + is >> i >> j; + getline(is, str); + g.addArc(nodes[i], nodes[j]); + } + break; + } + } + } + + /// \brief DIMACS maximum flow reader function. + /// + /// This function reads a maximum flow instance from DIMACS format, + /// i.e. from a DIMACS file having a line starting with + /// \code + /// p max + /// \endcode + /// At the beginning, \c g is cleared by \c g.clear(). The arc + /// capacities are written to the \c capacity arc map and \c s and + /// \c t are set to the source and the target nodes. + /// + /// If the capacity of an arc is negative, it will + /// be set to "infinite" instead. The actual value of "infinite" is + /// contolled by the \c infty parameter. If it is 0 (the default value), + /// \c std::numeric_limits::infinity() will be used if available, + /// \c std::numeric_limits::max() otherwise. If \c infty is set to + /// a non-zero value, that value will be used as "infinite". + /// + /// If the file type was previously evaluated by dimacsType(), then + /// the descriptor struct should be given by the \c dest parameter. + template + void readDimacsMax(std::istream& is, + Digraph &g, + CapacityMap& capacity, + typename Digraph::Node &s, + typename Digraph::Node &t, + typename CapacityMap::Value infty = 0, + DimacsDescriptor desc=DimacsDescriptor()) { + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); + if(desc.type!=DimacsDescriptor::MAX) + throw FormatError("Problem type mismatch"); + _readDimacs(is,g,capacity,s,t,infty,desc); + } + + /// \brief DIMACS shortest path reader function. + /// + /// This function reads a shortest path instance from DIMACS format, + /// i.e. from a DIMACS file having a line starting with + /// \code + /// p sp + /// \endcode + /// At the beginning, \c g is cleared by \c g.clear(). The arc + /// lengths are written to the \c length arc map and \c s is set to the + /// source node. + /// + /// If the file type was previously evaluated by dimacsType(), then + /// the descriptor struct should be given by the \c dest parameter. + template + void readDimacsSp(std::istream& is, + Digraph &g, + LengthMap& length, + typename Digraph::Node &s, + DimacsDescriptor desc=DimacsDescriptor()) { + typename Digraph::Node t; + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); + if(desc.type!=DimacsDescriptor::SP) + throw FormatError("Problem type mismatch"); + _readDimacs(is, g, length, s, t, 0, desc); + } + + /// \brief DIMACS capacitated digraph reader function. + /// + /// This function reads an arc capacitated digraph instance from + /// DIMACS 'max' or 'sp' format. + /// At the beginning, \c g is cleared by \c g.clear() + /// and the arc capacities/lengths are written to the \c capacity + /// arc map. + /// + /// In case of the 'max' format, if the capacity of an arc is negative, + /// it will + /// be set to "infinite" instead. The actual value of "infinite" is + /// contolled by the \c infty parameter. If it is 0 (the default value), + /// \c std::numeric_limits::infinity() will be used if available, + /// \c std::numeric_limits::max() otherwise. If \c infty is set to + /// a non-zero value, that value will be used as "infinite". + /// + /// If the file type was previously evaluated by dimacsType(), then + /// the descriptor struct should be given by the \c dest parameter. + template + void readDimacsCap(std::istream& is, + Digraph &g, + CapacityMap& capacity, + typename CapacityMap::Value infty = 0, + DimacsDescriptor desc=DimacsDescriptor()) { + typename Digraph::Node u,v; + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); + if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP) + throw FormatError("Problem type mismatch"); + _readDimacs(is, g, capacity, u, v, infty, desc); + } + + template + typename enable_if,void>::type + _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t, + dummy<0> = 0) + { + g.addEdge(s,t); + } + template + typename disable_if,void>::type + _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t, + dummy<1> = 1) + { + g.addArc(s,t); + } + + /// \brief DIMACS plain (di)graph reader function. + /// + /// This function reads a plain (di)graph without any designated nodes + /// and maps (e.g. a matching instance) from DIMACS format, i.e. from + /// DIMACS files having a line starting with + /// \code + /// p mat + /// \endcode + /// At the beginning, \c g is cleared by \c g.clear(). + /// + /// If the file type was previously evaluated by dimacsType(), then + /// the descriptor struct should be given by the \c dest parameter. + template + void readDimacsMat(std::istream& is, Graph &g, + DimacsDescriptor desc=DimacsDescriptor()) + { + if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is); + if(desc.type!=DimacsDescriptor::MAT) + throw FormatError("Problem type mismatch"); + + g.clear(); + std::vector nodes; + char c; + int i, j; + std::string str; + nodes.resize(desc.nodeNum + 1); + for (int k = 1; k <= desc.nodeNum; ++k) { + nodes[k] = g.addNode(); + } + + while (is >> c) { + switch (c) { + case 'c': // comment line + getline(is, str); + break; + case 'n': // node definition line + break; + case 'a': // arc definition line + is >> i >> j; + getline(is, str); + _addArcEdge(g,nodes[i], nodes[j]); + break; + } + } + } + + /// DIMACS plain digraph writer function. + /// + /// This function writes a digraph without any designated nodes and + /// maps into DIMACS format, i.e. into DIMACS file having a line + /// starting with + /// \code + /// p mat + /// \endcode + /// If \c comment is not empty, then it will be printed in the first line + /// prefixed by 'c'. + template + void writeDimacsMat(std::ostream& os, const Digraph &g, + std::string comment="") { + typedef typename Digraph::NodeIt NodeIt; + typedef typename Digraph::ArcIt ArcIt; + + if(!comment.empty()) + os << "c " << comment << std::endl; + os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl; + + typename Digraph::template NodeMap nodes(g); + int i = 1; + for(NodeIt v(g); v != INVALID; ++v) { + nodes.set(v, i); + ++i; + } + for(ArcIt e(g); e != INVALID; ++e) { + os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)] + << std::endl; + } + } + + /// @} + +} //namespace lemon + +#endif //LEMON_DIMACS_H diff --git a/lemon/lemon/edge_set.h b/lemon/lemon/edge_set.h new file mode 100644 index 0000000..8d3067d --- /dev/null +++ b/lemon/lemon/edge_set.h @@ -0,0 +1,1420 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_EDGE_SET_H +#define LEMON_EDGE_SET_H + +#include +#include + +/// \ingroup graphs +/// \file +/// \brief ArcSet and EdgeSet classes. +/// +/// Graphs which use another graph's node-set as own. +namespace lemon { + + template + class ListArcSetBase { + public: + + typedef typename GR::Node Node; + typedef typename GR::NodeIt NodeIt; + + protected: + + struct NodeT { + int first_out, first_in; + NodeT() : first_out(-1), first_in(-1) {} + }; + + typedef typename ItemSetTraits:: + template Map::Type NodesImplBase; + + NodesImplBase* _nodes; + + struct ArcT { + Node source, target; + int next_out, next_in; + int prev_out, prev_in; + ArcT() : prev_out(-1), prev_in(-1) {} + }; + + std::vector arcs; + + int first_arc; + int first_free_arc; + + const GR* _graph; + + void initalize(const GR& graph, NodesImplBase& nodes) { + _graph = &graph; + _nodes = &nodes; + } + + public: + + class Arc { + friend class ListArcSetBase; + protected: + Arc(int _id) : id(_id) {} + int id; + public: + Arc() {} + Arc(Invalid) : id(-1) {} + bool operator==(const Arc& arc) const { return id == arc.id; } + bool operator!=(const Arc& arc) const { return id != arc.id; } + bool operator<(const Arc& arc) const { return id < arc.id; } + }; + + ListArcSetBase() : first_arc(-1), first_free_arc(-1) {} + + Node addNode() { + LEMON_ASSERT(false, + "This graph structure does not support node insertion"); + return INVALID; // avoid warning + } + + Arc addArc(const Node& u, const Node& v) { + int n; + if (first_free_arc == -1) { + n = arcs.size(); + arcs.push_back(ArcT()); + } else { + n = first_free_arc; + first_free_arc = arcs[first_free_arc].next_in; + } + arcs[n].next_in = (*_nodes)[v].first_in; + if ((*_nodes)[v].first_in != -1) { + arcs[(*_nodes)[v].first_in].prev_in = n; + } + (*_nodes)[v].first_in = n; + arcs[n].next_out = (*_nodes)[u].first_out; + if ((*_nodes)[u].first_out != -1) { + arcs[(*_nodes)[u].first_out].prev_out = n; + } + (*_nodes)[u].first_out = n; + arcs[n].source = u; + arcs[n].target = v; + return Arc(n); + } + + void erase(const Arc& arc) { + int n = arc.id; + if (arcs[n].prev_in != -1) { + arcs[arcs[n].prev_in].next_in = arcs[n].next_in; + } else { + (*_nodes)[arcs[n].target].first_in = arcs[n].next_in; + } + if (arcs[n].next_in != -1) { + arcs[arcs[n].next_in].prev_in = arcs[n].prev_in; + } + + if (arcs[n].prev_out != -1) { + arcs[arcs[n].prev_out].next_out = arcs[n].next_out; + } else { + (*_nodes)[arcs[n].source].first_out = arcs[n].next_out; + } + if (arcs[n].next_out != -1) { + arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; + } + + } + + void clear() { + Node node; + for (first(node); node != INVALID; next(node)) { + (*_nodes)[node].first_in = -1; + (*_nodes)[node].first_out = -1; + } + arcs.clear(); + first_arc = -1; + first_free_arc = -1; + } + + void first(Node& node) const { + _graph->first(node); + } + + void next(Node& node) const { + _graph->next(node); + } + + void first(Arc& arc) const { + Node node; + first(node); + while (node != INVALID && (*_nodes)[node].first_in == -1) { + next(node); + } + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in; + } + + void next(Arc& arc) const { + if (arcs[arc.id].next_in != -1) { + arc.id = arcs[arc.id].next_in; + } else { + Node node = arcs[arc.id].target; + next(node); + while (node != INVALID && (*_nodes)[node].first_in == -1) { + next(node); + } + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in; + } + } + + void firstOut(Arc& arc, const Node& node) const { + arc.id = (*_nodes)[node].first_out; + } + + void nextOut(Arc& arc) const { + arc.id = arcs[arc.id].next_out; + } + + void firstIn(Arc& arc, const Node& node) const { + arc.id = (*_nodes)[node].first_in; + } + + void nextIn(Arc& arc) const { + arc.id = arcs[arc.id].next_in; + } + + int id(const Node& node) const { return _graph->id(node); } + int id(const Arc& arc) const { return arc.id; } + + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); } + Arc arcFromId(int ix) const { return Arc(ix); } + + int maxNodeId() const { return _graph->maxNodeId(); }; + int maxArcId() const { return arcs.size() - 1; } + + Node source(const Arc& arc) const { return arcs[arc.id].source;} + Node target(const Arc& arc) const { return arcs[arc.id].target;} + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + + NodeNotifier& notifier(Node) const { + return _graph->notifier(Node()); + } + + template + class NodeMap : public GR::template NodeMap { + typedef typename GR::template NodeMap Parent; + + public: + + explicit NodeMap(const ListArcSetBase& arcset) + : Parent(*arcset._graph) {} + + NodeMap(const ListArcSetBase& arcset, const V& value) + : Parent(*arcset._graph, value) {} + + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + /// \ingroup graphs + /// + /// \brief Digraph using a node set of another digraph or graph and + /// an own arc set. + /// + /// This structure can be used to establish another directed graph + /// over a node set of an existing one. This class uses the same + /// Node type as the underlying graph, and each valid node of the + /// original graph is valid in this arc set, therefore the node + /// objects of the original graph can be used directly with this + /// class. The node handling functions (id handling, observing, and + /// iterators) works equivalently as in the original graph. + /// + /// This implementation is based on doubly-linked lists, from each + /// node the outgoing and the incoming arcs make up lists, therefore + /// one arc can be erased in constant time. It also makes possible, + /// that node can be removed from the underlying graph, in this case + /// all arcs incident to the given node is erased from the arc set. + /// + /// This class fully conforms to the \ref concepts::Digraph + /// "Digraph" concept. + /// It provides only linear time counting for nodes and arcs. + /// + /// \param GR The type of the graph which shares its node set with + /// this class. Its interface must conform to the + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph" + /// concept. + template + class ListArcSet : public ArcSetExtender > { + typedef ArcSetExtender > Parent; + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + typedef typename Parent::NodesImplBase NodesImplBase; + + void eraseNode(const Node& node) { + Arc arc; + Parent::firstOut(arc, node); + while (arc != INVALID ) { + erase(arc); + Parent::firstOut(arc, node); + } + + Parent::firstIn(arc, node); + while (arc != INVALID ) { + erase(arc); + Parent::firstIn(arc, node); + } + } + + void clearNodes() { + Parent::clear(); + } + + class NodesImpl : public NodesImplBase { + typedef NodesImplBase Parent; + + public: + NodesImpl(const GR& graph, ListArcSet& arcset) + : Parent(graph), _arcset(arcset) {} + + virtual ~NodesImpl() {} + + protected: + + virtual void erase(const Node& node) { + _arcset.eraseNode(node); + Parent::erase(node); + } + virtual void erase(const std::vector& nodes) { + for (int i = 0; i < int(nodes.size()); ++i) { + _arcset.eraseNode(nodes[i]); + } + Parent::erase(nodes); + } + virtual void clear() { + _arcset.clearNodes(); + Parent::clear(); + } + + private: + ListArcSet& _arcset; + }; + + NodesImpl _nodes; + + public: + + /// \brief Constructor of the ArcSet. + /// + /// Constructor of the ArcSet. + ListArcSet(const GR& graph) : _nodes(graph, *this) { + Parent::initalize(graph, _nodes); + } + + /// \brief Add a new arc to the digraph. + /// + /// Add a new arc to the digraph with source node \c s + /// and target node \c t. + /// \return The new arc. + Arc addArc(const Node& s, const Node& t) { + return Parent::addArc(s, t); + } + + /// \brief Erase an arc from the digraph. + /// + /// Erase an arc \c a from the digraph. + void erase(const Arc& a) { + return Parent::erase(a); + } + + }; + + template + class ListEdgeSetBase { + public: + + typedef typename GR::Node Node; + typedef typename GR::NodeIt NodeIt; + + protected: + + struct NodeT { + int first_out; + NodeT() : first_out(-1) {} + }; + + typedef typename ItemSetTraits:: + template Map::Type NodesImplBase; + + NodesImplBase* _nodes; + + struct ArcT { + Node target; + int prev_out, next_out; + ArcT() : prev_out(-1), next_out(-1) {} + }; + + std::vector arcs; + + int first_arc; + int first_free_arc; + + const GR* _graph; + + void initalize(const GR& graph, NodesImplBase& nodes) { + _graph = &graph; + _nodes = &nodes; + } + + public: + + class Edge { + friend class ListEdgeSetBase; + protected: + + int id; + explicit Edge(int _id) { id = _id;} + + public: + Edge() {} + Edge (Invalid) { id = -1; } + bool operator==(const Edge& arc) const {return id == arc.id;} + bool operator!=(const Edge& arc) const {return id != arc.id;} + bool operator<(const Edge& arc) const {return id < arc.id;} + }; + + class Arc { + friend class ListEdgeSetBase; + protected: + Arc(int _id) : id(_id) {} + int id; + public: + operator Edge() const { return edgeFromId(id / 2); } + + Arc() {} + Arc(Invalid) : id(-1) {} + bool operator==(const Arc& arc) const { return id == arc.id; } + bool operator!=(const Arc& arc) const { return id != arc.id; } + bool operator<(const Arc& arc) const { return id < arc.id; } + }; + + ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {} + + Node addNode() { + LEMON_ASSERT(false, + "This graph structure does not support node insertion"); + return INVALID; // avoid warning + } + + Edge addEdge(const Node& u, const Node& v) { + int n; + + if (first_free_arc == -1) { + n = arcs.size(); + arcs.push_back(ArcT()); + arcs.push_back(ArcT()); + } else { + n = first_free_arc; + first_free_arc = arcs[n].next_out; + } + + arcs[n].target = u; + arcs[n | 1].target = v; + + arcs[n].next_out = (*_nodes)[v].first_out; + if ((*_nodes)[v].first_out != -1) { + arcs[(*_nodes)[v].first_out].prev_out = n; + } + (*_nodes)[v].first_out = n; + arcs[n].prev_out = -1; + + if ((*_nodes)[u].first_out != -1) { + arcs[(*_nodes)[u].first_out].prev_out = (n | 1); + } + arcs[n | 1].next_out = (*_nodes)[u].first_out; + (*_nodes)[u].first_out = (n | 1); + arcs[n | 1].prev_out = -1; + + return Edge(n / 2); + } + + void erase(const Edge& arc) { + int n = arc.id * 2; + + if (arcs[n].next_out != -1) { + arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; + } + + if (arcs[n].prev_out != -1) { + arcs[arcs[n].prev_out].next_out = arcs[n].next_out; + } else { + (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out; + } + + if (arcs[n | 1].next_out != -1) { + arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; + } + + if (arcs[n | 1].prev_out != -1) { + arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; + } else { + (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out; + } + + arcs[n].next_out = first_free_arc; + first_free_arc = n; + + } + + void clear() { + Node node; + for (first(node); node != INVALID; next(node)) { + (*_nodes)[node].first_out = -1; + } + arcs.clear(); + first_arc = -1; + first_free_arc = -1; + } + + void first(Node& node) const { + _graph->first(node); + } + + void next(Node& node) const { + _graph->next(node); + } + + void first(Arc& arc) const { + Node node; + first(node); + while (node != INVALID && (*_nodes)[node].first_out == -1) { + next(node); + } + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out; + } + + void next(Arc& arc) const { + if (arcs[arc.id].next_out != -1) { + arc.id = arcs[arc.id].next_out; + } else { + Node node = arcs[arc.id ^ 1].target; + next(node); + while(node != INVALID && (*_nodes)[node].first_out == -1) { + next(node); + } + arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out; + } + } + + void first(Edge& edge) const { + Node node; + first(node); + while (node != INVALID) { + edge.id = (*_nodes)[node].first_out; + while ((edge.id & 1) != 1) { + edge.id = arcs[edge.id].next_out; + } + if (edge.id != -1) { + edge.id /= 2; + return; + } + next(node); + } + edge.id = -1; + } + + void next(Edge& edge) const { + Node node = arcs[edge.id * 2].target; + edge.id = arcs[(edge.id * 2) | 1].next_out; + while ((edge.id & 1) != 1) { + edge.id = arcs[edge.id].next_out; + } + if (edge.id != -1) { + edge.id /= 2; + return; + } + next(node); + while (node != INVALID) { + edge.id = (*_nodes)[node].first_out; + while ((edge.id & 1) != 1) { + edge.id = arcs[edge.id].next_out; + } + if (edge.id != -1) { + edge.id /= 2; + return; + } + next(node); + } + edge.id = -1; + } + + void firstOut(Arc& arc, const Node& node) const { + arc.id = (*_nodes)[node].first_out; + } + + void nextOut(Arc& arc) const { + arc.id = arcs[arc.id].next_out; + } + + void firstIn(Arc& arc, const Node& node) const { + arc.id = (((*_nodes)[node].first_out) ^ 1); + if (arc.id == -2) arc.id = -1; + } + + void nextIn(Arc& arc) const { + arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1); + if (arc.id == -2) arc.id = -1; + } + + void firstInc(Edge &arc, bool& dir, const Node& node) const { + int de = (*_nodes)[node].first_out; + if (de != -1 ) { + arc.id = de / 2; + dir = ((de & 1) == 1); + } else { + arc.id = -1; + dir = true; + } + } + void nextInc(Edge &arc, bool& dir) const { + int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out); + if (de != -1 ) { + arc.id = de / 2; + dir = ((de & 1) == 1); + } else { + arc.id = -1; + dir = true; + } + } + + static bool direction(Arc arc) { + return (arc.id & 1) == 1; + } + + static Arc direct(Edge edge, bool dir) { + return Arc(edge.id * 2 + (dir ? 1 : 0)); + } + + int id(const Node& node) const { return _graph->id(node); } + static int id(Arc e) { return e.id; } + static int id(Edge e) { return e.id; } + + Node nodeFromId(int id) const { return _graph->nodeFromId(id); } + static Arc arcFromId(int id) { return Arc(id);} + static Edge edgeFromId(int id) { return Edge(id);} + + int maxNodeId() const { return _graph->maxNodeId(); }; + int maxEdgeId() const { return arcs.size() / 2 - 1; } + int maxArcId() const { return arcs.size()-1; } + + Node source(Arc e) const { return arcs[e.id ^ 1].target; } + Node target(Arc e) const { return arcs[e.id].target; } + + Node u(Edge e) const { return arcs[2 * e.id].target; } + Node v(Edge e) const { return arcs[2 * e.id + 1].target; } + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + + NodeNotifier& notifier(Node) const { + return _graph->notifier(Node()); + } + + template + class NodeMap : public GR::template NodeMap { + typedef typename GR::template NodeMap Parent; + + public: + + explicit NodeMap(const ListEdgeSetBase& arcset) + : Parent(*arcset._graph) {} + + NodeMap(const ListEdgeSetBase& arcset, const V& value) + : Parent(*arcset._graph, value) {} + + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + /// \ingroup graphs + /// + /// \brief Graph using a node set of another digraph or graph and an + /// own edge set. + /// + /// This structure can be used to establish another graph over a + /// node set of an existing one. This class uses the same Node type + /// as the underlying graph, and each valid node of the original + /// graph is valid in this arc set, therefore the node objects of + /// the original graph can be used directly with this class. The + /// node handling functions (id handling, observing, and iterators) + /// works equivalently as in the original graph. + /// + /// This implementation is based on doubly-linked lists, from each + /// node the incident edges make up lists, therefore one edge can be + /// erased in constant time. It also makes possible, that node can + /// be removed from the underlying graph, in this case all edges + /// incident to the given node is erased from the arc set. + /// + /// This class fully conforms to the \ref concepts::Graph "Graph" + /// concept. + /// It provides only linear time counting for nodes, edges and arcs. + /// + /// \param GR The type of the graph which shares its node set + /// with this class. Its interface must conform to the + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph" + /// concept. + template + class ListEdgeSet : public EdgeSetExtender > { + typedef EdgeSetExtender > Parent; + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + typedef typename Parent::Edge Edge; + + typedef typename Parent::NodesImplBase NodesImplBase; + + void eraseNode(const Node& node) { + Arc arc; + Parent::firstOut(arc, node); + while (arc != INVALID ) { + erase(arc); + Parent::firstOut(arc, node); + } + + } + + void clearNodes() { + Parent::clear(); + } + + class NodesImpl : public NodesImplBase { + typedef NodesImplBase Parent; + + public: + NodesImpl(const GR& graph, ListEdgeSet& arcset) + : Parent(graph), _arcset(arcset) {} + + virtual ~NodesImpl() {} + + protected: + + virtual void erase(const Node& node) { + _arcset.eraseNode(node); + Parent::erase(node); + } + virtual void erase(const std::vector& nodes) { + for (int i = 0; i < int(nodes.size()); ++i) { + _arcset.eraseNode(nodes[i]); + } + Parent::erase(nodes); + } + virtual void clear() { + _arcset.clearNodes(); + Parent::clear(); + } + + private: + ListEdgeSet& _arcset; + }; + + NodesImpl _nodes; + + public: + + /// \brief Constructor of the EdgeSet. + /// + /// Constructor of the EdgeSet. + ListEdgeSet(const GR& graph) : _nodes(graph, *this) { + Parent::initalize(graph, _nodes); + } + + /// \brief Add a new edge to the graph. + /// + /// Add a new edge to the graph with node \c u + /// and node \c v endpoints. + /// \return The new edge. + Edge addEdge(const Node& u, const Node& v) { + return Parent::addEdge(u, v); + } + + /// \brief Erase an edge from the graph. + /// + /// Erase the edge \c e from the graph. + void erase(const Edge& e) { + return Parent::erase(e); + } + + }; + + template + class SmartArcSetBase { + public: + + typedef typename GR::Node Node; + typedef typename GR::NodeIt NodeIt; + + protected: + + struct NodeT { + int first_out, first_in; + NodeT() : first_out(-1), first_in(-1) {} + }; + + typedef typename ItemSetTraits:: + template Map::Type NodesImplBase; + + NodesImplBase* _nodes; + + struct ArcT { + Node source, target; + int next_out, next_in; + ArcT() {} + }; + + std::vector arcs; + + const GR* _graph; + + void initalize(const GR& graph, NodesImplBase& nodes) { + _graph = &graph; + _nodes = &nodes; + } + + public: + + class Arc { + friend class SmartArcSetBase; + protected: + Arc(int _id) : id(_id) {} + int id; + public: + Arc() {} + Arc(Invalid) : id(-1) {} + bool operator==(const Arc& arc) const { return id == arc.id; } + bool operator!=(const Arc& arc) const { return id != arc.id; } + bool operator<(const Arc& arc) const { return id < arc.id; } + }; + + SmartArcSetBase() {} + + Node addNode() { + LEMON_ASSERT(false, + "This graph structure does not support node insertion"); + return INVALID; // avoid warning + } + + Arc addArc(const Node& u, const Node& v) { + int n = arcs.size(); + arcs.push_back(ArcT()); + arcs[n].next_in = (*_nodes)[v].first_in; + (*_nodes)[v].first_in = n; + arcs[n].next_out = (*_nodes)[u].first_out; + (*_nodes)[u].first_out = n; + arcs[n].source = u; + arcs[n].target = v; + return Arc(n); + } + + void clear() { + Node node; + for (first(node); node != INVALID; next(node)) { + (*_nodes)[node].first_in = -1; + (*_nodes)[node].first_out = -1; + } + arcs.clear(); + } + + void first(Node& node) const { + _graph->first(node); + } + + void next(Node& node) const { + _graph->next(node); + } + + void first(Arc& arc) const { + arc.id = arcs.size() - 1; + } + + static void next(Arc& arc) { + --arc.id; + } + + void firstOut(Arc& arc, const Node& node) const { + arc.id = (*_nodes)[node].first_out; + } + + void nextOut(Arc& arc) const { + arc.id = arcs[arc.id].next_out; + } + + void firstIn(Arc& arc, const Node& node) const { + arc.id = (*_nodes)[node].first_in; + } + + void nextIn(Arc& arc) const { + arc.id = arcs[arc.id].next_in; + } + + int id(const Node& node) const { return _graph->id(node); } + int id(const Arc& arc) const { return arc.id; } + + Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); } + Arc arcFromId(int ix) const { return Arc(ix); } + + int maxNodeId() const { return _graph->maxNodeId(); }; + int maxArcId() const { return arcs.size() - 1; } + + Node source(const Arc& arc) const { return arcs[arc.id].source;} + Node target(const Arc& arc) const { return arcs[arc.id].target;} + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + + NodeNotifier& notifier(Node) const { + return _graph->notifier(Node()); + } + + template + class NodeMap : public GR::template NodeMap { + typedef typename GR::template NodeMap Parent; + + public: + + explicit NodeMap(const SmartArcSetBase& arcset) + : Parent(*arcset._graph) { } + + NodeMap(const SmartArcSetBase& arcset, const V& value) + : Parent(*arcset._graph, value) { } + + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + + /// \ingroup graphs + /// + /// \brief Digraph using a node set of another digraph or graph and + /// an own arc set. + /// + /// This structure can be used to establish another directed graph + /// over a node set of an existing one. This class uses the same + /// Node type as the underlying graph, and each valid node of the + /// original graph is valid in this arc set, therefore the node + /// objects of the original graph can be used directly with this + /// class. The node handling functions (id handling, observing, and + /// iterators) works equivalently as in the original graph. + /// + /// \param GR The type of the graph which shares its node set with + /// this class. Its interface must conform to the + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph" + /// concept. + /// + /// This implementation is slightly faster than the \c ListArcSet, + /// because it uses continuous storage for arcs and it uses just + /// single-linked lists for enumerate outgoing and incoming + /// arcs. Therefore the arcs cannot be erased from the arc sets. + /// + /// This class fully conforms to the \ref concepts::Digraph "Digraph" + /// concept. + /// It provides only linear time counting for nodes and arcs. + /// + /// \warning If a node is erased from the underlying graph and this + /// node is the source or target of one arc in the arc set, then + /// the arc set is invalidated, and it cannot be used anymore. The + /// validity can be checked with the \c valid() member function. + template + class SmartArcSet : public ArcSetExtender > { + typedef ArcSetExtender > Parent; + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + + protected: + + typedef typename Parent::NodesImplBase NodesImplBase; + + void eraseNode(const Node& node) { + if (typename Parent::InArcIt(*this, node) == INVALID && + typename Parent::OutArcIt(*this, node) == INVALID) { + return; + } + throw typename NodesImplBase::Notifier::ImmediateDetach(); + } + + void clearNodes() { + Parent::clear(); + } + + class NodesImpl : public NodesImplBase { + typedef NodesImplBase Parent; + + public: + NodesImpl(const GR& graph, SmartArcSet& arcset) + : Parent(graph), _arcset(arcset) {} + + virtual ~NodesImpl() {} + + bool attached() const { + return Parent::attached(); + } + + protected: + + virtual void erase(const Node& node) { + try { + _arcset.eraseNode(node); + Parent::erase(node); + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { + Parent::clear(); + throw; + } + } + virtual void erase(const std::vector& nodes) { + try { + for (int i = 0; i < int(nodes.size()); ++i) { + _arcset.eraseNode(nodes[i]); + } + Parent::erase(nodes); + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { + Parent::clear(); + throw; + } + } + virtual void clear() { + _arcset.clearNodes(); + Parent::clear(); + } + + private: + SmartArcSet& _arcset; + }; + + NodesImpl _nodes; + + public: + + /// \brief Constructor of the ArcSet. + /// + /// Constructor of the ArcSet. + SmartArcSet(const GR& graph) : _nodes(graph, *this) { + Parent::initalize(graph, _nodes); + } + + /// \brief Add a new arc to the digraph. + /// + /// Add a new arc to the digraph with source node \c s + /// and target node \c t. + /// \return The new arc. + Arc addArc(const Node& s, const Node& t) { + return Parent::addArc(s, t); + } + + /// \brief Validity check + /// + /// This functions gives back false if the ArcSet is + /// invalidated. It occurs when a node in the underlying graph is + /// erased and it is not isolated in the ArcSet. + bool valid() const { + return _nodes.attached(); + } + + }; + + + template + class SmartEdgeSetBase { + public: + + typedef typename GR::Node Node; + typedef typename GR::NodeIt NodeIt; + + protected: + + struct NodeT { + int first_out; + NodeT() : first_out(-1) {} + }; + + typedef typename ItemSetTraits:: + template Map::Type NodesImplBase; + + NodesImplBase* _nodes; + + struct ArcT { + Node target; + int next_out; + ArcT() {} + }; + + std::vector arcs; + + const GR* _graph; + + void initalize(const GR& graph, NodesImplBase& nodes) { + _graph = &graph; + _nodes = &nodes; + } + + public: + + class Edge { + friend class SmartEdgeSetBase; + protected: + + int id; + explicit Edge(int _id) { id = _id;} + + public: + Edge() {} + Edge (Invalid) { id = -1; } + bool operator==(const Edge& arc) const {return id == arc.id;} + bool operator!=(const Edge& arc) const {return id != arc.id;} + bool operator<(const Edge& arc) const {return id < arc.id;} + }; + + class Arc { + friend class SmartEdgeSetBase; + protected: + Arc(int _id) : id(_id) {} + int id; + public: + operator Edge() const { return edgeFromId(id / 2); } + + Arc() {} + Arc(Invalid) : id(-1) {} + bool operator==(const Arc& arc) const { return id == arc.id; } + bool operator!=(const Arc& arc) const { return id != arc.id; } + bool operator<(const Arc& arc) const { return id < arc.id; } + }; + + SmartEdgeSetBase() {} + + Node addNode() { + LEMON_ASSERT(false, + "This graph structure does not support node insertion"); + return INVALID; // avoid warning + } + + Edge addEdge(const Node& u, const Node& v) { + int n = arcs.size(); + arcs.push_back(ArcT()); + arcs.push_back(ArcT()); + + arcs[n].target = u; + arcs[n | 1].target = v; + + arcs[n].next_out = (*_nodes)[v].first_out; + (*_nodes)[v].first_out = n; + + arcs[n | 1].next_out = (*_nodes)[u].first_out; + (*_nodes)[u].first_out = (n | 1); + + return Edge(n / 2); + } + + void clear() { + Node node; + for (first(node); node != INVALID; next(node)) { + (*_nodes)[node].first_out = -1; + } + arcs.clear(); + } + + void first(Node& node) const { + _graph->first(node); + } + + void next(Node& node) const { + _graph->next(node); + } + + void first(Arc& arc) const { + arc.id = arcs.size() - 1; + } + + static void next(Arc& arc) { + --arc.id; + } + + void first(Edge& arc) const { + arc.id = arcs.size() / 2 - 1; + } + + static void next(Edge& arc) { + --arc.id; + } + + void firstOut(Arc& arc, const Node& node) const { + arc.id = (*_nodes)[node].first_out; + } + + void nextOut(Arc& arc) const { + arc.id = arcs[arc.id].next_out; + } + + void firstIn(Arc& arc, const Node& node) const { + arc.id = (((*_nodes)[node].first_out) ^ 1); + if (arc.id == -2) arc.id = -1; + } + + void nextIn(Arc& arc) const { + arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1); + if (arc.id == -2) arc.id = -1; + } + + void firstInc(Edge &arc, bool& dir, const Node& node) const { + int de = (*_nodes)[node].first_out; + if (de != -1 ) { + arc.id = de / 2; + dir = ((de & 1) == 1); + } else { + arc.id = -1; + dir = true; + } + } + void nextInc(Edge &arc, bool& dir) const { + int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out); + if (de != -1 ) { + arc.id = de / 2; + dir = ((de & 1) == 1); + } else { + arc.id = -1; + dir = true; + } + } + + static bool direction(Arc arc) { + return (arc.id & 1) == 1; + } + + static Arc direct(Edge edge, bool dir) { + return Arc(edge.id * 2 + (dir ? 1 : 0)); + } + + int id(Node node) const { return _graph->id(node); } + static int id(Arc arc) { return arc.id; } + static int id(Edge arc) { return arc.id; } + + Node nodeFromId(int id) const { return _graph->nodeFromId(id); } + static Arc arcFromId(int id) { return Arc(id); } + static Edge edgeFromId(int id) { return Edge(id);} + + int maxNodeId() const { return _graph->maxNodeId(); }; + int maxArcId() const { return arcs.size() - 1; } + int maxEdgeId() const { return arcs.size() / 2 - 1; } + + Node source(Arc e) const { return arcs[e.id ^ 1].target; } + Node target(Arc e) const { return arcs[e.id].target; } + + Node u(Edge e) const { return arcs[2 * e.id].target; } + Node v(Edge e) const { return arcs[2 * e.id + 1].target; } + + typedef typename ItemSetTraits::ItemNotifier NodeNotifier; + + NodeNotifier& notifier(Node) const { + return _graph->notifier(Node()); + } + + template + class NodeMap : public GR::template NodeMap { + typedef typename GR::template NodeMap Parent; + + public: + + explicit NodeMap(const SmartEdgeSetBase& arcset) + : Parent(*arcset._graph) { } + + NodeMap(const SmartEdgeSetBase& arcset, const V& value) + : Parent(*arcset._graph, value) { } + + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + template + NodeMap& operator=(const CMap& cmap) { + Parent::operator=(cmap); + return *this; + } + }; + + }; + + /// \ingroup graphs + /// + /// \brief Graph using a node set of another digraph or graph and an + /// own edge set. + /// + /// This structure can be used to establish another graph over a + /// node set of an existing one. This class uses the same Node type + /// as the underlying graph, and each valid node of the original + /// graph is valid in this arc set, therefore the node objects of + /// the original graph can be used directly with this class. The + /// node handling functions (id handling, observing, and iterators) + /// works equivalently as in the original graph. + /// + /// \param GR The type of the graph which shares its node set + /// with this class. Its interface must conform to the + /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph" + /// concept. + /// + /// This implementation is slightly faster than the \c ListEdgeSet, + /// because it uses continuous storage for edges and it uses just + /// single-linked lists for enumerate incident edges. Therefore the + /// edges cannot be erased from the edge sets. + /// + /// This class fully conforms to the \ref concepts::Graph "Graph" + /// concept. + /// It provides only linear time counting for nodes, edges and arcs. + /// + /// \warning If a node is erased from the underlying graph and this + /// node is incident to one edge in the edge set, then the edge set + /// is invalidated, and it cannot be used anymore. The validity can + /// be checked with the \c valid() member function. + template + class SmartEdgeSet : public EdgeSetExtender > { + typedef EdgeSetExtender > Parent; + + public: + + typedef typename Parent::Node Node; + typedef typename Parent::Arc Arc; + typedef typename Parent::Edge Edge; + + protected: + + typedef typename Parent::NodesImplBase NodesImplBase; + + void eraseNode(const Node& node) { + if (typename Parent::IncEdgeIt(*this, node) == INVALID) { + return; + } + throw typename NodesImplBase::Notifier::ImmediateDetach(); + } + + void clearNodes() { + Parent::clear(); + } + + class NodesImpl : public NodesImplBase { + typedef NodesImplBase Parent; + + public: + NodesImpl(const GR& graph, SmartEdgeSet& arcset) + : Parent(graph), _arcset(arcset) {} + + virtual ~NodesImpl() {} + + bool attached() const { + return Parent::attached(); + } + + protected: + + virtual void erase(const Node& node) { + try { + _arcset.eraseNode(node); + Parent::erase(node); + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { + Parent::clear(); + throw; + } + } + virtual void erase(const std::vector& nodes) { + try { + for (int i = 0; i < int(nodes.size()); ++i) { + _arcset.eraseNode(nodes[i]); + } + Parent::erase(nodes); + } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) { + Parent::clear(); + throw; + } + } + virtual void clear() { + _arcset.clearNodes(); + Parent::clear(); + } + + private: + SmartEdgeSet& _arcset; + }; + + NodesImpl _nodes; + + public: + + /// \brief Constructor of the EdgeSet. + /// + /// Constructor of the EdgeSet. + SmartEdgeSet(const GR& graph) : _nodes(graph, *this) { + Parent::initalize(graph, _nodes); + } + + /// \brief Add a new edge to the graph. + /// + /// Add a new edge to the graph with node \c u + /// and node \c v endpoints. + /// \return The new edge. + Edge addEdge(const Node& u, const Node& v) { + return Parent::addEdge(u, v); + } + + /// \brief Validity check + /// + /// This functions gives back false if the EdgeSet is + /// invalidated. It occurs when a node in the underlying graph is + /// erased and it is not isolated in the EdgeSet. + bool valid() const { + return _nodes.attached(); + } + + }; + +} + +#endif diff --git a/lemon/lemon/elevator.h b/lemon/lemon/elevator.h new file mode 100644 index 0000000..e4adcd5 --- /dev/null +++ b/lemon/lemon/elevator.h @@ -0,0 +1,982 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_ELEVATOR_H +#define LEMON_ELEVATOR_H + +///\ingroup auxdat +///\file +///\brief Elevator class +/// +///Elevator class implements an efficient data structure +///for labeling items in push-relabel type algorithms. +/// + +#include +#include + +namespace lemon { + + ///Class for handling "labels" in push-relabel type algorithms. + + ///A class for handling "labels" in push-relabel type algorithms. + /// + ///\ingroup auxdat + ///Using this class you can assign "labels" (nonnegative integer numbers) + ///to the edges or nodes of a graph, manipulate and query them through + ///operations typically arising in "push-relabel" type algorithms. + /// + ///Each item is either \em active or not, and you can also choose a + ///highest level active item. + /// + ///\sa LinkedElevator + /// + ///\param GR Type of the underlying graph. + ///\param Item Type of the items the data is assigned to (\c GR::Node, + ///\c GR::Arc or \c GR::Edge). + template + class Elevator + { + public: + + typedef Item Key; + typedef int Value; + + private: + + typedef Item *Vit; + typedef typename ItemSetTraits::template Map::Type VitMap; + typedef typename ItemSetTraits::template Map::Type IntMap; + + const GR &_g; + int _max_level; + int _item_num; + VitMap _where; + IntMap _level; + std::vector _items; + std::vector _first; + std::vector _last_active; + + int _highest_active; + + void copy(Item i, Vit p) + { + _where[*p=i] = p; + } + void copy(Vit s, Vit p) + { + if(s!=p) + { + Item i=*s; + *p=i; + _where[i] = p; + } + } + void swap(Vit i, Vit j) + { + Item ti=*i; + Vit ct = _where[ti]; + _where[ti] = _where[*i=*j]; + _where[*j] = ct; + *j=ti; + } + + public: + + ///Constructor with given maximum level. + + ///Constructor with given maximum level. + /// + ///\param graph The underlying graph. + ///\param max_level The maximum allowed level. + ///Set the range of the possible labels to [0..max_level]. + Elevator(const GR &graph,int max_level) : + _g(graph), + _max_level(max_level), + _item_num(_max_level), + _where(graph), + _level(graph,0), + _items(_max_level), + _first(_max_level+2), + _last_active(_max_level+2), + _highest_active(-1) {} + ///Constructor. + + ///Constructor. + /// + ///\param graph The underlying graph. + ///Set the range of the possible labels to [0..max_level], + ///where \c max_level is equal to the number of labeled items in the graph. + Elevator(const GR &graph) : + _g(graph), + _max_level(countItems(graph)), + _item_num(_max_level), + _where(graph), + _level(graph,0), + _items(_max_level), + _first(_max_level+2), + _last_active(_max_level+2), + _highest_active(-1) + { + } + + ///Activate item \c i. + + ///Activate item \c i. + ///\pre Item \c i shouldn't be active before. + void activate(Item i) + { + const int l=_level[i]; + swap(_where[i],++_last_active[l]); + if(l>_highest_active) _highest_active=l; + } + + ///Deactivate item \c i. + + ///Deactivate item \c i. + ///\pre Item \c i must be active before. + void deactivate(Item i) + { + swap(_where[i],_last_active[_level[i]]--); + while(_highest_active>=0 && + _last_active[_highest_active]<_first[_highest_active]) + _highest_active--; + } + + ///Query whether item \c i is active + bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; } + + ///Return the level of item \c i. + int operator[](Item i) const { return _level[i]; } + + ///Return the number of items on level \c l. + int onLevel(int l) const + { + return _first[l+1]-_first[l]; + } + ///Return true if level \c l is empty. + bool emptyLevel(int l) const + { + return _first[l+1]-_first[l]==0; + } + ///Return the number of items above level \c l. + int aboveLevel(int l) const + { + return _first[_max_level+1]-_first[l+1]; + } + ///Return the number of active items on level \c l. + int activesOnLevel(int l) const + { + return _last_active[l]-_first[l]+1; + } + ///Return true if there is no active item on level \c l. + bool activeFree(int l) const + { + return _last_active[l]<_first[l]; + } + ///Return the maximum allowed level. + int maxLevel() const + { + return _max_level; + } + + ///\name Highest Active Item + ///Functions for working with the highest level + ///active item. + + ///@{ + + ///Return a highest level active item. + + ///Return a highest level active item or INVALID if there is no active + ///item. + Item highestActive() const + { + return _highest_active>=0?*_last_active[_highest_active]:INVALID; + } + + ///Return the highest active level. + + ///Return the level of the highest active item or -1 if there is no active + ///item. + int highestActiveLevel() const + { + return _highest_active; + } + + ///Lift the highest active item by one. + + ///Lift the item returned by highestActive() by one. + /// + void liftHighestActive() + { + Item it = *_last_active[_highest_active]; + ++_level[it]; + swap(_last_active[_highest_active]--,_last_active[_highest_active+1]); + --_first[++_highest_active]; + } + + ///Lift the highest active item to the given level. + + ///Lift the item returned by highestActive() to level \c new_level. + /// + ///\warning \c new_level must be strictly higher + ///than the current level. + /// + void liftHighestActive(int new_level) + { + const Item li = *_last_active[_highest_active]; + + copy(--_first[_highest_active+1],_last_active[_highest_active]--); + for(int l=_highest_active+1;l=0 && + _last_active[_highest_active]<_first[_highest_active]) + _highest_active--; + } + + ///@} + + ///\name Active Item on Certain Level + ///Functions for working with the active items. + + ///@{ + + ///Return an active item on level \c l. + + ///Return an active item on level \c l or \ref INVALID if there is no such + ///an item. (\c l must be from the range [0...\c max_level]. + Item activeOn(int l) const + { + return _last_active[l]>=_first[l]?*_last_active[l]:INVALID; + } + + ///Lift the active item returned by \c activeOn(level) by one. + + ///Lift the active item returned by \ref activeOn() "activeOn(level)" + ///by one. + Item liftActiveOn(int level) + { + Item it =*_last_active[level]; + ++_level[it]; + swap(_last_active[level]--, --_first[level+1]); + if (level+1>_highest_active) ++_highest_active; + } + + ///Lift the active item returned by \c activeOn(level) to the given level. + + ///Lift the active item returned by \ref activeOn() "activeOn(level)" + ///to the given level. + void liftActiveOn(int level, int new_level) + { + const Item ai = *_last_active[level]; + + copy(--_first[level+1], _last_active[level]--); + for(int l=level+1;l_highest_active) _highest_active=new_level; + } + + ///Lift the active item returned by \c activeOn(level) to the top level. + + ///Lift the active item returned by \ref activeOn() "activeOn(level)" + ///to the top level and deactivate it. + void liftActiveToTop(int level) + { + const Item ai = *_last_active[level]; + + copy(--_first[level+1],_last_active[level]--); + for(int l=level+1;l<_max_level;l++) + { + copy(_last_active[l],_first[l]); + copy(--_first[l+1], _last_active[l]--); + } + copy(ai,_first[_max_level]); + --_last_active[_max_level]; + _level[ai] = _max_level; + + if (_highest_active==level) { + while(_highest_active>=0 && + _last_active[_highest_active]<_first[_highest_active]) + _highest_active--; + } + } + + ///@} + + ///Lift an active item to a higher level. + + ///Lift an active item to a higher level. + ///\param i The item to be lifted. It must be active. + ///\param new_level The new level of \c i. It must be strictly higher + ///than the current level. + /// + void lift(Item i, int new_level) + { + const int lo = _level[i]; + const Vit w = _where[i]; + + copy(_last_active[lo],w); + copy(--_first[lo+1],_last_active[lo]--); + for(int l=lo+1;l_highest_active) _highest_active=new_level; + } + + ///Move an inactive item to the top but one level (in a dirty way). + + ///This function moves an inactive item from the top level to the top + ///but one level (in a dirty way). + ///\warning It makes the underlying datastructure corrupt, so use it + ///only if you really know what it is for. + ///\pre The item is on the top level. + void dirtyTopButOne(Item i) { + _level[i] = _max_level - 1; + } + + ///Lift all items on and above the given level to the top level. + + ///This function lifts all items on and above level \c l to the top + ///level and deactivates them. + void liftToTop(int l) + { + const Vit f=_first[l]; + const Vit tl=_first[_max_level]; + for(Vit i=f;i!=tl;++i) + _level[*i] = _max_level; + for(int i=l;i<=_max_level;i++) + { + _first[i]=f; + _last_active[i]=f-1; + } + for(_highest_active=l-1; + _highest_active>=0 && + _last_active[_highest_active]<_first[_highest_active]; + _highest_active--) ; + } + + private: + int _init_lev; + Vit _init_num; + + public: + + ///\name Initialization + ///Using these functions you can initialize the levels of the items. + ///\n + ///The initialization must be started with calling \c initStart(). + ///Then the items should be listed level by level starting with the + ///lowest one (level 0) using \c initAddItem() and \c initNewLevel(). + ///Finally \c initFinish() must be called. + ///The items not listed are put on the highest level. + ///@{ + + ///Start the initialization process. + void initStart() + { + _init_lev=0; + _init_num=&_items[0]; + _first[0]=&_items[0]; + _last_active[0]=&_items[0]-1; + Vit n=&_items[0]; + for(typename ItemSetTraits::ItemIt i(_g);i!=INVALID;++i) + { + *n=i; + _where[i] = n; + _level[i] = _max_level; + ++n; + } + } + + ///Add an item to the current level. + void initAddItem(Item i) + { + swap(_where[i],_init_num); + _level[i] = _init_lev; + ++_init_num; + } + + ///Start a new level. + + ///Start a new level. + ///It shouldn't be used before the items on level 0 are listed. + void initNewLevel() + { + _init_lev++; + _first[_init_lev]=_init_num; + _last_active[_init_lev]=_init_num-1; + } + + ///Finalize the initialization process. + void initFinish() + { + for(_init_lev++;_init_lev<=_max_level;_init_lev++) + { + _first[_init_lev]=_init_num; + _last_active[_init_lev]=_init_num-1; + } + _first[_max_level+1]=&_items[0]+_item_num; + _last_active[_max_level+1]=&_items[0]+_item_num-1; + _highest_active = -1; + } + + ///@} + + }; + + ///Class for handling "labels" in push-relabel type algorithms. + + ///A class for handling "labels" in push-relabel type algorithms. + /// + ///\ingroup auxdat + ///Using this class you can assign "labels" (nonnegative integer numbers) + ///to the edges or nodes of a graph, manipulate and query them through + ///operations typically arising in "push-relabel" type algorithms. + /// + ///Each item is either \em active or not, and you can also choose a + ///highest level active item. + /// + ///\sa Elevator + /// + ///\param GR Type of the underlying graph. + ///\param Item Type of the items the data is assigned to (\c GR::Node, + ///\c GR::Arc or \c GR::Edge). + template + class LinkedElevator { + public: + + typedef Item Key; + typedef int Value; + + private: + + typedef typename ItemSetTraits:: + template Map::Type ItemMap; + typedef typename ItemSetTraits:: + template Map::Type IntMap; + typedef typename ItemSetTraits:: + template Map::Type BoolMap; + + const GR &_graph; + int _max_level; + int _item_num; + std::vector _first, _last; + ItemMap _prev, _next; + int _highest_active; + IntMap _level; + BoolMap _active; + + public: + ///Constructor with given maximum level. + + ///Constructor with given maximum level. + /// + ///\param graph The underlying graph. + ///\param max_level The maximum allowed level. + ///Set the range of the possible labels to [0..max_level]. + LinkedElevator(const GR& graph, int max_level) + : _graph(graph), _max_level(max_level), _item_num(_max_level), + _first(_max_level + 1), _last(_max_level + 1), + _prev(graph), _next(graph), + _highest_active(-1), _level(graph), _active(graph) {} + + ///Constructor. + + ///Constructor. + /// + ///\param graph The underlying graph. + ///Set the range of the possible labels to [0..max_level], + ///where \c max_level is equal to the number of labeled items in the graph. + LinkedElevator(const GR& graph) + : _graph(graph), _max_level(countItems(graph)), + _item_num(_max_level), + _first(_max_level + 1), _last(_max_level + 1), + _prev(graph, INVALID), _next(graph, INVALID), + _highest_active(-1), _level(graph), _active(graph) {} + + + ///Activate item \c i. + + ///Activate item \c i. + ///\pre Item \c i shouldn't be active before. + void activate(Item i) { + _active[i] = true; + + int level = _level[i]; + if (level > _highest_active) { + _highest_active = level; + } + + if (_prev[i] == INVALID || _active[_prev[i]]) return; + //unlace + _next[_prev[i]] = _next[i]; + if (_next[i] != INVALID) { + _prev[_next[i]] = _prev[i]; + } else { + _last[level] = _prev[i]; + } + //lace + _next[i] = _first[level]; + _prev[_first[level]] = i; + _prev[i] = INVALID; + _first[level] = i; + + } + + ///Deactivate item \c i. + + ///Deactivate item \c i. + ///\pre Item \c i must be active before. + void deactivate(Item i) { + _active[i] = false; + int level = _level[i]; + + if (_next[i] == INVALID || !_active[_next[i]]) + goto find_highest_level; + + //unlace + _prev[_next[i]] = _prev[i]; + if (_prev[i] != INVALID) { + _next[_prev[i]] = _next[i]; + } else { + _first[_level[i]] = _next[i]; + } + //lace + _prev[i] = _last[level]; + _next[_last[level]] = i; + _next[i] = INVALID; + _last[level] = i; + + find_highest_level: + if (level == _highest_active) { + while (_highest_active >= 0 && activeFree(_highest_active)) + --_highest_active; + } + } + + ///Query whether item \c i is active + bool active(Item i) const { return _active[i]; } + + ///Return the level of item \c i. + int operator[](Item i) const { return _level[i]; } + + ///Return the number of items on level \c l. + int onLevel(int l) const { + int num = 0; + Item n = _first[l]; + while (n != INVALID) { + ++num; + n = _next[n]; + } + return num; + } + + ///Return true if the level is empty. + bool emptyLevel(int l) const { + return _first[l] == INVALID; + } + + ///Return the number of items above level \c l. + int aboveLevel(int l) const { + int num = 0; + for (int level = l + 1; level < _max_level; ++level) + num += onLevel(level); + return num; + } + + ///Return the number of active items on level \c l. + int activesOnLevel(int l) const { + int num = 0; + Item n = _first[l]; + while (n != INVALID && _active[n]) { + ++num; + n = _next[n]; + } + return num; + } + + ///Return true if there is no active item on level \c l. + bool activeFree(int l) const { + return _first[l] == INVALID || !_active[_first[l]]; + } + + ///Return the maximum allowed level. + int maxLevel() const { + return _max_level; + } + + ///\name Highest Active Item + ///Functions for working with the highest level + ///active item. + + ///@{ + + ///Return a highest level active item. + + ///Return a highest level active item or INVALID if there is no active + ///item. + Item highestActive() const { + return _highest_active >= 0 ? _first[_highest_active] : INVALID; + } + + ///Return the highest active level. + + ///Return the level of the highest active item or -1 if there is no active + ///item. + int highestActiveLevel() const { + return _highest_active; + } + + ///Lift the highest active item by one. + + ///Lift the item returned by highestActive() by one. + /// + void liftHighestActive() { + Item i = _first[_highest_active]; + if (_next[i] != INVALID) { + _prev[_next[i]] = INVALID; + _first[_highest_active] = _next[i]; + } else { + _first[_highest_active] = INVALID; + _last[_highest_active] = INVALID; + } + _level[i] = ++_highest_active; + if (_first[_highest_active] == INVALID) { + _first[_highest_active] = i; + _last[_highest_active] = i; + _prev[i] = INVALID; + _next[i] = INVALID; + } else { + _prev[_first[_highest_active]] = i; + _next[i] = _first[_highest_active]; + _first[_highest_active] = i; + } + } + + ///Lift the highest active item to the given level. + + ///Lift the item returned by highestActive() to level \c new_level. + /// + ///\warning \c new_level must be strictly higher + ///than the current level. + /// + void liftHighestActive(int new_level) { + Item i = _first[_highest_active]; + if (_next[i] != INVALID) { + _prev[_next[i]] = INVALID; + _first[_highest_active] = _next[i]; + } else { + _first[_highest_active] = INVALID; + _last[_highest_active] = INVALID; + } + _level[i] = _highest_active = new_level; + if (_first[_highest_active] == INVALID) { + _first[_highest_active] = _last[_highest_active] = i; + _prev[i] = INVALID; + _next[i] = INVALID; + } else { + _prev[_first[_highest_active]] = i; + _next[i] = _first[_highest_active]; + _first[_highest_active] = i; + } + } + + ///Lift the highest active item to the top level. + + ///Lift the item returned by highestActive() to the top level and + ///deactivate it. + void liftHighestActiveToTop() { + Item i = _first[_highest_active]; + _level[i] = _max_level; + if (_next[i] != INVALID) { + _prev[_next[i]] = INVALID; + _first[_highest_active] = _next[i]; + } else { + _first[_highest_active] = INVALID; + _last[_highest_active] = INVALID; + } + while (_highest_active >= 0 && activeFree(_highest_active)) + --_highest_active; + } + + ///@} + + ///\name Active Item on Certain Level + ///Functions for working with the active items. + + ///@{ + + ///Return an active item on level \c l. + + ///Return an active item on level \c l or \ref INVALID if there is no such + ///an item. (\c l must be from the range [0...\c max_level]. + Item activeOn(int l) const + { + return _active[_first[l]] ? _first[l] : INVALID; + } + + ///Lift the active item returned by \c activeOn(l) by one. + + ///Lift the active item returned by \ref activeOn() "activeOn(l)" + ///by one. + Item liftActiveOn(int l) + { + Item i = _first[l]; + if (_next[i] != INVALID) { + _prev[_next[i]] = INVALID; + _first[l] = _next[i]; + } else { + _first[l] = INVALID; + _last[l] = INVALID; + } + _level[i] = ++l; + if (_first[l] == INVALID) { + _first[l] = _last[l] = i; + _prev[i] = INVALID; + _next[i] = INVALID; + } else { + _prev[_first[l]] = i; + _next[i] = _first[l]; + _first[l] = i; + } + if (_highest_active < l) { + _highest_active = l; + } + } + + ///Lift the active item returned by \c activeOn(l) to the given level. + + ///Lift the active item returned by \ref activeOn() "activeOn(l)" + ///to the given level. + void liftActiveOn(int l, int new_level) + { + Item i = _first[l]; + if (_next[i] != INVALID) { + _prev[_next[i]] = INVALID; + _first[l] = _next[i]; + } else { + _first[l] = INVALID; + _last[l] = INVALID; + } + _level[i] = l = new_level; + if (_first[l] == INVALID) { + _first[l] = _last[l] = i; + _prev[i] = INVALID; + _next[i] = INVALID; + } else { + _prev[_first[l]] = i; + _next[i] = _first[l]; + _first[l] = i; + } + if (_highest_active < l) { + _highest_active = l; + } + } + + ///Lift the active item returned by \c activeOn(l) to the top level. + + ///Lift the active item returned by \ref activeOn() "activeOn(l)" + ///to the top level and deactivate it. + void liftActiveToTop(int l) + { + Item i = _first[l]; + if (_next[i] != INVALID) { + _prev[_next[i]] = INVALID; + _first[l] = _next[i]; + } else { + _first[l] = INVALID; + _last[l] = INVALID; + } + _level[i] = _max_level; + if (l == _highest_active) { + while (_highest_active >= 0 && activeFree(_highest_active)) + --_highest_active; + } + } + + ///@} + + /// \brief Lift an active item to a higher level. + /// + /// Lift an active item to a higher level. + /// \param i The item to be lifted. It must be active. + /// \param new_level The new level of \c i. It must be strictly higher + /// than the current level. + /// + void lift(Item i, int new_level) { + if (_next[i] != INVALID) { + _prev[_next[i]] = _prev[i]; + } else { + _last[new_level] = _prev[i]; + } + if (_prev[i] != INVALID) { + _next[_prev[i]] = _next[i]; + } else { + _first[new_level] = _next[i]; + } + _level[i] = new_level; + if (_first[new_level] == INVALID) { + _first[new_level] = _last[new_level] = i; + _prev[i] = INVALID; + _next[i] = INVALID; + } else { + _prev[_first[new_level]] = i; + _next[i] = _first[new_level]; + _first[new_level] = i; + } + if (_highest_active < new_level) { + _highest_active = new_level; + } + } + + ///Move an inactive item to the top but one level (in a dirty way). + + ///This function moves an inactive item from the top level to the top + ///but one level (in a dirty way). + ///\warning It makes the underlying datastructure corrupt, so use it + ///only if you really know what it is for. + ///\pre The item is on the top level. + void dirtyTopButOne(Item i) { + _level[i] = _max_level - 1; + } + + ///Lift all items on and above the given level to the top level. + + ///This function lifts all items on and above level \c l to the top + ///level and deactivates them. + void liftToTop(int l) { + for (int i = l + 1; _first[i] != INVALID; ++i) { + Item n = _first[i]; + while (n != INVALID) { + _level[n] = _max_level; + n = _next[n]; + } + _first[i] = INVALID; + _last[i] = INVALID; + } + if (_highest_active > l - 1) { + _highest_active = l - 1; + while (_highest_active >= 0 && activeFree(_highest_active)) + --_highest_active; + } + } + + private: + + int _init_level; + + public: + + ///\name Initialization + ///Using these functions you can initialize the levels of the items. + ///\n + ///The initialization must be started with calling \c initStart(). + ///Then the items should be listed level by level starting with the + ///lowest one (level 0) using \c initAddItem() and \c initNewLevel(). + ///Finally \c initFinish() must be called. + ///The items not listed are put on the highest level. + ///@{ + + ///Start the initialization process. + void initStart() { + + for (int i = 0; i <= _max_level; ++i) { + _first[i] = _last[i] = INVALID; + } + _init_level = 0; + for(typename ItemSetTraits::ItemIt i(_graph); + i != INVALID; ++i) { + _level[i] = _max_level; + _active[i] = false; + } + } + + ///Add an item to the current level. + void initAddItem(Item i) { + _level[i] = _init_level; + if (_last[_init_level] == INVALID) { + _first[_init_level] = i; + _last[_init_level] = i; + _prev[i] = INVALID; + _next[i] = INVALID; + } else { + _prev[i] = _last[_init_level]; + _next[i] = INVALID; + _next[_last[_init_level]] = i; + _last[_init_level] = i; + } + } + + ///Start a new level. + + ///Start a new level. + ///It shouldn't be used before the items on level 0 are listed. + void initNewLevel() { + ++_init_level; + } + + ///Finalize the initialization process. + void initFinish() { + _highest_active = -1; + } + + ///@} + + }; + + +} //END OF NAMESPACE LEMON + +#endif + diff --git a/lemon/lemon/error.h b/lemon/lemon/error.h new file mode 100644 index 0000000..f937704 --- /dev/null +++ b/lemon/lemon/error.h @@ -0,0 +1,276 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_ERROR_H +#define LEMON_ERROR_H + +/// \ingroup exceptions +/// \file +/// \brief Basic exception classes and error handling. + +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \addtogroup exceptions + /// @{ + + /// \brief Generic exception class. + /// + /// Base class for exceptions used in LEMON. + /// + class Exception : public std::exception { + public: + ///Constructor + Exception() throw() {} + ///Virtual destructor + virtual ~Exception() throw() {} + ///A short description of the exception + virtual const char* what() const throw() { + return "lemon::Exception"; + } + }; + + /// \brief Input-Output error + /// + /// This exception is thrown when a file operation cannot be + /// succeeded. + class IoError : public Exception { + protected: + std::string _message; + std::string _file; + + mutable std::string _what; + public: + + /// Copy constructor + IoError(const IoError &error) throw() : Exception() { + message(error._message); + file(error._file); + } + + /// Constructor + explicit IoError(const char *message) throw() { + IoError::message(message); + } + + /// Constructor + explicit IoError(const std::string &message) throw() { + IoError::message(message); + } + + /// Constructor + explicit IoError(const char *message, + const std::string &file) throw() { + IoError::message(message); + IoError::file(file); + } + + /// Constructor + explicit IoError(const std::string &message, + const std::string &file) throw() { + IoError::message(message); + IoError::file(file); + } + + /// Virtual destructor + virtual ~IoError() throw() {} + + /// Set the error message + void message(const char *message) throw() { + try { + _message = message; + } catch (...) {} + } + + /// Set the error message + void message(const std::string& message) throw() { + try { + _message = message; + } catch (...) {} + } + + /// Set the file name + void file(const std::string &file) throw() { + try { + _file = file; + } catch (...) {} + } + + /// Returns the error message + const std::string& message() const throw() { + return _message; + } + + /// \brief Returns the filename + /// + /// Returns the filename or an empty string if it was not specified. + const std::string& file() const throw() { + return _file; + } + + /// \brief Returns a short error message + /// + /// Returns a short error message which contains the message and the + /// file name. + virtual const char* what() const throw() { + try { + _what.clear(); + std::ostringstream oss; + oss << "lemon:IoError" << ": "; + oss << _message; + if (!_file.empty()) { + oss << " ('" << _file << "')"; + } + _what = oss.str(); + } + catch (...) {} + if (!_what.empty()) return _what.c_str(); + else return "lemon:IoError"; + } + + }; + + /// \brief Format error + /// + /// This exception is thrown when an input file has wrong + /// format or a data representation is not legal. + class FormatError : public Exception { + protected: + std::string _message; + std::string _file; + int _line; + + mutable std::string _what; + public: + + /// Copy constructor + FormatError(const FormatError &error) throw() : Exception() { + message(error._message); + file(error._file); + line(error._line); + } + + /// Constructor + explicit FormatError(const char *message) throw() { + FormatError::message(message); + _line = 0; + } + + /// Constructor + explicit FormatError(const std::string &message) throw() { + FormatError::message(message); + _line = 0; + } + + /// Constructor + explicit FormatError(const char *message, + const std::string &file, int line = 0) throw() { + FormatError::message(message); + FormatError::file(file); + FormatError::line(line); + } + + /// Constructor + explicit FormatError(const std::string &message, + const std::string &file, int line = 0) throw() { + FormatError::message(message); + FormatError::file(file); + FormatError::line(line); + } + + /// Virtual destructor + virtual ~FormatError() throw() {} + + /// Set the line number + void line(int line) throw() { _line = line; } + + /// Set the error message + void message(const char *message) throw() { + try { + _message = message; + } catch (...) {} + } + + /// Set the error message + void message(const std::string& message) throw() { + try { + _message = message; + } catch (...) {} + } + + /// Set the file name + void file(const std::string &file) throw() { + try { + _file = file; + } catch (...) {} + } + + /// \brief Returns the line number + /// + /// Returns the line number or zero if it was not specified. + int line() const throw() { return _line; } + + /// Returns the error message + const std::string& message() const throw() { + return _message; + } + + /// \brief Returns the filename + /// + /// Returns the filename or an empty string if it was not specified. + const std::string& file() const throw() { + return _file; + } + + /// \brief Returns a short error message + /// + /// Returns a short error message which contains the message, the + /// file name and the line number. + virtual const char* what() const throw() { + try { + _what.clear(); + std::ostringstream oss; + oss << "lemon:FormatError" << ": "; + oss << _message; + if (!_file.empty() || _line != 0) { + oss << " ("; + if (!_file.empty()) oss << "in file '" << _file << "'"; + if (!_file.empty() && _line != 0) oss << " "; + if (_line != 0) oss << "at line " << _line; + oss << ")"; + } + _what = oss.str(); + } + catch (...) {} + if (!_what.empty()) return _what.c_str(); + else return "lemon:FormatError"; + } + + }; + + /// @} + +} + +#endif // LEMON_ERROR_H diff --git a/lemon/lemon/euler.h b/lemon/lemon/euler.h new file mode 100644 index 0000000..41b8244 --- /dev/null +++ b/lemon/lemon/euler.h @@ -0,0 +1,287 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_EULER_H +#define LEMON_EULER_H + +#include +#include +#include +#include + +/// \ingroup graph_properties +/// \file +/// \brief Euler tour iterators and a function for checking the \e Eulerian +/// property. +/// +///This file provides Euler tour iterators and a function to check +///if a (di)graph is \e Eulerian. + +namespace lemon { + + ///Euler tour iterator for digraphs. + + /// \ingroup graph_prop + ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed + ///graph (if there exists) and it converts to the \c Arc type of the digraph. + /// + ///For example, if the given digraph has an Euler tour (i.e it has only one + ///non-trivial component and the in-degree is equal to the out-degree + ///for all nodes), then the following code will put the arcs of \c g + ///to the vector \c et according to an Euler tour of \c g. + ///\code + /// std::vector et; + /// for(DiEulerIt e(g); e!=INVALID; ++e) + /// et.push_back(e); + ///\endcode + ///If \c g has no Euler tour, then the resulted walk will not be closed + ///or not contain all arcs. + ///\sa EulerIt + template + class DiEulerIt + { + typedef typename GR::Node Node; + typedef typename GR::NodeIt NodeIt; + typedef typename GR::Arc Arc; + typedef typename GR::ArcIt ArcIt; + typedef typename GR::OutArcIt OutArcIt; + typedef typename GR::InArcIt InArcIt; + + const GR &g; + typename GR::template NodeMap narc; + std::list euler; + + public: + + ///Constructor + + ///Constructor. + ///\param gr A digraph. + ///\param start The starting point of the tour. If it is not given, + ///the tour will start from the first node that has an outgoing arc. + DiEulerIt(const GR &gr, typename GR::Node start = INVALID) + : g(gr), narc(g) + { + if (start==INVALID) { + NodeIt n(g); + while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n; + start=n; + } + if (start!=INVALID) { + for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n); + while (narc[start]!=INVALID) { + euler.push_back(narc[start]); + Node next=g.target(narc[start]); + ++narc[start]; + start=next; + } + } + } + + ///Arc conversion + operator Arc() { return euler.empty()?INVALID:euler.front(); } + ///Compare with \c INVALID + bool operator==(Invalid) { return euler.empty(); } + ///Compare with \c INVALID + bool operator!=(Invalid) { return !euler.empty(); } + + ///Next arc of the tour + + ///Next arc of the tour + /// + DiEulerIt &operator++() { + Node s=g.target(euler.front()); + euler.pop_front(); + typename std::list::iterator next=euler.begin(); + while(narc[s]!=INVALID) { + euler.insert(next,narc[s]); + Node n=g.target(narc[s]); + ++narc[s]; + s=n; + } + return *this; + } + ///Postfix incrementation + + /// Postfix incrementation. + /// + ///\warning This incrementation + ///returns an \c Arc, not a \ref DiEulerIt, as one may + ///expect. + Arc operator++(int) + { + Arc e=*this; + ++(*this); + return e; + } + }; + + ///Euler tour iterator for graphs. + + /// \ingroup graph_properties + ///This iterator provides an Euler tour (Eulerian circuit) of an + ///\e undirected graph (if there exists) and it converts to the \c Arc + ///and \c Edge types of the graph. + /// + ///For example, if the given graph has an Euler tour (i.e it has only one + ///non-trivial component and the degree of each node is even), + ///the following code will print the arc IDs according to an + ///Euler tour of \c g. + ///\code + /// for(EulerIt e(g); e!=INVALID; ++e) { + /// std::cout << g.id(Edge(e)) << std::eol; + /// } + ///\endcode + ///Although this iterator is for undirected graphs, it still returns + ///arcs in order to indicate the direction of the tour. + ///(But arcs convert to edges, of course.) + /// + ///If \c g has no Euler tour, then the resulted walk will not be closed + ///or not contain all edges. + template + class EulerIt + { + typedef typename GR::Node Node; + typedef typename GR::NodeIt NodeIt; + typedef typename GR::Arc Arc; + typedef typename GR::Edge Edge; + typedef typename GR::ArcIt ArcIt; + typedef typename GR::OutArcIt OutArcIt; + typedef typename GR::InArcIt InArcIt; + + const GR &g; + typename GR::template NodeMap narc; + typename GR::template EdgeMap visited; + std::list euler; + + public: + + ///Constructor + + ///Constructor. + ///\param gr A graph. + ///\param start The starting point of the tour. If it is not given, + ///the tour will start from the first node that has an incident edge. + EulerIt(const GR &gr, typename GR::Node start = INVALID) + : g(gr), narc(g), visited(g, false) + { + if (start==INVALID) { + NodeIt n(g); + while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n; + start=n; + } + if (start!=INVALID) { + for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n); + while(narc[start]!=INVALID) { + euler.push_back(narc[start]); + visited[narc[start]]=true; + Node next=g.target(narc[start]); + ++narc[start]; + start=next; + while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start]; + } + } + } + + ///Arc conversion + operator Arc() const { return euler.empty()?INVALID:euler.front(); } + ///Edge conversion + operator Edge() const { return euler.empty()?INVALID:euler.front(); } + ///Compare with \c INVALID + bool operator==(Invalid) const { return euler.empty(); } + ///Compare with \c INVALID + bool operator!=(Invalid) const { return !euler.empty(); } + + ///Next arc of the tour + + ///Next arc of the tour + /// + EulerIt &operator++() { + Node s=g.target(euler.front()); + euler.pop_front(); + typename std::list::iterator next=euler.begin(); + while(narc[s]!=INVALID) { + while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s]; + if(narc[s]==INVALID) break; + else { + euler.insert(next,narc[s]); + visited[narc[s]]=true; + Node n=g.target(narc[s]); + ++narc[s]; + s=n; + } + } + return *this; + } + + ///Postfix incrementation + + /// Postfix incrementation. + /// + ///\warning This incrementation returns an \c Arc (which converts to + ///an \c Edge), not an \ref EulerIt, as one may expect. + Arc operator++(int) + { + Arc e=*this; + ++(*this); + return e; + } + }; + + + ///Check if the given graph is Eulerian + + /// \ingroup graph_properties + ///This function checks if the given graph is Eulerian. + ///It works for both directed and undirected graphs. + /// + ///By definition, a digraph is called \e Eulerian if + ///and only if it is connected and the number of incoming and outgoing + ///arcs are the same for each node. + ///Similarly, an undirected graph is called \e Eulerian if + ///and only if it is connected and the number of incident edges is even + ///for each node. + /// + ///\note There are (di)graphs that are not Eulerian, but still have an + /// Euler tour, since they may contain isolated nodes. + /// + ///\sa DiEulerIt, EulerIt + template +#ifdef DOXYGEN + bool +#else + typename enable_if,bool>::type + eulerian(const GR &g) + { + for(typename GR::NodeIt n(g);n!=INVALID;++n) + if(countIncEdges(g,n)%2) return false; + return connected(g); + } + template + typename disable_if,bool>::type +#endif + eulerian(const GR &g) + { + for(typename GR::NodeIt n(g);n!=INVALID;++n) + if(countInArcs(g,n)!=countOutArcs(g,n)) return false; + return connected(undirector(g)); + } + +} + +#endif diff --git a/lemon/lemon/fib_heap.h b/lemon/lemon/fib_heap.h new file mode 100644 index 0000000..3441722 --- /dev/null +++ b/lemon/lemon/fib_heap.h @@ -0,0 +1,475 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_FIB_HEAP_H +#define LEMON_FIB_HEAP_H + +///\file +///\ingroup heaps +///\brief Fibonacci heap implementation. + +#include +#include +#include +#include + +namespace lemon { + + /// \ingroup heaps + /// + /// \brief Fibonacci heap data structure. + /// + /// This class implements the \e Fibonacci \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". + /// + /// The methods \ref increase() and \ref erase() are not efficient in a + /// Fibonacci heap. In case of many calls of these operations, it is + /// better to use other heap structure, e.g. \ref BinHeap "binary heap". + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. +#ifdef DOXYGEN + template +#else + template > +#endif + class FibHeap { + public: + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + /// Functor type for comparing the priorities. + typedef CMP Compare; + + private: + class Store; + + std::vector _data; + int _minimum; + ItemIntMap &_iim; + Compare _comp; + int _num; + + public: + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit FibHeap(ItemIntMap &map) + : _minimum(0), _iim(map), _num() {} + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + FibHeap(ItemIntMap &map, const Compare &comp) + : _minimum(0), _iim(map), _comp(comp), _num() {} + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _num; } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _num==0; } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { + _data.clear(); _minimum = 0; _num = 0; + } + + /// \brief Insert an item into the heap with the given priority. + /// + /// This function inserts the given item into the heap with the + /// given priority. + /// \param item The item to insert. + /// \param prio The priority of the item. + /// \pre \e item must not be stored in the heap. + void push (const Item& item, const Prio& prio) { + int i=_iim[item]; + if ( i < 0 ) { + int s=_data.size(); + _iim.set( item, s ); + Store st; + st.name=item; + _data.push_back(st); + i=s; + } else { + _data[i].parent=_data[i].child=-1; + _data[i].degree=0; + _data[i].in=true; + _data[i].marked=false; + } + + if ( _num ) { + _data[_data[_minimum].right_neighbor].left_neighbor=i; + _data[i].right_neighbor=_data[_minimum].right_neighbor; + _data[_minimum].right_neighbor=i; + _data[i].left_neighbor=_minimum; + if ( _comp( prio, _data[_minimum].prio) ) _minimum=i; + } else { + _data[i].right_neighbor=_data[i].left_neighbor=i; + _minimum=i; + } + _data[i].prio=prio; + ++_num; + } + + /// \brief Return the item having minimum priority. + /// + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { return _data[_minimum].name; } + + /// \brief The minimum priority. + /// + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { return _data[_minimum].prio; } + + /// \brief Remove the item having minimum priority. + /// + /// This function removes the item having minimum priority. + /// \pre The heap must be non-empty. + void pop() { + /*The first case is that there are only one root.*/ + if ( _data[_minimum].left_neighbor==_minimum ) { + _data[_minimum].in=false; + if ( _data[_minimum].degree!=0 ) { + makeRoot(_data[_minimum].child); + _minimum=_data[_minimum].child; + balance(); + } + } else { + int right=_data[_minimum].right_neighbor; + unlace(_minimum); + _data[_minimum].in=false; + if ( _data[_minimum].degree > 0 ) { + int left=_data[_minimum].left_neighbor; + int child=_data[_minimum].child; + int last_child=_data[child].left_neighbor; + + makeRoot(child); + + _data[left].right_neighbor=child; + _data[child].left_neighbor=left; + _data[right].left_neighbor=last_child; + _data[last_child].right_neighbor=right; + } + _minimum=right; + balance(); + } // the case where there are more roots + --_num; + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param item The item to delete. + /// \pre \e item must be in the heap. + void erase (const Item& item) { + int i=_iim[item]; + + if ( i >= 0 && _data[i].in ) { + if ( _data[i].parent!=-1 ) { + int p=_data[i].parent; + cut(i,p); + cascade(p); + } + _minimum=i; //As if its prio would be -infinity + pop(); + } + } + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param item The item. + /// \pre \e item must be in the heap. + Prio operator[](const Item& item) const { + return _data[_iim[item]].prio; + } + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// \param item The item. + /// \param prio The priority. + void set (const Item& item, const Prio& prio) { + int i=_iim[item]; + if ( i >= 0 && _data[i].in ) { + if ( _comp(prio, _data[i].prio) ) decrease(item, prio); + if ( _comp(_data[i].prio, prio) ) increase(item, prio); + } else push(item, prio); + } + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param item The item. + /// \param prio The priority. + /// \pre \e item must be stored in the heap with priority at least \e prio. + void decrease (const Item& item, const Prio& prio) { + int i=_iim[item]; + _data[i].prio=prio; + int p=_data[i].parent; + + if ( p!=-1 && _comp(prio, _data[p].prio) ) { + cut(i,p); + cascade(p); + } + if ( _comp(prio, _data[_minimum].prio) ) _minimum=i; + } + + /// \brief Increase the priority of an item to the given value. + /// + /// This function increases the priority of an item to the given value. + /// \param item The item. + /// \param prio The priority. + /// \pre \e item must be stored in the heap with priority at most \e prio. + void increase (const Item& item, const Prio& prio) { + erase(item); + push(item, prio); + } + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param item The item. + State state(const Item &item) const { + int i=_iim[item]; + if( i>=0 ) { + if ( _data[i].in ) i=0; + else i=-2; + } + return State(i); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) { + erase(i); + } + _iim[i] = st; + break; + case IN_HEAP: + break; + } + } + + private: + + void balance() { + + int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1; + + std::vector A(maxdeg,-1); + + /* + *Recall that now minimum does not point to the minimum prio element. + *We set minimum to this during balance(). + */ + int anchor=_data[_minimum].left_neighbor; + int next=_minimum; + bool end=false; + + do { + int active=next; + if ( anchor==active ) end=true; + int d=_data[active].degree; + next=_data[active].right_neighbor; + + while (A[d]!=-1) { + if( _comp(_data[active].prio, _data[A[d]].prio) ) { + fuse(active,A[d]); + } else { + fuse(A[d],active); + active=A[d]; + } + A[d]=-1; + ++d; + } + A[d]=active; + } while ( !end ); + + + while ( _data[_minimum].parent >=0 ) + _minimum=_data[_minimum].parent; + int s=_minimum; + int m=_minimum; + do { + if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s; + s=_data[s].right_neighbor; + } while ( s != m ); + } + + void makeRoot(int c) { + int s=c; + do { + _data[s].parent=-1; + s=_data[s].right_neighbor; + } while ( s != c ); + } + + void cut(int a, int b) { + /* + *Replacing a from the children of b. + */ + --_data[b].degree; + + if ( _data[b].degree !=0 ) { + int child=_data[b].child; + if ( child==a ) + _data[b].child=_data[child].right_neighbor; + unlace(a); + } + + + /*Lacing a to the roots.*/ + int right=_data[_minimum].right_neighbor; + _data[_minimum].right_neighbor=a; + _data[a].left_neighbor=_minimum; + _data[a].right_neighbor=right; + _data[right].left_neighbor=a; + + _data[a].parent=-1; + _data[a].marked=false; + } + + void cascade(int a) { + if ( _data[a].parent!=-1 ) { + int p=_data[a].parent; + + if ( _data[a].marked==false ) _data[a].marked=true; + else { + cut(a,p); + cascade(p); + } + } + } + + void fuse(int a, int b) { + unlace(b); + + /*Lacing b under a.*/ + _data[b].parent=a; + + if (_data[a].degree==0) { + _data[b].left_neighbor=b; + _data[b].right_neighbor=b; + _data[a].child=b; + } else { + int child=_data[a].child; + int last_child=_data[child].left_neighbor; + _data[child].left_neighbor=b; + _data[b].right_neighbor=child; + _data[last_child].right_neighbor=b; + _data[b].left_neighbor=last_child; + } + + ++_data[a].degree; + + _data[b].marked=false; + } + + /* + *It is invoked only if a has siblings. + */ + void unlace(int a) { + int leftn=_data[a].left_neighbor; + int rightn=_data[a].right_neighbor; + _data[leftn].right_neighbor=rightn; + _data[rightn].left_neighbor=leftn; + } + + + class Store { + friend class FibHeap; + + Item name; + int parent; + int left_neighbor; + int right_neighbor; + int child; + int degree; + bool marked; + bool in; + Prio prio; + + Store() : parent(-1), child(-1), degree(), marked(false), in(true) {} + }; + }; + +} //namespace lemon + +#endif //LEMON_FIB_HEAP_H + diff --git a/lemon/lemon/fractional_matching.h b/lemon/lemon/fractional_matching.h new file mode 100644 index 0000000..ba69194 --- /dev/null +++ b/lemon/lemon/fractional_matching.h @@ -0,0 +1,2139 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_FRACTIONAL_MATCHING_H +#define LEMON_FRACTIONAL_MATCHING_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +///\ingroup matching +///\file +///\brief Fractional matching algorithms in general graphs. + +namespace lemon { + + /// \brief Default traits class of MaxFractionalMatching class. + /// + /// Default traits class of MaxFractionalMatching class. + /// \tparam GR Graph type. + template + struct MaxFractionalMatchingDefaultTraits { + + /// \brief The type of the graph the algorithm runs on. + typedef GR Graph; + + /// \brief The type of the map that stores the matching. + /// + /// The type of the map that stores the matching arcs. + /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + typedef typename Graph::template NodeMap MatchingMap; + + /// \brief Instantiates a MatchingMap. + /// + /// This function instantiates a \ref MatchingMap. + /// \param graph The graph for which we would like to define + /// the matching map. + static MatchingMap* createMatchingMap(const Graph& graph) { + return new MatchingMap(graph); + } + + /// \brief The elevator type used by MaxFractionalMatching algorithm. + /// + /// The elevator type used by MaxFractionalMatching algorithm. + /// + /// \sa Elevator + /// \sa LinkedElevator + typedef LinkedElevator Elevator; + + /// \brief Instantiates an Elevator. + /// + /// This function instantiates an \ref Elevator. + /// \param graph The graph for which we would like to define + /// the elevator. + /// \param max_level The maximum level of the elevator. + static Elevator* createElevator(const Graph& graph, int max_level) { + return new Elevator(graph, max_level); + } + }; + + /// \ingroup matching + /// + /// \brief Max cardinality fractional matching + /// + /// This class provides an implementation of fractional matching + /// algorithm based on push-relabel principle. + /// + /// The maximum cardinality fractional matching is a relaxation of the + /// maximum cardinality matching problem where the odd set constraints + /// are omitted. + /// It can be formulated with the following linear program. + /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f] + /// \f[x_e \ge 0\quad \forall e\in E\f] + /// \f[\max \sum_{e\in E}x_e\f] + /// where \f$\delta(X)\f$ is the set of edges incident to a node in + /// \f$X\f$. The result can be represented as the union of a + /// matching with one value edges and a set of odd length cycles + /// with half value edges. + /// + /// The algorithm calculates an optimal fractional matching and a + /// barrier. The number of adjacents of any node set minus the size + /// of node set is a lower bound on the uncovered nodes in the + /// graph. For maximum matching a barrier is computed which + /// maximizes this difference. + /// + /// The algorithm can be executed with the run() function. After it + /// the matching (the primal solution) and the barrier (the dual + /// solution) can be obtained using the query functions. + /// + /// The primal solution is multiplied by + /// \ref MaxFractionalMatching::primalScale "2". + /// + /// \tparam GR The undirected graph type the algorithm runs on. +#ifdef DOXYGEN + template +#else + template > +#endif + class MaxFractionalMatching { + public: + + /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits + /// class" of the algorithm. + typedef TR Traits; + /// The type of the graph the algorithm runs on. + typedef typename TR::Graph Graph; + /// The type of the matching map. + typedef typename TR::MatchingMap MatchingMap; + /// The type of the elevator. + typedef typename TR::Elevator Elevator; + + /// \brief Scaling factor for primal solution + /// + /// Scaling factor for primal solution. + static const int primalScale = 2; + + private: + + const Graph &_graph; + int _node_num; + bool _allow_loops; + int _empty_level; + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + bool _local_matching; + MatchingMap *_matching; + + bool _local_level; + Elevator *_level; + + typedef typename Graph::template NodeMap InDegMap; + InDegMap *_indeg; + + void createStructures() { + _node_num = countNodes(_graph); + + if (!_matching) { + _local_matching = true; + _matching = Traits::createMatchingMap(_graph); + } + if (!_level) { + _local_level = true; + _level = Traits::createElevator(_graph, _node_num); + } + if (!_indeg) { + _indeg = new InDegMap(_graph); + } + } + + void destroyStructures() { + if (_local_matching) { + delete _matching; + } + if (_local_level) { + delete _level; + } + if (_indeg) { + delete _indeg; + } + } + + void postprocessing() { + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_indeg)[n] != 0) continue; + _indeg->set(n, -1); + Node u = n; + while ((*_matching)[u] != INVALID) { + Node v = _graph.target((*_matching)[u]); + _indeg->set(v, -1); + Arc a = _graph.oppositeArc((*_matching)[u]); + u = _graph.target((*_matching)[v]); + _indeg->set(u, -1); + _matching->set(v, a); + } + } + + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_indeg)[n] != 1) continue; + _indeg->set(n, -1); + + int num = 1; + Node u = _graph.target((*_matching)[n]); + while (u != n) { + _indeg->set(u, -1); + u = _graph.target((*_matching)[u]); + ++num; + } + if (num % 2 == 0 && num > 2) { + Arc prev = _graph.oppositeArc((*_matching)[n]); + Node v = _graph.target((*_matching)[n]); + u = _graph.target((*_matching)[v]); + _matching->set(v, prev); + while (u != n) { + prev = _graph.oppositeArc((*_matching)[u]); + v = _graph.target((*_matching)[u]); + u = _graph.target((*_matching)[v]); + _matching->set(v, prev); + } + } + } + } + + public: + + typedef MaxFractionalMatching Create; + + ///\name Named Template Parameters + + ///@{ + + template + struct SetMatchingMapTraits : public Traits { + typedef T MatchingMap; + static MatchingMap *createMatchingMap(const Graph&) { + LEMON_ASSERT(false, "MatchingMap is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// MatchingMap type + /// + /// \ref named-templ-param "Named parameter" for setting MatchingMap + /// type. + template + struct SetMatchingMap + : public MaxFractionalMatching > { + typedef MaxFractionalMatching > Create; + }; + + template + struct SetElevatorTraits : public Traits { + typedef T Elevator; + static Elevator *createElevator(const Graph&, int) { + LEMON_ASSERT(false, "Elevator is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// Elevator type + /// + /// \ref named-templ-param "Named parameter" for setting Elevator + /// type. If this named parameter is used, then an external + /// elevator object must be passed to the algorithm using the + /// \ref elevator(Elevator&) "elevator()" function before calling + /// \ref run() or \ref init(). + /// \sa SetStandardElevator + template + struct SetElevator + : public MaxFractionalMatching > { + typedef MaxFractionalMatching > Create; + }; + + template + struct SetStandardElevatorTraits : public Traits { + typedef T Elevator; + static Elevator *createElevator(const Graph& graph, int max_level) { + return new Elevator(graph, max_level); + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// Elevator type with automatic allocation + /// + /// \ref named-templ-param "Named parameter" for setting Elevator + /// type with automatic allocation. + /// The Elevator should have standard constructor interface to be + /// able to automatically created by the algorithm (i.e. the + /// graph and the maximum level should be passed to it). + /// However an external elevator object could also be passed to the + /// algorithm with the \ref elevator(Elevator&) "elevator()" function + /// before calling \ref run() or \ref init(). + /// \sa SetElevator + template + struct SetStandardElevator + : public MaxFractionalMatching > { + typedef MaxFractionalMatching > Create; + }; + + /// @} + + protected: + + MaxFractionalMatching() {} + + public: + + /// \brief Constructor + /// + /// Constructor. + /// + MaxFractionalMatching(const Graph &graph, bool allow_loops = true) + : _graph(graph), _allow_loops(allow_loops), + _local_matching(false), _matching(0), + _local_level(false), _level(0), _indeg(0) + {} + + ~MaxFractionalMatching() { + destroyStructures(); + } + + /// \brief Sets the matching map. + /// + /// Sets the matching map. + /// If you don't use this function before calling \ref run() or + /// \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated map, + /// of course. + /// \return (*this) + MaxFractionalMatching& matchingMap(MatchingMap& map) { + if (_local_matching) { + delete _matching; + _local_matching = false; + } + _matching = ↦ + return *this; + } + + /// \brief Sets the elevator used by algorithm. + /// + /// Sets the elevator used by algorithm. + /// If you don't use this function before calling \ref run() or + /// \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated elevator, + /// of course. + /// \return (*this) + MaxFractionalMatching& elevator(Elevator& elevator) { + if (_local_level) { + delete _level; + _local_level = false; + } + _level = &elevator; + return *this; + } + + /// \brief Returns a const reference to the elevator. + /// + /// Returns a const reference to the elevator. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const Elevator& elevator() const { + return *_level; + } + + /// \name Execution control + /// The simplest way to execute the algorithm is to use one of the + /// member functions called \c run(). \n + /// If you need more control on the execution, first + /// you must call \ref init() and then one variant of the start() + /// member. + + /// @{ + + /// \brief Initializes the internal data structures. + /// + /// Initializes the internal data structures and sets the initial + /// matching. + void init() { + createStructures(); + + _level->initStart(); + for (NodeIt n(_graph); n != INVALID; ++n) { + _indeg->set(n, 0); + _matching->set(n, INVALID); + _level->initAddItem(n); + } + _level->initFinish(); + + _empty_level = _node_num; + for (NodeIt n(_graph); n != INVALID; ++n) { + for (OutArcIt a(_graph, n); a != INVALID; ++a) { + if (_graph.target(a) == n && !_allow_loops) continue; + _matching->set(n, a); + Node v = _graph.target((*_matching)[n]); + _indeg->set(v, (*_indeg)[v] + 1); + break; + } + } + + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_indeg)[n] == 0) { + _level->activate(n); + } + } + } + + /// \brief Starts the algorithm and computes a fractional matching + /// + /// The algorithm computes a maximum fractional matching. + /// + /// \param postprocess The algorithm computes first a matching + /// which is a union of a matching with one value edges, cycles + /// with half value edges and even length paths with half value + /// edges. If the parameter is true, then after the push-relabel + /// algorithm it postprocesses the matching to contain only + /// matching edges and half value odd cycles. + void start(bool postprocess = true) { + Node n; + while ((n = _level->highestActive()) != INVALID) { + int level = _level->highestActiveLevel(); + int new_level = _level->maxLevel(); + for (InArcIt a(_graph, n); a != INVALID; ++a) { + Node u = _graph.source(a); + if (n == u && !_allow_loops) continue; + Node v = _graph.target((*_matching)[u]); + if ((*_level)[v] < level) { + _indeg->set(v, (*_indeg)[v] - 1); + if ((*_indeg)[v] == 0) { + _level->activate(v); + } + _matching->set(u, a); + _indeg->set(n, (*_indeg)[n] + 1); + _level->deactivate(n); + goto no_more_push; + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + if (new_level + 1 < _level->maxLevel()) { + _level->liftHighestActive(new_level + 1); + } else { + _level->liftHighestActiveToTop(); + } + if (_level->emptyLevel(level)) { + _level->liftToTop(level); + } + no_more_push: + ; + } + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] == INVALID) continue; + Node u = _graph.target((*_matching)[n]); + if ((*_indeg)[u] > 1) { + _indeg->set(u, (*_indeg)[u] - 1); + _matching->set(n, INVALID); + } + } + if (postprocess) { + postprocessing(); + } + } + + /// \brief Starts the algorithm and computes a perfect fractional + /// matching + /// + /// The algorithm computes a perfect fractional matching. If it + /// does not exists, then the algorithm returns false and the + /// matching is undefined and the barrier. + /// + /// \param postprocess The algorithm computes first a matching + /// which is a union of a matching with one value edges, cycles + /// with half value edges and even length paths with half value + /// edges. If the parameter is true, then after the push-relabel + /// algorithm it postprocesses the matching to contain only + /// matching edges and half value odd cycles. + bool startPerfect(bool postprocess = true) { + Node n; + while ((n = _level->highestActive()) != INVALID) { + int level = _level->highestActiveLevel(); + int new_level = _level->maxLevel(); + for (InArcIt a(_graph, n); a != INVALID; ++a) { + Node u = _graph.source(a); + if (n == u && !_allow_loops) continue; + Node v = _graph.target((*_matching)[u]); + if ((*_level)[v] < level) { + _indeg->set(v, (*_indeg)[v] - 1); + if ((*_indeg)[v] == 0) { + _level->activate(v); + } + _matching->set(u, a); + _indeg->set(n, (*_indeg)[n] + 1); + _level->deactivate(n); + goto no_more_push; + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + if (new_level + 1 < _level->maxLevel()) { + _level->liftHighestActive(new_level + 1); + } else { + _level->liftHighestActiveToTop(); + _empty_level = _level->maxLevel() - 1; + return false; + } + if (_level->emptyLevel(level)) { + _level->liftToTop(level); + _empty_level = level; + return false; + } + no_more_push: + ; + } + if (postprocess) { + postprocessing(); + } + return true; + } + + /// \brief Runs the algorithm + /// + /// Just a shortcut for the next code: + ///\code + /// init(); + /// start(); + ///\endcode + void run(bool postprocess = true) { + init(); + start(postprocess); + } + + /// \brief Runs the algorithm to find a perfect fractional matching + /// + /// Just a shortcut for the next code: + ///\code + /// init(); + /// startPerfect(); + ///\endcode + bool runPerfect(bool postprocess = true) { + init(); + return startPerfect(postprocess); + } + + ///@} + + /// \name Query Functions + /// The result of the %Matching algorithm can be obtained using these + /// functions.\n + /// Before the use of these functions, + /// either run() or start() must be called. + ///@{ + + + /// \brief Return the number of covered nodes in the matching. + /// + /// This function returns the number of covered nodes in the matching. + /// + /// \pre Either run() or start() must be called before using this function. + int matchingSize() const { + int num = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + ++num; + } + } + return num; + } + + /// \brief Returns a const reference to the matching map. + /// + /// Returns a const reference to the node map storing the found + /// fractional matching. This method can be called after + /// running the algorithm. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const MatchingMap& matchingMap() const { + return *_matching; + } + + /// \brief Return \c true if the given edge is in the matching. + /// + /// This function returns \c true if the given edge is in the + /// found matching. The result is scaled by \ref primalScale + /// "primal scale". + /// + /// \pre Either run() or start() must be called before using this function. + int matching(const Edge& edge) const { + return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) + + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0); + } + + /// \brief Return the fractional matching arc (or edge) incident + /// to the given node. + /// + /// This function returns one of the fractional matching arc (or + /// edge) incident to the given node in the found matching or \c + /// INVALID if the node is not covered by the matching or if the + /// node is on an odd length cycle then it is the successor edge + /// on the cycle. + /// + /// \pre Either run() or start() must be called before using this function. + Arc matching(const Node& node) const { + return (*_matching)[node]; + } + + /// \brief Returns true if the node is in the barrier + /// + /// The barrier is a subset of the nodes. If the nodes in the + /// barrier have less adjacent nodes than the size of the barrier, + /// then at least as much nodes cannot be covered as the + /// difference of the two subsets. + bool barrier(const Node& node) const { + return (*_level)[node] >= _empty_level; + } + + /// @} + + }; + + /// \ingroup matching + /// + /// \brief Weighted fractional matching in general graphs + /// + /// This class provides an efficient implementation of fractional + /// matching algorithm. The implementation uses priority queues and + /// provides \f$O(nm\log n)\f$ time complexity. + /// + /// The maximum weighted fractional matching is a relaxation of the + /// maximum weighted matching problem where the odd set constraints + /// are omitted. + /// It can be formulated with the following linear program. + /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f] + /// \f[x_e \ge 0\quad \forall e\in E\f] + /// \f[\max \sum_{e\in E}x_ew_e\f] + /// where \f$\delta(X)\f$ is the set of edges incident to a node in + /// \f$X\f$. The result must be the union of a matching with one + /// value edges and a set of odd length cycles with half value edges. + /// + /// The algorithm calculates an optimal fractional matching and a + /// proof of the optimality. The solution of the dual problem can be + /// used to check the result of the algorithm. The dual linear + /// problem is the following. + /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f] + /// \f[y_u \ge 0 \quad \forall u \in V\f] + /// \f[\min \sum_{u \in V}y_u \f] + /// + /// The algorithm can be executed with the run() function. + /// After it the matching (the primal solution) and the dual solution + /// can be obtained using the query functions. + /// + /// The primal solution is multiplied by + /// \ref MaxWeightedFractionalMatching::primalScale "2". + /// If the value type is integer, then the dual + /// solution is scaled by + /// \ref MaxWeightedFractionalMatching::dualScale "4". + /// + /// \tparam GR The undirected graph type the algorithm runs on. + /// \tparam WM The type edge weight map. The default type is + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap". +#ifdef DOXYGEN + template +#else + template > +#endif + class MaxWeightedFractionalMatching { + public: + + /// The graph type of the algorithm + typedef GR Graph; + /// The type of the edge weight map + typedef WM WeightMap; + /// The value type of the edge weights + typedef typename WeightMap::Value Value; + + /// The type of the matching map + typedef typename Graph::template NodeMap + MatchingMap; + + /// \brief Scaling factor for primal solution + /// + /// Scaling factor for primal solution. + static const int primalScale = 2; + + /// \brief Scaling factor for dual solution + /// + /// Scaling factor for dual solution. It is equal to 4 or 1 + /// according to the value type. + static const int dualScale = + std::numeric_limits::is_integer ? 4 : 1; + + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + typedef typename Graph::template NodeMap NodePotential; + + const Graph& _graph; + const WeightMap& _weight; + + MatchingMap* _matching; + NodePotential* _node_potential; + + int _node_num; + bool _allow_loops; + + enum Status { + EVEN = -1, MATCHED = 0, ODD = 1 + }; + + typedef typename Graph::template NodeMap StatusMap; + StatusMap* _status; + + typedef typename Graph::template NodeMap PredMap; + PredMap* _pred; + + typedef ExtendFindEnum TreeSet; + + IntNodeMap *_tree_set_index; + TreeSet *_tree_set; + + IntNodeMap *_delta1_index; + BinHeap *_delta1; + + IntNodeMap *_delta2_index; + BinHeap *_delta2; + + IntEdgeMap *_delta3_index; + BinHeap *_delta3; + + Value _delta_sum; + + void createStructures() { + _node_num = countNodes(_graph); + + if (!_matching) { + _matching = new MatchingMap(_graph); + } + if (!_node_potential) { + _node_potential = new NodePotential(_graph); + } + if (!_status) { + _status = new StatusMap(_graph); + } + if (!_pred) { + _pred = new PredMap(_graph); + } + if (!_tree_set) { + _tree_set_index = new IntNodeMap(_graph); + _tree_set = new TreeSet(*_tree_set_index); + } + if (!_delta1) { + _delta1_index = new IntNodeMap(_graph); + _delta1 = new BinHeap(*_delta1_index); + } + if (!_delta2) { + _delta2_index = new IntNodeMap(_graph); + _delta2 = new BinHeap(*_delta2_index); + } + if (!_delta3) { + _delta3_index = new IntEdgeMap(_graph); + _delta3 = new BinHeap(*_delta3_index); + } + } + + void destroyStructures() { + if (_matching) { + delete _matching; + } + if (_node_potential) { + delete _node_potential; + } + if (_status) { + delete _status; + } + if (_pred) { + delete _pred; + } + if (_tree_set) { + delete _tree_set_index; + delete _tree_set; + } + if (_delta1) { + delete _delta1_index; + delete _delta1; + } + if (_delta2) { + delete _delta2_index; + delete _delta2; + } + if (_delta3) { + delete _delta3_index; + delete _delta3; + } + } + + void matchedToEven(Node node, int tree) { + _tree_set->insert(node, tree); + _node_potential->set(node, (*_node_potential)[node] + _delta_sum); + _delta1->push(node, (*_node_potential)[node]); + + if (_delta2->state(node) == _delta2->IN_HEAP) { + _delta2->erase(node); + } + + for (InArcIt a(_graph, node); a != INVALID; ++a) { + Node v = _graph.source(a); + Value rw = (*_node_potential)[node] + (*_node_potential)[v] - + dualScale * _weight[a]; + if (node == v) { + if (_allow_loops && _graph.direction(a)) { + _delta3->push(a, rw / 2); + } + } else if ((*_status)[v] == EVEN) { + _delta3->push(a, rw / 2); + } else if ((*_status)[v] == MATCHED) { + if (_delta2->state(v) != _delta2->IN_HEAP) { + _pred->set(v, a); + _delta2->push(v, rw); + } else if ((*_delta2)[v] > rw) { + _pred->set(v, a); + _delta2->decrease(v, rw); + } + } + } + } + + void matchedToOdd(Node node, int tree) { + _tree_set->insert(node, tree); + _node_potential->set(node, (*_node_potential)[node] - _delta_sum); + + if (_delta2->state(node) == _delta2->IN_HEAP) { + _delta2->erase(node); + } + } + + void evenToMatched(Node node, int tree) { + _delta1->erase(node); + _node_potential->set(node, (*_node_potential)[node] - _delta_sum); + Arc min = INVALID; + Value minrw = std::numeric_limits::max(); + for (InArcIt a(_graph, node); a != INVALID; ++a) { + Node v = _graph.source(a); + Value rw = (*_node_potential)[node] + (*_node_potential)[v] - + dualScale * _weight[a]; + + if (node == v) { + if (_allow_loops && _graph.direction(a)) { + _delta3->erase(a); + } + } else if ((*_status)[v] == EVEN) { + _delta3->erase(a); + if (minrw > rw) { + min = _graph.oppositeArc(a); + minrw = rw; + } + } else if ((*_status)[v] == MATCHED) { + if ((*_pred)[v] == a) { + Arc mina = INVALID; + Value minrwa = std::numeric_limits::max(); + for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) { + Node va = _graph.target(aa); + if ((*_status)[va] != EVEN || + _tree_set->find(va) == tree) continue; + Value rwa = (*_node_potential)[v] + (*_node_potential)[va] - + dualScale * _weight[aa]; + if (minrwa > rwa) { + minrwa = rwa; + mina = aa; + } + } + if (mina != INVALID) { + _pred->set(v, mina); + _delta2->increase(v, minrwa); + } else { + _pred->set(v, INVALID); + _delta2->erase(v); + } + } + } + } + if (min != INVALID) { + _pred->set(node, min); + _delta2->push(node, minrw); + } else { + _pred->set(node, INVALID); + } + } + + void oddToMatched(Node node) { + _node_potential->set(node, (*_node_potential)[node] + _delta_sum); + Arc min = INVALID; + Value minrw = std::numeric_limits::max(); + for (InArcIt a(_graph, node); a != INVALID; ++a) { + Node v = _graph.source(a); + if ((*_status)[v] != EVEN) continue; + Value rw = (*_node_potential)[node] + (*_node_potential)[v] - + dualScale * _weight[a]; + + if (minrw > rw) { + min = _graph.oppositeArc(a); + minrw = rw; + } + } + if (min != INVALID) { + _pred->set(node, min); + _delta2->push(node, minrw); + } else { + _pred->set(node, INVALID); + } + } + + void alternatePath(Node even, int tree) { + Node odd; + + _status->set(even, MATCHED); + evenToMatched(even, tree); + + Arc prev = (*_matching)[even]; + while (prev != INVALID) { + odd = _graph.target(prev); + even = _graph.target((*_pred)[odd]); + _matching->set(odd, (*_pred)[odd]); + _status->set(odd, MATCHED); + oddToMatched(odd); + + prev = (*_matching)[even]; + _status->set(even, MATCHED); + _matching->set(even, _graph.oppositeArc((*_matching)[odd])); + evenToMatched(even, tree); + } + } + + void destroyTree(int tree) { + for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) { + if ((*_status)[n] == EVEN) { + _status->set(n, MATCHED); + evenToMatched(n, tree); + } else if ((*_status)[n] == ODD) { + _status->set(n, MATCHED); + oddToMatched(n); + } + } + _tree_set->eraseClass(tree); + } + + + void unmatchNode(const Node& node) { + int tree = _tree_set->find(node); + + alternatePath(node, tree); + destroyTree(tree); + + _matching->set(node, INVALID); + } + + + void augmentOnEdge(const Edge& edge) { + Node left = _graph.u(edge); + int left_tree = _tree_set->find(left); + + alternatePath(left, left_tree); + destroyTree(left_tree); + _matching->set(left, _graph.direct(edge, true)); + + Node right = _graph.v(edge); + int right_tree = _tree_set->find(right); + + alternatePath(right, right_tree); + destroyTree(right_tree); + _matching->set(right, _graph.direct(edge, false)); + } + + void augmentOnArc(const Arc& arc) { + Node left = _graph.source(arc); + _status->set(left, MATCHED); + _matching->set(left, arc); + _pred->set(left, arc); + + Node right = _graph.target(arc); + int right_tree = _tree_set->find(right); + + alternatePath(right, right_tree); + destroyTree(right_tree); + _matching->set(right, _graph.oppositeArc(arc)); + } + + void extendOnArc(const Arc& arc) { + Node base = _graph.target(arc); + int tree = _tree_set->find(base); + + Node odd = _graph.source(arc); + _tree_set->insert(odd, tree); + _status->set(odd, ODD); + matchedToOdd(odd, tree); + _pred->set(odd, arc); + + Node even = _graph.target((*_matching)[odd]); + _tree_set->insert(even, tree); + _status->set(even, EVEN); + matchedToEven(even, tree); + } + + void cycleOnEdge(const Edge& edge, int tree) { + Node nca = INVALID; + std::vector left_path, right_path; + + { + std::set left_set, right_set; + Node left = _graph.u(edge); + left_path.push_back(left); + left_set.insert(left); + + Node right = _graph.v(edge); + right_path.push_back(right); + right_set.insert(right); + + while (true) { + + if (left_set.find(right) != left_set.end()) { + nca = right; + break; + } + + if ((*_matching)[left] == INVALID) break; + + left = _graph.target((*_matching)[left]); + left_path.push_back(left); + left = _graph.target((*_pred)[left]); + left_path.push_back(left); + + left_set.insert(left); + + if (right_set.find(left) != right_set.end()) { + nca = left; + break; + } + + if ((*_matching)[right] == INVALID) break; + + right = _graph.target((*_matching)[right]); + right_path.push_back(right); + right = _graph.target((*_pred)[right]); + right_path.push_back(right); + + right_set.insert(right); + + } + + if (nca == INVALID) { + if ((*_matching)[left] == INVALID) { + nca = right; + while (left_set.find(nca) == left_set.end()) { + nca = _graph.target((*_matching)[nca]); + right_path.push_back(nca); + nca = _graph.target((*_pred)[nca]); + right_path.push_back(nca); + } + } else { + nca = left; + while (right_set.find(nca) == right_set.end()) { + nca = _graph.target((*_matching)[nca]); + left_path.push_back(nca); + nca = _graph.target((*_pred)[nca]); + left_path.push_back(nca); + } + } + } + } + + alternatePath(nca, tree); + Arc prev; + + prev = _graph.direct(edge, true); + for (int i = 0; left_path[i] != nca; i += 2) { + _matching->set(left_path[i], prev); + _status->set(left_path[i], MATCHED); + evenToMatched(left_path[i], tree); + + prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]); + _status->set(left_path[i + 1], MATCHED); + oddToMatched(left_path[i + 1]); + } + _matching->set(nca, prev); + + for (int i = 0; right_path[i] != nca; i += 2) { + _status->set(right_path[i], MATCHED); + evenToMatched(right_path[i], tree); + + _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]); + _status->set(right_path[i + 1], MATCHED); + oddToMatched(right_path[i + 1]); + } + + destroyTree(tree); + } + + void extractCycle(const Arc &arc) { + Node left = _graph.source(arc); + Node odd = _graph.target((*_matching)[left]); + Arc prev; + while (odd != left) { + Node even = _graph.target((*_matching)[odd]); + prev = (*_matching)[odd]; + odd = _graph.target((*_matching)[even]); + _matching->set(even, _graph.oppositeArc(prev)); + } + _matching->set(left, arc); + + Node right = _graph.target(arc); + int right_tree = _tree_set->find(right); + alternatePath(right, right_tree); + destroyTree(right_tree); + _matching->set(right, _graph.oppositeArc(arc)); + } + + public: + + /// \brief Constructor + /// + /// Constructor. + MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight, + bool allow_loops = true) + : _graph(graph), _weight(weight), _matching(0), + _node_potential(0), _node_num(0), _allow_loops(allow_loops), + _status(0), _pred(0), + _tree_set_index(0), _tree_set(0), + + _delta1_index(0), _delta1(0), + _delta2_index(0), _delta2(0), + _delta3_index(0), _delta3(0), + + _delta_sum() {} + + ~MaxWeightedFractionalMatching() { + destroyStructures(); + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to use the + /// \ref run() member function. + + ///@{ + + /// \brief Initialize the algorithm + /// + /// This function initializes the algorithm. + void init() { + createStructures(); + + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_delta1_index)[n] = _delta1->PRE_HEAP; + (*_delta2_index)[n] = _delta2->PRE_HEAP; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + (*_delta3_index)[e] = _delta3->PRE_HEAP; + } + + _delta1->clear(); + _delta2->clear(); + _delta3->clear(); + _tree_set->clear(); + + for (NodeIt n(_graph); n != INVALID; ++n) { + Value max = 0; + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + if (_graph.target(e) == n && !_allow_loops) continue; + if ((dualScale * _weight[e]) / 2 > max) { + max = (dualScale * _weight[e]) / 2; + } + } + _node_potential->set(n, max); + _delta1->push(n, max); + + _tree_set->insert(n); + + _matching->set(n, INVALID); + _status->set(n, EVEN); + } + + for (EdgeIt e(_graph); e != INVALID; ++e) { + Node left = _graph.u(e); + Node right = _graph.v(e); + if (left == right && !_allow_loops) continue; + _delta3->push(e, ((*_node_potential)[left] + + (*_node_potential)[right] - + dualScale * _weight[e]) / 2); + } + } + + /// \brief Start the algorithm + /// + /// This function starts the algorithm. + /// + /// \pre \ref init() must be called before using this function. + void start() { + enum OpType { + D1, D2, D3 + }; + + int unmatched = _node_num; + while (unmatched > 0) { + Value d1 = !_delta1->empty() ? + _delta1->prio() : std::numeric_limits::max(); + + Value d2 = !_delta2->empty() ? + _delta2->prio() : std::numeric_limits::max(); + + Value d3 = !_delta3->empty() ? + _delta3->prio() : std::numeric_limits::max(); + + _delta_sum = d3; OpType ot = D3; + if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; } + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; } + + switch (ot) { + case D1: + { + Node n = _delta1->top(); + unmatchNode(n); + --unmatched; + } + break; + case D2: + { + Node n = _delta2->top(); + Arc a = (*_pred)[n]; + if ((*_matching)[n] == INVALID) { + augmentOnArc(a); + --unmatched; + } else { + Node v = _graph.target((*_matching)[n]); + if ((*_matching)[n] != + _graph.oppositeArc((*_matching)[v])) { + extractCycle(a); + --unmatched; + } else { + extendOnArc(a); + } + } + } break; + case D3: + { + Edge e = _delta3->top(); + + Node left = _graph.u(e); + Node right = _graph.v(e); + + int left_tree = _tree_set->find(left); + int right_tree = _tree_set->find(right); + + if (left_tree == right_tree) { + cycleOnEdge(e, left_tree); + --unmatched; + } else { + augmentOnEdge(e); + unmatched -= 2; + } + } break; + } + } + } + + /// \brief Run the algorithm. + /// + /// This method runs the \c %MaxWeightedFractionalMatching algorithm. + /// + /// \note mwfm.run() is just a shortcut of the following code. + /// \code + /// mwfm.init(); + /// mwfm.start(); + /// \endcode + void run() { + init(); + start(); + } + + /// @} + + /// \name Primal Solution + /// Functions to get the primal solution, i.e. the maximum weighted + /// matching.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the weight of the matching. + /// + /// This function returns the weight of the found matching. This + /// value is scaled by \ref primalScale "primal scale". + /// + /// \pre Either run() or start() must be called before using this function. + Value matchingWeight() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + sum += _weight[(*_matching)[n]]; + } + } + return sum * primalScale / 2; + } + + /// \brief Return the number of covered nodes in the matching. + /// + /// This function returns the number of covered nodes in the matching. + /// + /// \pre Either run() or start() must be called before using this function. + int matchingSize() const { + int num = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + ++num; + } + } + return num; + } + + /// \brief Return \c true if the given edge is in the matching. + /// + /// This function returns \c true if the given edge is in the + /// found matching. The result is scaled by \ref primalScale + /// "primal scale". + /// + /// \pre Either run() or start() must be called before using this function. + int matching(const Edge& edge) const { + return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) + + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0); + } + + /// \brief Return the fractional matching arc (or edge) incident + /// to the given node. + /// + /// This function returns one of the fractional matching arc (or + /// edge) incident to the given node in the found matching or \c + /// INVALID if the node is not covered by the matching or if the + /// node is on an odd length cycle then it is the successor edge + /// on the cycle. + /// + /// \pre Either run() or start() must be called before using this function. + Arc matching(const Node& node) const { + return (*_matching)[node]; + } + + /// \brief Return a const reference to the matching map. + /// + /// This function returns a const reference to a node map that stores + /// the matching arc (or edge) incident to each node. + const MatchingMap& matchingMap() const { + return *_matching; + } + + /// @} + + /// \name Dual Solution + /// Functions to get the dual solution.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the value of the dual solution. + /// + /// This function returns the value of the dual solution. + /// It should be equal to the primal value scaled by \ref dualScale + /// "dual scale". + /// + /// \pre Either run() or start() must be called before using this function. + Value dualValue() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + sum += nodeValue(n); + } + return sum; + } + + /// \brief Return the dual value (potential) of the given node. + /// + /// This function returns the dual value (potential) of the given node. + /// + /// \pre Either run() or start() must be called before using this function. + Value nodeValue(const Node& n) const { + return (*_node_potential)[n]; + } + + /// @} + + }; + + /// \ingroup matching + /// + /// \brief Weighted fractional perfect matching in general graphs + /// + /// This class provides an efficient implementation of fractional + /// matching algorithm. The implementation uses priority queues and + /// provides \f$O(nm\log n)\f$ time complexity. + /// + /// The maximum weighted fractional perfect matching is a relaxation + /// of the maximum weighted perfect matching problem where the odd + /// set constraints are omitted. + /// It can be formulated with the following linear program. + /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f] + /// \f[x_e \ge 0\quad \forall e\in E\f] + /// \f[\max \sum_{e\in E}x_ew_e\f] + /// where \f$\delta(X)\f$ is the set of edges incident to a node in + /// \f$X\f$. The result must be the union of a matching with one + /// value edges and a set of odd length cycles with half value edges. + /// + /// The algorithm calculates an optimal fractional matching and a + /// proof of the optimality. The solution of the dual problem can be + /// used to check the result of the algorithm. The dual linear + /// problem is the following. + /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f] + /// \f[\min \sum_{u \in V}y_u \f] + /// + /// The algorithm can be executed with the run() function. + /// After it the matching (the primal solution) and the dual solution + /// can be obtained using the query functions. + /// + /// The primal solution is multiplied by + /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2". + /// If the value type is integer, then the dual + /// solution is scaled by + /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4". + /// + /// \tparam GR The undirected graph type the algorithm runs on. + /// \tparam WM The type edge weight map. The default type is + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap". +#ifdef DOXYGEN + template +#else + template > +#endif + class MaxWeightedPerfectFractionalMatching { + public: + + /// The graph type of the algorithm + typedef GR Graph; + /// The type of the edge weight map + typedef WM WeightMap; + /// The value type of the edge weights + typedef typename WeightMap::Value Value; + + /// The type of the matching map + typedef typename Graph::template NodeMap + MatchingMap; + + /// \brief Scaling factor for primal solution + /// + /// Scaling factor for primal solution. + static const int primalScale = 2; + + /// \brief Scaling factor for dual solution + /// + /// Scaling factor for dual solution. It is equal to 4 or 1 + /// according to the value type. + static const int dualScale = + std::numeric_limits::is_integer ? 4 : 1; + + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + typedef typename Graph::template NodeMap NodePotential; + + const Graph& _graph; + const WeightMap& _weight; + + MatchingMap* _matching; + NodePotential* _node_potential; + + int _node_num; + bool _allow_loops; + + enum Status { + EVEN = -1, MATCHED = 0, ODD = 1 + }; + + typedef typename Graph::template NodeMap StatusMap; + StatusMap* _status; + + typedef typename Graph::template NodeMap PredMap; + PredMap* _pred; + + typedef ExtendFindEnum TreeSet; + + IntNodeMap *_tree_set_index; + TreeSet *_tree_set; + + IntNodeMap *_delta2_index; + BinHeap *_delta2; + + IntEdgeMap *_delta3_index; + BinHeap *_delta3; + + Value _delta_sum; + + void createStructures() { + _node_num = countNodes(_graph); + + if (!_matching) { + _matching = new MatchingMap(_graph); + } + if (!_node_potential) { + _node_potential = new NodePotential(_graph); + } + if (!_status) { + _status = new StatusMap(_graph); + } + if (!_pred) { + _pred = new PredMap(_graph); + } + if (!_tree_set) { + _tree_set_index = new IntNodeMap(_graph); + _tree_set = new TreeSet(*_tree_set_index); + } + if (!_delta2) { + _delta2_index = new IntNodeMap(_graph); + _delta2 = new BinHeap(*_delta2_index); + } + if (!_delta3) { + _delta3_index = new IntEdgeMap(_graph); + _delta3 = new BinHeap(*_delta3_index); + } + } + + void destroyStructures() { + if (_matching) { + delete _matching; + } + if (_node_potential) { + delete _node_potential; + } + if (_status) { + delete _status; + } + if (_pred) { + delete _pred; + } + if (_tree_set) { + delete _tree_set_index; + delete _tree_set; + } + if (_delta2) { + delete _delta2_index; + delete _delta2; + } + if (_delta3) { + delete _delta3_index; + delete _delta3; + } + } + + void matchedToEven(Node node, int tree) { + _tree_set->insert(node, tree); + _node_potential->set(node, (*_node_potential)[node] + _delta_sum); + + if (_delta2->state(node) == _delta2->IN_HEAP) { + _delta2->erase(node); + } + + for (InArcIt a(_graph, node); a != INVALID; ++a) { + Node v = _graph.source(a); + Value rw = (*_node_potential)[node] + (*_node_potential)[v] - + dualScale * _weight[a]; + if (node == v) { + if (_allow_loops && _graph.direction(a)) { + _delta3->push(a, rw / 2); + } + } else if ((*_status)[v] == EVEN) { + _delta3->push(a, rw / 2); + } else if ((*_status)[v] == MATCHED) { + if (_delta2->state(v) != _delta2->IN_HEAP) { + _pred->set(v, a); + _delta2->push(v, rw); + } else if ((*_delta2)[v] > rw) { + _pred->set(v, a); + _delta2->decrease(v, rw); + } + } + } + } + + void matchedToOdd(Node node, int tree) { + _tree_set->insert(node, tree); + _node_potential->set(node, (*_node_potential)[node] - _delta_sum); + + if (_delta2->state(node) == _delta2->IN_HEAP) { + _delta2->erase(node); + } + } + + void evenToMatched(Node node, int tree) { + _node_potential->set(node, (*_node_potential)[node] - _delta_sum); + Arc min = INVALID; + Value minrw = std::numeric_limits::max(); + for (InArcIt a(_graph, node); a != INVALID; ++a) { + Node v = _graph.source(a); + Value rw = (*_node_potential)[node] + (*_node_potential)[v] - + dualScale * _weight[a]; + + if (node == v) { + if (_allow_loops && _graph.direction(a)) { + _delta3->erase(a); + } + } else if ((*_status)[v] == EVEN) { + _delta3->erase(a); + if (minrw > rw) { + min = _graph.oppositeArc(a); + minrw = rw; + } + } else if ((*_status)[v] == MATCHED) { + if ((*_pred)[v] == a) { + Arc mina = INVALID; + Value minrwa = std::numeric_limits::max(); + for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) { + Node va = _graph.target(aa); + if ((*_status)[va] != EVEN || + _tree_set->find(va) == tree) continue; + Value rwa = (*_node_potential)[v] + (*_node_potential)[va] - + dualScale * _weight[aa]; + if (minrwa > rwa) { + minrwa = rwa; + mina = aa; + } + } + if (mina != INVALID) { + _pred->set(v, mina); + _delta2->increase(v, minrwa); + } else { + _pred->set(v, INVALID); + _delta2->erase(v); + } + } + } + } + if (min != INVALID) { + _pred->set(node, min); + _delta2->push(node, minrw); + } else { + _pred->set(node, INVALID); + } + } + + void oddToMatched(Node node) { + _node_potential->set(node, (*_node_potential)[node] + _delta_sum); + Arc min = INVALID; + Value minrw = std::numeric_limits::max(); + for (InArcIt a(_graph, node); a != INVALID; ++a) { + Node v = _graph.source(a); + if ((*_status)[v] != EVEN) continue; + Value rw = (*_node_potential)[node] + (*_node_potential)[v] - + dualScale * _weight[a]; + + if (minrw > rw) { + min = _graph.oppositeArc(a); + minrw = rw; + } + } + if (min != INVALID) { + _pred->set(node, min); + _delta2->push(node, minrw); + } else { + _pred->set(node, INVALID); + } + } + + void alternatePath(Node even, int tree) { + Node odd; + + _status->set(even, MATCHED); + evenToMatched(even, tree); + + Arc prev = (*_matching)[even]; + while (prev != INVALID) { + odd = _graph.target(prev); + even = _graph.target((*_pred)[odd]); + _matching->set(odd, (*_pred)[odd]); + _status->set(odd, MATCHED); + oddToMatched(odd); + + prev = (*_matching)[even]; + _status->set(even, MATCHED); + _matching->set(even, _graph.oppositeArc((*_matching)[odd])); + evenToMatched(even, tree); + } + } + + void destroyTree(int tree) { + for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) { + if ((*_status)[n] == EVEN) { + _status->set(n, MATCHED); + evenToMatched(n, tree); + } else if ((*_status)[n] == ODD) { + _status->set(n, MATCHED); + oddToMatched(n); + } + } + _tree_set->eraseClass(tree); + } + + void augmentOnEdge(const Edge& edge) { + Node left = _graph.u(edge); + int left_tree = _tree_set->find(left); + + alternatePath(left, left_tree); + destroyTree(left_tree); + _matching->set(left, _graph.direct(edge, true)); + + Node right = _graph.v(edge); + int right_tree = _tree_set->find(right); + + alternatePath(right, right_tree); + destroyTree(right_tree); + _matching->set(right, _graph.direct(edge, false)); + } + + void augmentOnArc(const Arc& arc) { + Node left = _graph.source(arc); + _status->set(left, MATCHED); + _matching->set(left, arc); + _pred->set(left, arc); + + Node right = _graph.target(arc); + int right_tree = _tree_set->find(right); + + alternatePath(right, right_tree); + destroyTree(right_tree); + _matching->set(right, _graph.oppositeArc(arc)); + } + + void extendOnArc(const Arc& arc) { + Node base = _graph.target(arc); + int tree = _tree_set->find(base); + + Node odd = _graph.source(arc); + _tree_set->insert(odd, tree); + _status->set(odd, ODD); + matchedToOdd(odd, tree); + _pred->set(odd, arc); + + Node even = _graph.target((*_matching)[odd]); + _tree_set->insert(even, tree); + _status->set(even, EVEN); + matchedToEven(even, tree); + } + + void cycleOnEdge(const Edge& edge, int tree) { + Node nca = INVALID; + std::vector left_path, right_path; + + { + std::set left_set, right_set; + Node left = _graph.u(edge); + left_path.push_back(left); + left_set.insert(left); + + Node right = _graph.v(edge); + right_path.push_back(right); + right_set.insert(right); + + while (true) { + + if (left_set.find(right) != left_set.end()) { + nca = right; + break; + } + + if ((*_matching)[left] == INVALID) break; + + left = _graph.target((*_matching)[left]); + left_path.push_back(left); + left = _graph.target((*_pred)[left]); + left_path.push_back(left); + + left_set.insert(left); + + if (right_set.find(left) != right_set.end()) { + nca = left; + break; + } + + if ((*_matching)[right] == INVALID) break; + + right = _graph.target((*_matching)[right]); + right_path.push_back(right); + right = _graph.target((*_pred)[right]); + right_path.push_back(right); + + right_set.insert(right); + + } + + if (nca == INVALID) { + if ((*_matching)[left] == INVALID) { + nca = right; + while (left_set.find(nca) == left_set.end()) { + nca = _graph.target((*_matching)[nca]); + right_path.push_back(nca); + nca = _graph.target((*_pred)[nca]); + right_path.push_back(nca); + } + } else { + nca = left; + while (right_set.find(nca) == right_set.end()) { + nca = _graph.target((*_matching)[nca]); + left_path.push_back(nca); + nca = _graph.target((*_pred)[nca]); + left_path.push_back(nca); + } + } + } + } + + alternatePath(nca, tree); + Arc prev; + + prev = _graph.direct(edge, true); + for (int i = 0; left_path[i] != nca; i += 2) { + _matching->set(left_path[i], prev); + _status->set(left_path[i], MATCHED); + evenToMatched(left_path[i], tree); + + prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]); + _status->set(left_path[i + 1], MATCHED); + oddToMatched(left_path[i + 1]); + } + _matching->set(nca, prev); + + for (int i = 0; right_path[i] != nca; i += 2) { + _status->set(right_path[i], MATCHED); + evenToMatched(right_path[i], tree); + + _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]); + _status->set(right_path[i + 1], MATCHED); + oddToMatched(right_path[i + 1]); + } + + destroyTree(tree); + } + + void extractCycle(const Arc &arc) { + Node left = _graph.source(arc); + Node odd = _graph.target((*_matching)[left]); + Arc prev; + while (odd != left) { + Node even = _graph.target((*_matching)[odd]); + prev = (*_matching)[odd]; + odd = _graph.target((*_matching)[even]); + _matching->set(even, _graph.oppositeArc(prev)); + } + _matching->set(left, arc); + + Node right = _graph.target(arc); + int right_tree = _tree_set->find(right); + alternatePath(right, right_tree); + destroyTree(right_tree); + _matching->set(right, _graph.oppositeArc(arc)); + } + + public: + + /// \brief Constructor + /// + /// Constructor. + MaxWeightedPerfectFractionalMatching(const Graph& graph, + const WeightMap& weight, + bool allow_loops = true) + : _graph(graph), _weight(weight), _matching(0), + _node_potential(0), _node_num(0), _allow_loops(allow_loops), + _status(0), _pred(0), + _tree_set_index(0), _tree_set(0), + + _delta2_index(0), _delta2(0), + _delta3_index(0), _delta3(0), + + _delta_sum() {} + + ~MaxWeightedPerfectFractionalMatching() { + destroyStructures(); + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to use the + /// \ref run() member function. + + ///@{ + + /// \brief Initialize the algorithm + /// + /// This function initializes the algorithm. + void init() { + createStructures(); + + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_delta2_index)[n] = _delta2->PRE_HEAP; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + (*_delta3_index)[e] = _delta3->PRE_HEAP; + } + + _delta2->clear(); + _delta3->clear(); + _tree_set->clear(); + + for (NodeIt n(_graph); n != INVALID; ++n) { + Value max = - std::numeric_limits::max(); + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + if (_graph.target(e) == n && !_allow_loops) continue; + if ((dualScale * _weight[e]) / 2 > max) { + max = (dualScale * _weight[e]) / 2; + } + } + _node_potential->set(n, max); + + _tree_set->insert(n); + + _matching->set(n, INVALID); + _status->set(n, EVEN); + } + + for (EdgeIt e(_graph); e != INVALID; ++e) { + Node left = _graph.u(e); + Node right = _graph.v(e); + if (left == right && !_allow_loops) continue; + _delta3->push(e, ((*_node_potential)[left] + + (*_node_potential)[right] - + dualScale * _weight[e]) / 2); + } + } + + /// \brief Start the algorithm + /// + /// This function starts the algorithm. + /// + /// \pre \ref init() must be called before using this function. + bool start() { + enum OpType { + D2, D3 + }; + + int unmatched = _node_num; + while (unmatched > 0) { + Value d2 = !_delta2->empty() ? + _delta2->prio() : std::numeric_limits::max(); + + Value d3 = !_delta3->empty() ? + _delta3->prio() : std::numeric_limits::max(); + + _delta_sum = d3; OpType ot = D3; + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; } + + if (_delta_sum == std::numeric_limits::max()) { + return false; + } + + switch (ot) { + case D2: + { + Node n = _delta2->top(); + Arc a = (*_pred)[n]; + if ((*_matching)[n] == INVALID) { + augmentOnArc(a); + --unmatched; + } else { + Node v = _graph.target((*_matching)[n]); + if ((*_matching)[n] != + _graph.oppositeArc((*_matching)[v])) { + extractCycle(a); + --unmatched; + } else { + extendOnArc(a); + } + } + } break; + case D3: + { + Edge e = _delta3->top(); + + Node left = _graph.u(e); + Node right = _graph.v(e); + + int left_tree = _tree_set->find(left); + int right_tree = _tree_set->find(right); + + if (left_tree == right_tree) { + cycleOnEdge(e, left_tree); + --unmatched; + } else { + augmentOnEdge(e); + unmatched -= 2; + } + } break; + } + } + return true; + } + + /// \brief Run the algorithm. + /// + /// This method runs the \c %MaxWeightedPerfectFractionalMatching + /// algorithm. + /// + /// \note mwfm.run() is just a shortcut of the following code. + /// \code + /// mwpfm.init(); + /// mwpfm.start(); + /// \endcode + bool run() { + init(); + return start(); + } + + /// @} + + /// \name Primal Solution + /// Functions to get the primal solution, i.e. the maximum weighted + /// matching.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the weight of the matching. + /// + /// This function returns the weight of the found matching. This + /// value is scaled by \ref primalScale "primal scale". + /// + /// \pre Either run() or start() must be called before using this function. + Value matchingWeight() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + sum += _weight[(*_matching)[n]]; + } + } + return sum * primalScale / 2; + } + + /// \brief Return the number of covered nodes in the matching. + /// + /// This function returns the number of covered nodes in the matching. + /// + /// \pre Either run() or start() must be called before using this function. + int matchingSize() const { + int num = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + ++num; + } + } + return num; + } + + /// \brief Return \c true if the given edge is in the matching. + /// + /// This function returns \c true if the given edge is in the + /// found matching. The result is scaled by \ref primalScale + /// "primal scale". + /// + /// \pre Either run() or start() must be called before using this function. + int matching(const Edge& edge) const { + return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) + + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0); + } + + /// \brief Return the fractional matching arc (or edge) incident + /// to the given node. + /// + /// This function returns one of the fractional matching arc (or + /// edge) incident to the given node in the found matching or \c + /// INVALID if the node is not covered by the matching or if the + /// node is on an odd length cycle then it is the successor edge + /// on the cycle. + /// + /// \pre Either run() or start() must be called before using this function. + Arc matching(const Node& node) const { + return (*_matching)[node]; + } + + /// \brief Return a const reference to the matching map. + /// + /// This function returns a const reference to a node map that stores + /// the matching arc (or edge) incident to each node. + const MatchingMap& matchingMap() const { + return *_matching; + } + + /// @} + + /// \name Dual Solution + /// Functions to get the dual solution.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the value of the dual solution. + /// + /// This function returns the value of the dual solution. + /// It should be equal to the primal value scaled by \ref dualScale + /// "dual scale". + /// + /// \pre Either run() or start() must be called before using this function. + Value dualValue() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + sum += nodeValue(n); + } + return sum; + } + + /// \brief Return the dual value (potential) of the given node. + /// + /// This function returns the dual value (potential) of the given node. + /// + /// \pre Either run() or start() must be called before using this function. + Value nodeValue(const Node& n) const { + return (*_node_potential)[n]; + } + + /// @} + + }; + +} //END OF NAMESPACE LEMON + +#endif //LEMON_FRACTIONAL_MATCHING_H diff --git a/lemon/lemon/full_graph.h b/lemon/lemon/full_graph.h new file mode 100644 index 0000000..0158fcc --- /dev/null +++ b/lemon/lemon/full_graph.h @@ -0,0 +1,628 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_FULL_GRAPH_H +#define LEMON_FULL_GRAPH_H + +#include +#include + +///\ingroup graphs +///\file +///\brief FullDigraph and FullGraph classes. + +namespace lemon { + + class FullDigraphBase { + public: + + typedef FullDigraphBase Digraph; + + class Node; + class Arc; + + protected: + + int _node_num; + int _arc_num; + + FullDigraphBase() {} + + void construct(int n) { _node_num = n; _arc_num = n * n; } + + public: + + typedef True NodeNumTag; + typedef True ArcNumTag; + + Node operator()(int ix) const { return Node(ix); } + static int index(const Node& node) { return node._id; } + + Arc arc(const Node& s, const Node& t) const { + return Arc(s._id * _node_num + t._id); + } + + int nodeNum() const { return _node_num; } + int arcNum() const { return _arc_num; } + + int maxNodeId() const { return _node_num - 1; } + int maxArcId() const { return _arc_num - 1; } + + Node source(Arc arc) const { return arc._id / _node_num; } + Node target(Arc arc) const { return arc._id % _node_num; } + + static int id(Node node) { return node._id; } + static int id(Arc arc) { return arc._id; } + + static Node nodeFromId(int id) { return Node(id);} + static Arc arcFromId(int id) { return Arc(id);} + + typedef True FindArcTag; + + Arc findArc(Node s, Node t, Arc prev = INVALID) const { + return prev == INVALID ? arc(s, t) : INVALID; + } + + class Node { + friend class FullDigraphBase; + + protected: + int _id; + Node(int id) : _id(id) {} + public: + Node() {} + Node (Invalid) : _id(-1) {} + bool operator==(const Node node) const {return _id == node._id;} + bool operator!=(const Node node) const {return _id != node._id;} + bool operator<(const Node node) const {return _id < node._id;} + }; + + class Arc { + friend class FullDigraphBase; + + protected: + int _id; // _node_num * source + target; + + Arc(int id) : _id(id) {} + + public: + Arc() { } + Arc (Invalid) { _id = -1; } + bool operator==(const Arc arc) const {return _id == arc._id;} + bool operator!=(const Arc arc) const {return _id != arc._id;} + bool operator<(const Arc arc) const {return _id < arc._id;} + }; + + void first(Node& node) const { + node._id = _node_num - 1; + } + + static void next(Node& node) { + --node._id; + } + + void first(Arc& arc) const { + arc._id = _arc_num - 1; + } + + static void next(Arc& arc) { + --arc._id; + } + + void firstOut(Arc& arc, const Node& node) const { + arc._id = (node._id + 1) * _node_num - 1; + } + + void nextOut(Arc& arc) const { + if (arc._id % _node_num == 0) arc._id = 0; + --arc._id; + } + + void firstIn(Arc& arc, const Node& node) const { + arc._id = _arc_num + node._id - _node_num; + } + + void nextIn(Arc& arc) const { + arc._id -= _node_num; + if (arc._id < 0) arc._id = -1; + } + + }; + + typedef DigraphExtender ExtendedFullDigraphBase; + + /// \ingroup graphs + /// + /// \brief A directed full graph class. + /// + /// FullDigraph is a simple and fast implmenetation of directed full + /// (complete) graphs. It contains an arc from each node to each node + /// (including a loop for each node), therefore the number of arcs + /// is the square of the number of nodes. + /// This class is completely static and it needs constant memory space. + /// Thus you can neither add nor delete nodes or arcs, however + /// the structure can be resized using resize(). + /// + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept". + /// Most of its member functions and nested classes are documented + /// only in the concept class. + /// + /// This class provides constant time counting for nodes and arcs. + /// + /// \note FullDigraph and FullGraph classes are very similar, + /// but there are two differences. While this class conforms only + /// to the \ref concepts::Digraph "Digraph" concept, FullGraph + /// conforms to the \ref concepts::Graph "Graph" concept, + /// moreover FullGraph does not contain a loop for each + /// node as this class does. + /// + /// \sa FullGraph + class FullDigraph : public ExtendedFullDigraphBase { + typedef ExtendedFullDigraphBase Parent; + + public: + + /// \brief Default constructor. + /// + /// Default constructor. The number of nodes and arcs will be zero. + FullDigraph() { construct(0); } + + /// \brief Constructor + /// + /// Constructor. + /// \param n The number of the nodes. + FullDigraph(int n) { construct(n); } + + /// \brief Resizes the digraph + /// + /// This function resizes the digraph. It fully destroys and + /// rebuilds the structure, therefore the maps of the digraph will be + /// reallocated automatically and the previous values will be lost. + void resize(int n) { + Parent::notifier(Arc()).clear(); + Parent::notifier(Node()).clear(); + construct(n); + Parent::notifier(Node()).build(); + Parent::notifier(Arc()).build(); + } + + /// \brief Returns the node with the given index. + /// + /// Returns the node with the given index. Since this structure is + /// completely static, the nodes can be indexed with integers from + /// the range [0..nodeNum()-1]. + /// The index of a node is the same as its ID. + /// \sa index() + Node operator()(int ix) const { return Parent::operator()(ix); } + + /// \brief Returns the index of the given node. + /// + /// Returns the index of the given node. Since this structure is + /// completely static, the nodes can be indexed with integers from + /// the range [0..nodeNum()-1]. + /// The index of a node is the same as its ID. + /// \sa operator()() + static int index(const Node& node) { return Parent::index(node); } + + /// \brief Returns the arc connecting the given nodes. + /// + /// Returns the arc connecting the given nodes. + Arc arc(Node u, Node v) const { + return Parent::arc(u, v); + } + + /// \brief Number of nodes. + int nodeNum() const { return Parent::nodeNum(); } + /// \brief Number of arcs. + int arcNum() const { return Parent::arcNum(); } + }; + + + class FullGraphBase { + public: + + typedef FullGraphBase Graph; + + class Node; + class Arc; + class Edge; + + protected: + + int _node_num; + int _edge_num; + + FullGraphBase() {} + + void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; } + + int _uid(int e) const { + int u = e / _node_num; + int v = e % _node_num; + return u < v ? u : _node_num - 2 - u; + } + + int _vid(int e) const { + int u = e / _node_num; + int v = e % _node_num; + return u < v ? v : _node_num - 1 - v; + } + + void _uvid(int e, int& u, int& v) const { + u = e / _node_num; + v = e % _node_num; + if (u >= v) { + u = _node_num - 2 - u; + v = _node_num - 1 - v; + } + } + + void _stid(int a, int& s, int& t) const { + if ((a & 1) == 1) { + _uvid(a >> 1, s, t); + } else { + _uvid(a >> 1, t, s); + } + } + + int _eid(int u, int v) const { + if (u < (_node_num - 1) / 2) { + return u * _node_num + v; + } else { + return (_node_num - 1 - u) * _node_num - v - 1; + } + } + + public: + + Node operator()(int ix) const { return Node(ix); } + static int index(const Node& node) { return node._id; } + + Edge edge(const Node& u, const Node& v) const { + if (u._id < v._id) { + return Edge(_eid(u._id, v._id)); + } else if (u._id != v._id) { + return Edge(_eid(v._id, u._id)); + } else { + return INVALID; + } + } + + Arc arc(const Node& s, const Node& t) const { + if (s._id < t._id) { + return Arc((_eid(s._id, t._id) << 1) | 1); + } else if (s._id != t._id) { + return Arc(_eid(t._id, s._id) << 1); + } else { + return INVALID; + } + } + + typedef True NodeNumTag; + typedef True ArcNumTag; + typedef True EdgeNumTag; + + int nodeNum() const { return _node_num; } + int arcNum() const { return 2 * _edge_num; } + int edgeNum() const { return _edge_num; } + + static int id(Node node) { return node._id; } + static int id(Arc arc) { return arc._id; } + static int id(Edge edge) { return edge._id; } + + int maxNodeId() const { return _node_num-1; } + int maxArcId() const { return 2 * _edge_num-1; } + int maxEdgeId() const { return _edge_num-1; } + + static Node nodeFromId(int id) { return Node(id);} + static Arc arcFromId(int id) { return Arc(id);} + static Edge edgeFromId(int id) { return Edge(id);} + + Node u(Edge edge) const { + return Node(_uid(edge._id)); + } + + Node v(Edge edge) const { + return Node(_vid(edge._id)); + } + + Node source(Arc arc) const { + return Node((arc._id & 1) == 1 ? + _uid(arc._id >> 1) : _vid(arc._id >> 1)); + } + + Node target(Arc arc) const { + return Node((arc._id & 1) == 1 ? + _vid(arc._id >> 1) : _uid(arc._id >> 1)); + } + + typedef True FindEdgeTag; + typedef True FindArcTag; + + Edge findEdge(Node u, Node v, Edge prev = INVALID) const { + return prev != INVALID ? INVALID : edge(u, v); + } + + Arc findArc(Node s, Node t, Arc prev = INVALID) const { + return prev != INVALID ? INVALID : arc(s, t); + } + + class Node { + friend class FullGraphBase; + + protected: + int _id; + Node(int id) : _id(id) {} + public: + Node() {} + Node (Invalid) { _id = -1; } + bool operator==(const Node node) const {return _id == node._id;} + bool operator!=(const Node node) const {return _id != node._id;} + bool operator<(const Node node) const {return _id < node._id;} + }; + + class Edge { + friend class FullGraphBase; + friend class Arc; + + protected: + int _id; + + Edge(int id) : _id(id) {} + + public: + Edge() { } + Edge (Invalid) { _id = -1; } + + bool operator==(const Edge edge) const {return _id == edge._id;} + bool operator!=(const Edge edge) const {return _id != edge._id;} + bool operator<(const Edge edge) const {return _id < edge._id;} + }; + + class Arc { + friend class FullGraphBase; + + protected: + int _id; + + Arc(int id) : _id(id) {} + + public: + Arc() { } + Arc (Invalid) { _id = -1; } + + operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); } + + bool operator==(const Arc arc) const {return _id == arc._id;} + bool operator!=(const Arc arc) const {return _id != arc._id;} + bool operator<(const Arc arc) const {return _id < arc._id;} + }; + + static bool direction(Arc arc) { + return (arc._id & 1) == 1; + } + + static Arc direct(Edge edge, bool dir) { + return Arc((edge._id << 1) | (dir ? 1 : 0)); + } + + void first(Node& node) const { + node._id = _node_num - 1; + } + + static void next(Node& node) { + --node._id; + } + + void first(Arc& arc) const { + arc._id = (_edge_num << 1) - 1; + } + + static void next(Arc& arc) { + --arc._id; + } + + void first(Edge& edge) const { + edge._id = _edge_num - 1; + } + + static void next(Edge& edge) { + --edge._id; + } + + void firstOut(Arc& arc, const Node& node) const { + int s = node._id, t = _node_num - 1; + if (s < t) { + arc._id = (_eid(s, t) << 1) | 1; + } else { + --t; + arc._id = (t != -1 ? (_eid(t, s) << 1) : -1); + } + } + + void nextOut(Arc& arc) const { + int s, t; + _stid(arc._id, s, t); + --t; + if (s < t) { + arc._id = (_eid(s, t) << 1) | 1; + } else { + if (s == t) --t; + arc._id = (t != -1 ? (_eid(t, s) << 1) : -1); + } + } + + void firstIn(Arc& arc, const Node& node) const { + int s = _node_num - 1, t = node._id; + if (s > t) { + arc._id = (_eid(t, s) << 1); + } else { + --s; + arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1); + } + } + + void nextIn(Arc& arc) const { + int s, t; + _stid(arc._id, s, t); + --s; + if (s > t) { + arc._id = (_eid(t, s) << 1); + } else { + if (s == t) --s; + arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1); + } + } + + void firstInc(Edge& edge, bool& dir, const Node& node) const { + int u = node._id, v = _node_num - 1; + if (u < v) { + edge._id = _eid(u, v); + dir = true; + } else { + --v; + edge._id = (v != -1 ? _eid(v, u) : -1); + dir = false; + } + } + + void nextInc(Edge& edge, bool& dir) const { + int u, v; + if (dir) { + _uvid(edge._id, u, v); + --v; + if (u < v) { + edge._id = _eid(u, v); + } else { + --v; + edge._id = (v != -1 ? _eid(v, u) : -1); + dir = false; + } + } else { + _uvid(edge._id, v, u); + --v; + edge._id = (v != -1 ? _eid(v, u) : -1); + } + } + + }; + + typedef GraphExtender ExtendedFullGraphBase; + + /// \ingroup graphs + /// + /// \brief An undirected full graph class. + /// + /// FullGraph is a simple and fast implmenetation of undirected full + /// (complete) graphs. It contains an edge between every distinct pair + /// of nodes, therefore the number of edges is n(n-1)/2. + /// This class is completely static and it needs constant memory space. + /// Thus you can neither add nor delete nodes or edges, however + /// the structure can be resized using resize(). + /// + /// This type fully conforms to the \ref concepts::Graph "Graph concept". + /// Most of its member functions and nested classes are documented + /// only in the concept class. + /// + /// This class provides constant time counting for nodes, edges and arcs. + /// + /// \note FullDigraph and FullGraph classes are very similar, + /// but there are two differences. While FullDigraph + /// conforms only to the \ref concepts::Digraph "Digraph" concept, + /// this class conforms to the \ref concepts::Graph "Graph" concept, + /// moreover this class does not contain a loop for each + /// node as FullDigraph does. + /// + /// \sa FullDigraph + class FullGraph : public ExtendedFullGraphBase { + typedef ExtendedFullGraphBase Parent; + + public: + + /// \brief Default constructor. + /// + /// Default constructor. The number of nodes and edges will be zero. + FullGraph() { construct(0); } + + /// \brief Constructor + /// + /// Constructor. + /// \param n The number of the nodes. + FullGraph(int n) { construct(n); } + + /// \brief Resizes the graph + /// + /// This function resizes the graph. It fully destroys and + /// rebuilds the structure, therefore the maps of the graph will be + /// reallocated automatically and the previous values will be lost. + void resize(int n) { + Parent::notifier(Arc()).clear(); + Parent::notifier(Edge()).clear(); + Parent::notifier(Node()).clear(); + construct(n); + Parent::notifier(Node()).build(); + Parent::notifier(Edge()).build(); + Parent::notifier(Arc()).build(); + } + + /// \brief Returns the node with the given index. + /// + /// Returns the node with the given index. Since this structure is + /// completely static, the nodes can be indexed with integers from + /// the range [0..nodeNum()-1]. + /// The index of a node is the same as its ID. + /// \sa index() + Node operator()(int ix) const { return Parent::operator()(ix); } + + /// \brief Returns the index of the given node. + /// + /// Returns the index of the given node. Since this structure is + /// completely static, the nodes can be indexed with integers from + /// the range [0..nodeNum()-1]. + /// The index of a node is the same as its ID. + /// \sa operator()() + static int index(const Node& node) { return Parent::index(node); } + + /// \brief Returns the arc connecting the given nodes. + /// + /// Returns the arc connecting the given nodes. + Arc arc(Node s, Node t) const { + return Parent::arc(s, t); + } + + /// \brief Returns the edge connecting the given nodes. + /// + /// Returns the edge connecting the given nodes. + Edge edge(Node u, Node v) const { + return Parent::edge(u, v); + } + + /// \brief Number of nodes. + int nodeNum() const { return Parent::nodeNum(); } + /// \brief Number of arcs. + int arcNum() const { return Parent::arcNum(); } + /// \brief Number of edges. + int edgeNum() const { return Parent::edgeNum(); } + + }; + + +} //namespace lemon + + +#endif //LEMON_FULL_GRAPH_H diff --git a/lemon/lemon/glpk.cc b/lemon/lemon/glpk.cc new file mode 100644 index 0000000..17a6d76 --- /dev/null +++ b/lemon/lemon/glpk.cc @@ -0,0 +1,1003 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Implementation of the LEMON GLPK LP and MIP solver interface. + +#include +#include + +#include + +namespace lemon { + + // GlpkBase members + + GlpkBase::GlpkBase() : LpBase() { + lp = glp_create_prob(); + glp_create_index(lp); + messageLevel(MESSAGE_NOTHING); + } + + GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() { + lp = glp_create_prob(); + glp_copy_prob(lp, other.lp, GLP_ON); + glp_create_index(lp); + rows = other.rows; + cols = other.cols; + messageLevel(MESSAGE_NOTHING); + } + + GlpkBase::~GlpkBase() { + glp_delete_prob(lp); + } + + int GlpkBase::_addCol() { + int i = glp_add_cols(lp, 1); + glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0); + return i; + } + + int GlpkBase::_addRow() { + int i = glp_add_rows(lp, 1); + glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0); + return i; + } + + int GlpkBase::_addRow(Value lo, ExprIterator b, + ExprIterator e, Value up) { + int i = glp_add_rows(lp, 1); + + if (lo == -INF) { + if (up == INF) { + glp_set_row_bnds(lp, i, GLP_FR, lo, up); + } else { + glp_set_row_bnds(lp, i, GLP_UP, lo, up); + } + } else { + if (up == INF) { + glp_set_row_bnds(lp, i, GLP_LO, lo, up); + } else if (lo != up) { + glp_set_row_bnds(lp, i, GLP_DB, lo, up); + } else { + glp_set_row_bnds(lp, i, GLP_FX, lo, up); + } + } + + std::vector indexes; + std::vector values; + + indexes.push_back(0); + values.push_back(0); + + for(ExprIterator it = b; it != e; ++it) { + indexes.push_back(it->first); + values.push_back(it->second); + } + + glp_set_mat_row(lp, i, values.size() - 1, + &indexes.front(), &values.front()); + return i; + } + + void GlpkBase::_eraseCol(int i) { + int ca[2]; + ca[1] = i; + glp_del_cols(lp, 1, ca); + } + + void GlpkBase::_eraseRow(int i) { + int ra[2]; + ra[1] = i; + glp_del_rows(lp, 1, ra); + } + + void GlpkBase::_eraseColId(int i) { + cols.eraseIndex(i); + cols.shiftIndices(i); + } + + void GlpkBase::_eraseRowId(int i) { + rows.eraseIndex(i); + rows.shiftIndices(i); + } + + void GlpkBase::_getColName(int c, std::string& name) const { + const char *str = glp_get_col_name(lp, c); + if (str) name = str; + else name.clear(); + } + + void GlpkBase::_setColName(int c, const std::string & name) { + glp_set_col_name(lp, c, const_cast(name.c_str())); + + } + + int GlpkBase::_colByName(const std::string& name) const { + int k = glp_find_col(lp, const_cast(name.c_str())); + return k > 0 ? k : -1; + } + + void GlpkBase::_getRowName(int r, std::string& name) const { + const char *str = glp_get_row_name(lp, r); + if (str) name = str; + else name.clear(); + } + + void GlpkBase::_setRowName(int r, const std::string & name) { + glp_set_row_name(lp, r, const_cast(name.c_str())); + + } + + int GlpkBase::_rowByName(const std::string& name) const { + int k = glp_find_row(lp, const_cast(name.c_str())); + return k > 0 ? k : -1; + } + + void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) { + std::vector indexes; + std::vector values; + + indexes.push_back(0); + values.push_back(0); + + for(ExprIterator it = b; it != e; ++it) { + indexes.push_back(it->first); + values.push_back(it->second); + } + + glp_set_mat_row(lp, i, values.size() - 1, + &indexes.front(), &values.front()); + } + + void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const { + int length = glp_get_mat_row(lp, ix, 0, 0); + + std::vector indexes(length + 1); + std::vector values(length + 1); + + glp_get_mat_row(lp, ix, &indexes.front(), &values.front()); + + for (int i = 1; i <= length; ++i) { + *b = std::make_pair(indexes[i], values[i]); + ++b; + } + } + + void GlpkBase::_setColCoeffs(int ix, ExprIterator b, + ExprIterator e) { + + std::vector indexes; + std::vector values; + + indexes.push_back(0); + values.push_back(0); + + for(ExprIterator it = b; it != e; ++it) { + indexes.push_back(it->first); + values.push_back(it->second); + } + + glp_set_mat_col(lp, ix, values.size() - 1, + &indexes.front(), &values.front()); + } + + void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const { + int length = glp_get_mat_col(lp, ix, 0, 0); + + std::vector indexes(length + 1); + std::vector values(length + 1); + + glp_get_mat_col(lp, ix, &indexes.front(), &values.front()); + + for (int i = 1; i <= length; ++i) { + *b = std::make_pair(indexes[i], values[i]); + ++b; + } + } + + void GlpkBase::_setCoeff(int ix, int jx, Value value) { + + if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) { + + int length = glp_get_mat_row(lp, ix, 0, 0); + + std::vector indexes(length + 2); + std::vector values(length + 2); + + glp_get_mat_row(lp, ix, &indexes.front(), &values.front()); + + //The following code does not suppose that the elements of the + //array indexes are sorted + bool found = false; + for (int i = 1; i <= length; ++i) { + if (indexes[i] == jx) { + found = true; + values[i] = value; + break; + } + } + if (!found) { + ++length; + indexes[length] = jx; + values[length] = value; + } + + glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front()); + + } else { + + int length = glp_get_mat_col(lp, jx, 0, 0); + + std::vector indexes(length + 2); + std::vector values(length + 2); + + glp_get_mat_col(lp, jx, &indexes.front(), &values.front()); + + //The following code does not suppose that the elements of the + //array indexes are sorted + bool found = false; + for (int i = 1; i <= length; ++i) { + if (indexes[i] == ix) { + found = true; + values[i] = value; + break; + } + } + if (!found) { + ++length; + indexes[length] = ix; + values[length] = value; + } + + glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front()); + } + + } + + GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const { + + int length = glp_get_mat_row(lp, ix, 0, 0); + + std::vector indexes(length + 1); + std::vector values(length + 1); + + glp_get_mat_row(lp, ix, &indexes.front(), &values.front()); + + for (int i = 1; i <= length; ++i) { + if (indexes[i] == jx) { + return values[i]; + } + } + + return 0; + } + + void GlpkBase::_setColLowerBound(int i, Value lo) { + LEMON_ASSERT(lo != INF, "Invalid bound"); + + int b = glp_get_col_type(lp, i); + double up = glp_get_col_ub(lp, i); + if (lo == -INF) { + switch (b) { + case GLP_FR: + case GLP_LO: + glp_set_col_bnds(lp, i, GLP_FR, lo, up); + break; + case GLP_UP: + break; + case GLP_DB: + case GLP_FX: + glp_set_col_bnds(lp, i, GLP_UP, lo, up); + break; + default: + break; + } + } else { + switch (b) { + case GLP_FR: + case GLP_LO: + glp_set_col_bnds(lp, i, GLP_LO, lo, up); + break; + case GLP_UP: + case GLP_DB: + case GLP_FX: + if (lo == up) + glp_set_col_bnds(lp, i, GLP_FX, lo, up); + else + glp_set_col_bnds(lp, i, GLP_DB, lo, up); + break; + default: + break; + } + } + } + + GlpkBase::Value GlpkBase::_getColLowerBound(int i) const { + int b = glp_get_col_type(lp, i); + switch (b) { + case GLP_LO: + case GLP_DB: + case GLP_FX: + return glp_get_col_lb(lp, i); + default: + return -INF; + } + } + + void GlpkBase::_setColUpperBound(int i, Value up) { + LEMON_ASSERT(up != -INF, "Invalid bound"); + + int b = glp_get_col_type(lp, i); + double lo = glp_get_col_lb(lp, i); + if (up == INF) { + switch (b) { + case GLP_FR: + case GLP_LO: + break; + case GLP_UP: + glp_set_col_bnds(lp, i, GLP_FR, lo, up); + break; + case GLP_DB: + case GLP_FX: + glp_set_col_bnds(lp, i, GLP_LO, lo, up); + break; + default: + break; + } + } else { + switch (b) { + case GLP_FR: + glp_set_col_bnds(lp, i, GLP_UP, lo, up); + break; + case GLP_UP: + glp_set_col_bnds(lp, i, GLP_UP, lo, up); + break; + case GLP_LO: + case GLP_DB: + case GLP_FX: + if (lo == up) + glp_set_col_bnds(lp, i, GLP_FX, lo, up); + else + glp_set_col_bnds(lp, i, GLP_DB, lo, up); + break; + default: + break; + } + } + + } + + GlpkBase::Value GlpkBase::_getColUpperBound(int i) const { + int b = glp_get_col_type(lp, i); + switch (b) { + case GLP_UP: + case GLP_DB: + case GLP_FX: + return glp_get_col_ub(lp, i); + default: + return INF; + } + } + + void GlpkBase::_setRowLowerBound(int i, Value lo) { + LEMON_ASSERT(lo != INF, "Invalid bound"); + + int b = glp_get_row_type(lp, i); + double up = glp_get_row_ub(lp, i); + if (lo == -INF) { + switch (b) { + case GLP_FR: + case GLP_LO: + glp_set_row_bnds(lp, i, GLP_FR, lo, up); + break; + case GLP_UP: + break; + case GLP_DB: + case GLP_FX: + glp_set_row_bnds(lp, i, GLP_UP, lo, up); + break; + default: + break; + } + } else { + switch (b) { + case GLP_FR: + case GLP_LO: + glp_set_row_bnds(lp, i, GLP_LO, lo, up); + break; + case GLP_UP: + case GLP_DB: + case GLP_FX: + if (lo == up) + glp_set_row_bnds(lp, i, GLP_FX, lo, up); + else + glp_set_row_bnds(lp, i, GLP_DB, lo, up); + break; + default: + break; + } + } + + } + + GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const { + int b = glp_get_row_type(lp, i); + switch (b) { + case GLP_LO: + case GLP_DB: + case GLP_FX: + return glp_get_row_lb(lp, i); + default: + return -INF; + } + } + + void GlpkBase::_setRowUpperBound(int i, Value up) { + LEMON_ASSERT(up != -INF, "Invalid bound"); + + int b = glp_get_row_type(lp, i); + double lo = glp_get_row_lb(lp, i); + if (up == INF) { + switch (b) { + case GLP_FR: + case GLP_LO: + break; + case GLP_UP: + glp_set_row_bnds(lp, i, GLP_FR, lo, up); + break; + case GLP_DB: + case GLP_FX: + glp_set_row_bnds(lp, i, GLP_LO, lo, up); + break; + default: + break; + } + } else { + switch (b) { + case GLP_FR: + glp_set_row_bnds(lp, i, GLP_UP, lo, up); + break; + case GLP_UP: + glp_set_row_bnds(lp, i, GLP_UP, lo, up); + break; + case GLP_LO: + case GLP_DB: + case GLP_FX: + if (lo == up) + glp_set_row_bnds(lp, i, GLP_FX, lo, up); + else + glp_set_row_bnds(lp, i, GLP_DB, lo, up); + break; + default: + break; + } + } + } + + GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const { + int b = glp_get_row_type(lp, i); + switch (b) { + case GLP_UP: + case GLP_DB: + case GLP_FX: + return glp_get_row_ub(lp, i); + default: + return INF; + } + } + + void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) { + for (int i = 1; i <= glp_get_num_cols(lp); ++i) { + glp_set_obj_coef(lp, i, 0.0); + } + for (ExprIterator it = b; it != e; ++it) { + glp_set_obj_coef(lp, it->first, it->second); + } + } + + void GlpkBase::_getObjCoeffs(InsertIterator b) const { + for (int i = 1; i <= glp_get_num_cols(lp); ++i) { + Value val = glp_get_obj_coef(lp, i); + if (val != 0.0) { + *b = std::make_pair(i, val); + ++b; + } + } + } + + void GlpkBase::_setObjCoeff(int i, Value obj_coef) { + //i = 0 means the constant term (shift) + glp_set_obj_coef(lp, i, obj_coef); + } + + GlpkBase::Value GlpkBase::_getObjCoeff(int i) const { + //i = 0 means the constant term (shift) + return glp_get_obj_coef(lp, i); + } + + void GlpkBase::_setSense(GlpkBase::Sense sense) { + switch (sense) { + case MIN: + glp_set_obj_dir(lp, GLP_MIN); + break; + case MAX: + glp_set_obj_dir(lp, GLP_MAX); + break; + } + } + + GlpkBase::Sense GlpkBase::_getSense() const { + switch(glp_get_obj_dir(lp)) { + case GLP_MIN: + return MIN; + case GLP_MAX: + return MAX; + default: + LEMON_ASSERT(false, "Wrong sense"); + return GlpkBase::Sense(); + } + } + + void GlpkBase::_clear() { + glp_erase_prob(lp); + rows.clear(); + cols.clear(); + } + + void GlpkBase::freeEnv() { + glp_free_env(); + } + + void GlpkBase::_messageLevel(MessageLevel level) { + switch (level) { + case MESSAGE_NOTHING: + _message_level = GLP_MSG_OFF; + break; + case MESSAGE_ERROR: + _message_level = GLP_MSG_ERR; + break; + case MESSAGE_WARNING: + _message_level = GLP_MSG_ERR; + break; + case MESSAGE_NORMAL: + _message_level = GLP_MSG_ON; + break; + case MESSAGE_VERBOSE: + _message_level = GLP_MSG_ALL; + break; + } + } + + GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper; + + // GlpkLp members + + GlpkLp::GlpkLp() + : LpBase(), LpSolver(), GlpkBase() { + presolver(false); + } + + GlpkLp::GlpkLp(const GlpkLp& other) + : LpBase(other), LpSolver(other), GlpkBase(other) { + presolver(false); + } + + GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; } + GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); } + + const char* GlpkLp::_solverName() const { return "GlpkLp"; } + + void GlpkLp::_clear_temporals() { + _primal_ray.clear(); + _dual_ray.clear(); + } + + GlpkLp::SolveExitStatus GlpkLp::_solve() { + return solvePrimal(); + } + + GlpkLp::SolveExitStatus GlpkLp::solvePrimal() { + _clear_temporals(); + + glp_smcp smcp; + glp_init_smcp(&smcp); + + smcp.msg_lev = _message_level; + smcp.presolve = _presolve; + + // If the basis is not valid we get an error return value. + // In this case we can try to create a new basis. + switch (glp_simplex(lp, &smcp)) { + case 0: + break; + case GLP_EBADB: + case GLP_ESING: + case GLP_ECOND: + glp_term_out(false); + glp_adv_basis(lp, 0); + glp_term_out(true); + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED; + break; + default: + return UNSOLVED; + } + + return SOLVED; + } + + GlpkLp::SolveExitStatus GlpkLp::solveDual() { + _clear_temporals(); + + glp_smcp smcp; + glp_init_smcp(&smcp); + + smcp.msg_lev = _message_level; + smcp.meth = GLP_DUAL; + smcp.presolve = _presolve; + + // If the basis is not valid we get an error return value. + // In this case we can try to create a new basis. + switch (glp_simplex(lp, &smcp)) { + case 0: + break; + case GLP_EBADB: + case GLP_ESING: + case GLP_ECOND: + glp_term_out(false); + glp_adv_basis(lp, 0); + glp_term_out(true); + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED; + break; + default: + return UNSOLVED; + } + return SOLVED; + } + + GlpkLp::Value GlpkLp::_getPrimal(int i) const { + return glp_get_col_prim(lp, i); + } + + GlpkLp::Value GlpkLp::_getDual(int i) const { + return glp_get_row_dual(lp, i); + } + + GlpkLp::Value GlpkLp::_getPrimalValue() const { + return glp_get_obj_val(lp); + } + + GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const { + switch (glp_get_col_stat(lp, i)) { + case GLP_BS: + return BASIC; + case GLP_UP: + return UPPER; + case GLP_LO: + return LOWER; + case GLP_NF: + return FREE; + case GLP_NS: + return FIXED; + default: + LEMON_ASSERT(false, "Wrong column status"); + return GlpkLp::VarStatus(); + } + } + + GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const { + switch (glp_get_row_stat(lp, i)) { + case GLP_BS: + return BASIC; + case GLP_UP: + return UPPER; + case GLP_LO: + return LOWER; + case GLP_NF: + return FREE; + case GLP_NS: + return FIXED; + default: + LEMON_ASSERT(false, "Wrong row status"); + return GlpkLp::VarStatus(); + } + } + + GlpkLp::Value GlpkLp::_getPrimalRay(int i) const { + if (_primal_ray.empty()) { + int row_num = glp_get_num_rows(lp); + int col_num = glp_get_num_cols(lp); + + _primal_ray.resize(col_num + 1, 0.0); + + int index = glp_get_unbnd_ray(lp); + if (index != 0) { + // The primal ray is found in primal simplex second phase + LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) : + glp_get_col_stat(lp, index - row_num)) != GLP_BS, + "Wrong primal ray"); + + bool negate = glp_get_obj_dir(lp) == GLP_MAX; + + if (index > row_num) { + _primal_ray[index - row_num] = 1.0; + if (glp_get_col_dual(lp, index - row_num) > 0) { + negate = !negate; + } + } else { + if (glp_get_row_dual(lp, index) > 0) { + negate = !negate; + } + } + + std::vector ray_indexes(row_num + 1); + std::vector ray_values(row_num + 1); + int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(), + &ray_values.front()); + + for (int i = 1; i <= ray_length; ++i) { + if (ray_indexes[i] > row_num) { + _primal_ray[ray_indexes[i] - row_num] = ray_values[i]; + } + } + + if (negate) { + for (int i = 1; i <= col_num; ++i) { + _primal_ray[i] = - _primal_ray[i]; + } + } + } else { + for (int i = 1; i <= col_num; ++i) { + _primal_ray[i] = glp_get_col_prim(lp, i); + } + } + } + return _primal_ray[i]; + } + + GlpkLp::Value GlpkLp::_getDualRay(int i) const { + if (_dual_ray.empty()) { + int row_num = glp_get_num_rows(lp); + + _dual_ray.resize(row_num + 1, 0.0); + + int index = glp_get_unbnd_ray(lp); + if (index != 0) { + // The dual ray is found in dual simplex second phase + LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) : + glp_get_col_stat(lp, index - row_num)) == GLP_BS, + + "Wrong dual ray"); + + int idx; + bool negate = false; + + if (index > row_num) { + idx = glp_get_col_bind(lp, index - row_num); + if (glp_get_col_prim(lp, index - row_num) > + glp_get_col_ub(lp, index - row_num)) { + negate = true; + } + } else { + idx = glp_get_row_bind(lp, index); + if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) { + negate = true; + } + } + + _dual_ray[idx] = negate ? - 1.0 : 1.0; + + glp_btran(lp, &_dual_ray.front()); + } else { + double eps = 1e-7; + // The dual ray is found in primal simplex first phase + // We assume that the glpk minimizes the slack to get feasible solution + for (int i = 1; i <= row_num; ++i) { + int index = glp_get_bhead(lp, i); + if (index <= row_num) { + double res = glp_get_row_prim(lp, index); + if (res > glp_get_row_ub(lp, index) + eps) { + _dual_ray[i] = -1; + } else if (res < glp_get_row_lb(lp, index) - eps) { + _dual_ray[i] = 1; + } else { + _dual_ray[i] = 0; + } + _dual_ray[i] *= glp_get_rii(lp, index); + } else { + double res = glp_get_col_prim(lp, index - row_num); + if (res > glp_get_col_ub(lp, index - row_num) + eps) { + _dual_ray[i] = -1; + } else if (res < glp_get_col_lb(lp, index - row_num) - eps) { + _dual_ray[i] = 1; + } else { + _dual_ray[i] = 0; + } + _dual_ray[i] /= glp_get_sjj(lp, index - row_num); + } + } + + glp_btran(lp, &_dual_ray.front()); + + for (int i = 1; i <= row_num; ++i) { + _dual_ray[i] /= glp_get_rii(lp, i); + } + } + } + return _dual_ray[i]; + } + + GlpkLp::ProblemType GlpkLp::_getPrimalType() const { + if (glp_get_status(lp) == GLP_OPT) + return OPTIMAL; + switch (glp_get_prim_stat(lp)) { + case GLP_UNDEF: + return UNDEFINED; + case GLP_FEAS: + case GLP_INFEAS: + if (glp_get_dual_stat(lp) == GLP_NOFEAS) { + return UNBOUNDED; + } else { + return UNDEFINED; + } + case GLP_NOFEAS: + return INFEASIBLE; + default: + LEMON_ASSERT(false, "Wrong primal type"); + return GlpkLp::ProblemType(); + } + } + + GlpkLp::ProblemType GlpkLp::_getDualType() const { + if (glp_get_status(lp) == GLP_OPT) + return OPTIMAL; + switch (glp_get_dual_stat(lp)) { + case GLP_UNDEF: + return UNDEFINED; + case GLP_FEAS: + case GLP_INFEAS: + if (glp_get_prim_stat(lp) == GLP_NOFEAS) { + return UNBOUNDED; + } else { + return UNDEFINED; + } + case GLP_NOFEAS: + return INFEASIBLE; + default: + LEMON_ASSERT(false, "Wrong primal type"); + return GlpkLp::ProblemType(); + } + } + + void GlpkLp::presolver(bool presolve) { + _presolve = presolve; + } + + // GlpkMip members + + GlpkMip::GlpkMip() + : LpBase(), MipSolver(), GlpkBase() { + } + + GlpkMip::GlpkMip(const GlpkMip& other) + : LpBase(), MipSolver(), GlpkBase(other) { + } + + void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) { + switch (col_type) { + case INTEGER: + glp_set_col_kind(lp, i, GLP_IV); + break; + case REAL: + glp_set_col_kind(lp, i, GLP_CV); + break; + } + } + + GlpkMip::ColTypes GlpkMip::_getColType(int i) const { + switch (glp_get_col_kind(lp, i)) { + case GLP_IV: + case GLP_BV: + return INTEGER; + default: + return REAL; + } + + } + + GlpkMip::SolveExitStatus GlpkMip::_solve() { + glp_smcp smcp; + glp_init_smcp(&smcp); + + smcp.msg_lev = _message_level; + smcp.meth = GLP_DUAL; + + // If the basis is not valid we get an error return value. + // In this case we can try to create a new basis. + switch (glp_simplex(lp, &smcp)) { + case 0: + break; + case GLP_EBADB: + case GLP_ESING: + case GLP_ECOND: + glp_term_out(false); + glp_adv_basis(lp, 0); + glp_term_out(true); + if (glp_simplex(lp, &smcp) != 0) return UNSOLVED; + break; + default: + return UNSOLVED; + } + + if (glp_get_status(lp) != GLP_OPT) return SOLVED; + + glp_iocp iocp; + glp_init_iocp(&iocp); + + iocp.msg_lev = _message_level; + + if (glp_intopt(lp, &iocp) != 0) return UNSOLVED; + return SOLVED; + } + + + GlpkMip::ProblemType GlpkMip::_getType() const { + switch (glp_get_status(lp)) { + case GLP_OPT: + switch (glp_mip_status(lp)) { + case GLP_UNDEF: + return UNDEFINED; + case GLP_NOFEAS: + return INFEASIBLE; + case GLP_FEAS: + return FEASIBLE; + case GLP_OPT: + return OPTIMAL; + default: + LEMON_ASSERT(false, "Wrong problem type."); + return GlpkMip::ProblemType(); + } + case GLP_NOFEAS: + return INFEASIBLE; + case GLP_INFEAS: + case GLP_FEAS: + if (glp_get_dual_stat(lp) == GLP_NOFEAS) { + return UNBOUNDED; + } else { + return UNDEFINED; + } + default: + LEMON_ASSERT(false, "Wrong problem type."); + return GlpkMip::ProblemType(); + } + } + + GlpkMip::Value GlpkMip::_getSol(int i) const { + return glp_mip_col_val(lp, i); + } + + GlpkMip::Value GlpkMip::_getSolValue() const { + return glp_mip_obj_val(lp); + } + + GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; } + GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); } + + const char* GlpkMip::_solverName() const { return "GlpkMip"; } + +} //END OF NAMESPACE LEMON diff --git a/lemon/lemon/glpk.h b/lemon/lemon/glpk.h new file mode 100644 index 0000000..00da8c9 --- /dev/null +++ b/lemon/lemon/glpk.h @@ -0,0 +1,248 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_GLPK_H +#define LEMON_GLPK_H + +///\file +///\brief Header of the LEMON-GLPK lp solver interface. +///\ingroup lp_group + +#include + +namespace lemon { + + namespace _solver_bits { + class VoidPtr { + private: + void *_ptr; + public: + VoidPtr() : _ptr(0) {} + + template + VoidPtr(T* ptr) : _ptr(reinterpret_cast(ptr)) {} + + template + VoidPtr& operator=(T* ptr) { + _ptr = reinterpret_cast(ptr); + return *this; + } + + template + operator T*() const { return reinterpret_cast(_ptr); } + }; + } + + /// \brief Base interface for the GLPK LP and MIP solver + /// + /// This class implements the common interface of the GLPK LP and MIP solver. + /// \ingroup lp_group + class GlpkBase : virtual public LpBase { + protected: + + _solver_bits::VoidPtr lp; + + GlpkBase(); + GlpkBase(const GlpkBase&); + virtual ~GlpkBase(); + + protected: + + virtual int _addCol(); + virtual int _addRow(); + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u); + + virtual void _eraseCol(int i); + virtual void _eraseRow(int i); + + virtual void _eraseColId(int i); + virtual void _eraseRowId(int i); + + virtual void _getColName(int col, std::string& name) const; + virtual void _setColName(int col, const std::string& name); + virtual int _colByName(const std::string& name) const; + + virtual void _getRowName(int row, std::string& name) const; + virtual void _setRowName(int row, const std::string& name); + virtual int _rowByName(const std::string& name) const; + + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getRowCoeffs(int i, InsertIterator b) const; + + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getColCoeffs(int i, InsertIterator b) const; + + virtual void _setCoeff(int row, int col, Value value); + virtual Value _getCoeff(int row, int col) const; + + virtual void _setColLowerBound(int i, Value value); + virtual Value _getColLowerBound(int i) const; + + virtual void _setColUpperBound(int i, Value value); + virtual Value _getColUpperBound(int i) const; + + virtual void _setRowLowerBound(int i, Value value); + virtual Value _getRowLowerBound(int i) const; + + virtual void _setRowUpperBound(int i, Value value); + virtual Value _getRowUpperBound(int i) const; + + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e); + virtual void _getObjCoeffs(InsertIterator b) const; + + virtual void _setObjCoeff(int i, Value obj_coef); + virtual Value _getObjCoeff(int i) const; + + virtual void _setSense(Sense); + virtual Sense _getSense() const; + + virtual void _clear(); + + virtual void _messageLevel(MessageLevel level); + + private: + + static void freeEnv(); + + struct FreeEnvHelper { + ~FreeEnvHelper() { + freeEnv(); + } + }; + + static FreeEnvHelper freeEnvHelper; + + protected: + + int _message_level; + + public: + + ///Pointer to the underlying GLPK data structure. + _solver_bits::VoidPtr lpx() {return lp;} + ///Const pointer to the underlying GLPK data structure. + _solver_bits::VoidPtr lpx() const {return lp;} + + ///Returns the constraint identifier understood by GLPK. + int lpxRow(Row r) const { return rows(id(r)); } + + ///Returns the variable identifier understood by GLPK. + int lpxCol(Col c) const { return cols(id(c)); } + + }; + + /// \brief Interface for the GLPK LP solver + /// + /// This class implements an interface for the GLPK LP solver. + ///\ingroup lp_group + class GlpkLp : public LpSolver, public GlpkBase { + public: + + ///\e + GlpkLp(); + ///\e + GlpkLp(const GlpkLp&); + + ///\e + virtual GlpkLp* cloneSolver() const; + ///\e + virtual GlpkLp* newSolver() const; + + private: + + mutable std::vector _primal_ray; + mutable std::vector _dual_ray; + + void _clear_temporals(); + + protected: + + virtual const char* _solverName() const; + + virtual SolveExitStatus _solve(); + virtual Value _getPrimal(int i) const; + virtual Value _getDual(int i) const; + + virtual Value _getPrimalValue() const; + + virtual VarStatus _getColStatus(int i) const; + virtual VarStatus _getRowStatus(int i) const; + + virtual Value _getPrimalRay(int i) const; + virtual Value _getDualRay(int i) const; + + virtual ProblemType _getPrimalType() const; + virtual ProblemType _getDualType() const; + + public: + + ///Solve with primal simplex + SolveExitStatus solvePrimal(); + + ///Solve with dual simplex + SolveExitStatus solveDual(); + + private: + + bool _presolve; + + public: + + ///Turns on or off the presolver + + ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver + /// + ///The presolver is off by default. + void presolver(bool presolve); + + }; + + /// \brief Interface for the GLPK MIP solver + /// + /// This class implements an interface for the GLPK MIP solver. + ///\ingroup lp_group + class GlpkMip : public MipSolver, public GlpkBase { + public: + + ///\e + GlpkMip(); + ///\e + GlpkMip(const GlpkMip&); + + virtual GlpkMip* cloneSolver() const; + virtual GlpkMip* newSolver() const; + + protected: + + virtual const char* _solverName() const; + + virtual ColTypes _getColType(int col) const; + virtual void _setColType(int col, ColTypes col_type); + + virtual SolveExitStatus _solve(); + virtual ProblemType _getType() const; + virtual Value _getSol(int i) const; + virtual Value _getSolValue() const; + + }; + + +} //END OF NAMESPACE LEMON + +#endif //LEMON_GLPK_H + diff --git a/lemon/lemon/gomory_hu.h b/lemon/lemon/gomory_hu.h new file mode 100644 index 0000000..41903f5 --- /dev/null +++ b/lemon/lemon/gomory_hu.h @@ -0,0 +1,568 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_GOMORY_HU_TREE_H +#define LEMON_GOMORY_HU_TREE_H + +#include + +#include +#include +#include +#include + +/// \ingroup min_cut +/// \file +/// \brief Gomory-Hu cut tree in graphs. + +namespace lemon { + + /// \ingroup min_cut + /// + /// \brief Gomory-Hu cut tree algorithm + /// + /// The Gomory-Hu tree is a tree on the node set of a given graph, but it + /// may contain edges which are not in the original graph. It has the + /// property that the minimum capacity edge of the path between two nodes + /// in this tree has the same weight as the minimum cut in the graph + /// between these nodes. Moreover the components obtained by removing + /// this edge from the tree determine the corresponding minimum cut. + /// Therefore once this tree is computed, the minimum cut between any pair + /// of nodes can easily be obtained. + /// + /// The algorithm calculates \e n-1 distinct minimum cuts (currently with + /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall + /// time complexity. It calculates a rooted Gomory-Hu tree. + /// The structure of the tree and the edge weights can be + /// obtained using \c predNode(), \c predValue() and \c rootDist(). + /// The functions \c minCutMap() and \c minCutValue() calculate + /// the minimum cut and the minimum cut value between any two nodes + /// in the graph. You can also list (iterate on) the nodes and the + /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt. + /// + /// \tparam GR The type of the undirected graph the algorithm runs on. + /// \tparam CAP The type of the edge map containing the capacities. + /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap". +#ifdef DOXYGEN + template +#else + template > +#endif + class GomoryHu { + public: + + /// The graph type of the algorithm + typedef GR Graph; + /// The capacity map type of the algorithm + typedef CAP Capacity; + /// The value type of capacities + typedef typename Capacity::Value Value; + + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + const Graph& _graph; + const Capacity& _capacity; + + Node _root; + typename Graph::template NodeMap* _pred; + typename Graph::template NodeMap* _weight; + typename Graph::template NodeMap* _order; + + void createStructures() { + if (!_pred) { + _pred = new typename Graph::template NodeMap(_graph); + } + if (!_weight) { + _weight = new typename Graph::template NodeMap(_graph); + } + if (!_order) { + _order = new typename Graph::template NodeMap(_graph); + } + } + + void destroyStructures() { + if (_pred) { + delete _pred; + } + if (_weight) { + delete _weight; + } + if (_order) { + delete _order; + } + } + + public: + + /// \brief Constructor + /// + /// Constructor. + /// \param graph The undirected graph the algorithm runs on. + /// \param capacity The edge capacity map. + GomoryHu(const Graph& graph, const Capacity& capacity) + : _graph(graph), _capacity(capacity), + _pred(0), _weight(0), _order(0) + { + checkConcept, Capacity>(); + } + + + /// \brief Destructor + /// + /// Destructor. + ~GomoryHu() { + destroyStructures(); + } + + private: + + // Initialize the internal data structures + void init() { + createStructures(); + + _root = NodeIt(_graph); + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_pred)[n] = _root; + (*_order)[n] = -1; + } + (*_pred)[_root] = INVALID; + (*_weight)[_root] = std::numeric_limits::max(); + } + + + // Start the algorithm + void start() { + Preflow fa(_graph, _capacity, _root, INVALID); + + for (NodeIt n(_graph); n != INVALID; ++n) { + if (n == _root) continue; + + Node pn = (*_pred)[n]; + fa.source(n); + fa.target(pn); + + fa.runMinCut(); + + (*_weight)[n] = fa.flowValue(); + + for (NodeIt nn(_graph); nn != INVALID; ++nn) { + if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) { + (*_pred)[nn] = n; + } + } + if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) { + (*_pred)[n] = (*_pred)[pn]; + (*_pred)[pn] = n; + (*_weight)[n] = (*_weight)[pn]; + (*_weight)[pn] = fa.flowValue(); + } + } + + (*_order)[_root] = 0; + int index = 1; + + for (NodeIt n(_graph); n != INVALID; ++n) { + std::vector st; + Node nn = n; + while ((*_order)[nn] == -1) { + st.push_back(nn); + nn = (*_pred)[nn]; + } + while (!st.empty()) { + (*_order)[st.back()] = index++; + st.pop_back(); + } + } + } + + public: + + ///\name Execution Control + + ///@{ + + /// \brief Run the Gomory-Hu algorithm. + /// + /// This function runs the Gomory-Hu algorithm. + void run() { + init(); + start(); + } + + /// @} + + ///\name Query Functions + ///The results of the algorithm can be obtained using these + ///functions.\n + ///\ref run() should be called before using them.\n + ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt. + + ///@{ + + /// \brief Return the predecessor node in the Gomory-Hu tree. + /// + /// This function returns the predecessor node of the given node + /// in the Gomory-Hu tree. + /// If \c node is the root of the tree, then it returns \c INVALID. + /// + /// \pre \ref run() must be called before using this function. + Node predNode(const Node& node) const { + return (*_pred)[node]; + } + + /// \brief Return the weight of the predecessor edge in the + /// Gomory-Hu tree. + /// + /// This function returns the weight of the predecessor edge of the + /// given node in the Gomory-Hu tree. + /// If \c node is the root of the tree, the result is undefined. + /// + /// \pre \ref run() must be called before using this function. + Value predValue(const Node& node) const { + return (*_weight)[node]; + } + + /// \brief Return the distance from the root node in the Gomory-Hu tree. + /// + /// This function returns the distance of the given node from the root + /// node in the Gomory-Hu tree. + /// + /// \pre \ref run() must be called before using this function. + int rootDist(const Node& node) const { + return (*_order)[node]; + } + + /// \brief Return the minimum cut value between two nodes + /// + /// This function returns the minimum cut value between the nodes + /// \c s and \c t. + /// It finds the nearest common ancestor of the given nodes in the + /// Gomory-Hu tree and calculates the minimum weight edge on the + /// paths to the ancestor. + /// + /// \pre \ref run() must be called before using this function. + Value minCutValue(const Node& s, const Node& t) const { + Node sn = s, tn = t; + Value value = std::numeric_limits::max(); + + while (sn != tn) { + if ((*_order)[sn] < (*_order)[tn]) { + if ((*_weight)[tn] <= value) value = (*_weight)[tn]; + tn = (*_pred)[tn]; + } else { + if ((*_weight)[sn] <= value) value = (*_weight)[sn]; + sn = (*_pred)[sn]; + } + } + return value; + } + + /// \brief Return the minimum cut between two nodes + /// + /// This function returns the minimum cut between the nodes \c s and \c t + /// in the \c cutMap parameter by setting the nodes in the component of + /// \c s to \c true and the other nodes to \c false. + /// + /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt. + /// + /// \param s The base node. + /// \param t The node you want to separate from node \c s. + /// \param cutMap The cut will be returned in this map. + /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap + /// "ReadWriteMap" on the graph nodes. + /// + /// \return The value of the minimum cut between \c s and \c t. + /// + /// \pre \ref run() must be called before using this function. + template + Value minCutMap(const Node& s, + const Node& t, + CutMap& cutMap + ) const { + Node sn = s, tn = t; + bool s_root=false; + Node rn = INVALID; + Value value = std::numeric_limits::max(); + + while (sn != tn) { + if ((*_order)[sn] < (*_order)[tn]) { + if ((*_weight)[tn] <= value) { + rn = tn; + s_root = false; + value = (*_weight)[tn]; + } + tn = (*_pred)[tn]; + } else { + if ((*_weight)[sn] <= value) { + rn = sn; + s_root = true; + value = (*_weight)[sn]; + } + sn = (*_pred)[sn]; + } + } + + typename Graph::template NodeMap reached(_graph, false); + reached[_root] = true; + cutMap.set(_root, !s_root); + reached[rn] = true; + cutMap.set(rn, s_root); + + std::vector st; + for (NodeIt n(_graph); n != INVALID; ++n) { + st.clear(); + Node nn = n; + while (!reached[nn]) { + st.push_back(nn); + nn = (*_pred)[nn]; + } + while (!st.empty()) { + cutMap.set(st.back(), cutMap[nn]); + st.pop_back(); + } + } + + return value; + } + + ///@} + + friend class MinCutNodeIt; + + /// Iterate on the nodes of a minimum cut + + /// This iterator class lists the nodes of a minimum cut found by + /// GomoryHu. Before using it, you must allocate a GomoryHu class + /// and call its \ref GomoryHu::run() "run()" method. + /// + /// This example counts the nodes in the minimum cut separating \c s from + /// \c t. + /// \code + /// GomoryHu gom(g, capacities); + /// gom.run(); + /// int cnt=0; + /// for(GomoryHu::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt; + /// \endcode + class MinCutNodeIt + { + bool _side; + typename Graph::NodeIt _node_it; + typename Graph::template NodeMap _cut; + public: + /// Constructor + + /// Constructor. + /// + MinCutNodeIt(GomoryHu const &gomory, + ///< The GomoryHu class. You must call its + /// run() method + /// before initializing this iterator. + const Node& s, ///< The base node. + const Node& t, + ///< The node you want to separate from node \c s. + bool side=true + ///< If it is \c true (default) then the iterator lists + /// the nodes of the component containing \c s, + /// otherwise it lists the other component. + /// \note As the minimum cut is not always unique, + /// \code + /// MinCutNodeIt(gomory, s, t, true); + /// \endcode + /// and + /// \code + /// MinCutNodeIt(gomory, t, s, false); + /// \endcode + /// does not necessarily give the same set of nodes. + /// However, it is ensured that + /// \code + /// MinCutNodeIt(gomory, s, t, true); + /// \endcode + /// and + /// \code + /// MinCutNodeIt(gomory, s, t, false); + /// \endcode + /// together list each node exactly once. + ) + : _side(side), _cut(gomory._graph) + { + gomory.minCutMap(s,t,_cut); + for(_node_it=typename Graph::NodeIt(gomory._graph); + _node_it!=INVALID && _cut[_node_it]!=_side; + ++_node_it) {} + } + /// Conversion to \c Node + + /// Conversion to \c Node. + /// + operator typename Graph::Node() const + { + return _node_it; + } + bool operator==(Invalid) { return _node_it==INVALID; } + bool operator!=(Invalid) { return _node_it!=INVALID; } + /// Next node + + /// Next node. + /// + MinCutNodeIt &operator++() + { + for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {} + return *this; + } + /// Postfix incrementation + + /// Postfix incrementation. + /// + /// \warning This incrementation + /// returns a \c Node, not a \c MinCutNodeIt, as one may + /// expect. + typename Graph::Node operator++(int) + { + typename Graph::Node n=*this; + ++(*this); + return n; + } + }; + + friend class MinCutEdgeIt; + + /// Iterate on the edges of a minimum cut + + /// This iterator class lists the edges of a minimum cut found by + /// GomoryHu. Before using it, you must allocate a GomoryHu class + /// and call its \ref GomoryHu::run() "run()" method. + /// + /// This example computes the value of the minimum cut separating \c s from + /// \c t. + /// \code + /// GomoryHu gom(g, capacities); + /// gom.run(); + /// int value=0; + /// for(GomoryHu::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e) + /// value+=capacities[e]; + /// \endcode + /// The result will be the same as the value returned by + /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)". + class MinCutEdgeIt + { + bool _side; + const Graph &_graph; + typename Graph::NodeIt _node_it; + typename Graph::OutArcIt _arc_it; + typename Graph::template NodeMap _cut; + void step() + { + ++_arc_it; + while(_node_it!=INVALID && _arc_it==INVALID) + { + for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {} + if(_node_it!=INVALID) + _arc_it=typename Graph::OutArcIt(_graph,_node_it); + } + } + + public: + /// Constructor + + /// Constructor. + /// + MinCutEdgeIt(GomoryHu const &gomory, + ///< The GomoryHu class. You must call its + /// run() method + /// before initializing this iterator. + const Node& s, ///< The base node. + const Node& t, + ///< The node you want to separate from node \c s. + bool side=true + ///< If it is \c true (default) then the listed arcs + /// will be oriented from the + /// nodes of the component containing \c s, + /// otherwise they will be oriented in the opposite + /// direction. + ) + : _graph(gomory._graph), _cut(_graph) + { + gomory.minCutMap(s,t,_cut); + if(!side) + for(typename Graph::NodeIt n(_graph);n!=INVALID;++n) + _cut[n]=!_cut[n]; + + for(_node_it=typename Graph::NodeIt(_graph); + _node_it!=INVALID && !_cut[_node_it]; + ++_node_it) {} + _arc_it = _node_it!=INVALID ? + typename Graph::OutArcIt(_graph,_node_it) : INVALID; + while(_node_it!=INVALID && _arc_it == INVALID) + { + for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {} + if(_node_it!=INVALID) + _arc_it= typename Graph::OutArcIt(_graph,_node_it); + } + while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step(); + } + /// Conversion to \c Arc + + /// Conversion to \c Arc. + /// + operator typename Graph::Arc() const + { + return _arc_it; + } + /// Conversion to \c Edge + + /// Conversion to \c Edge. + /// + operator typename Graph::Edge() const + { + return _arc_it; + } + bool operator==(Invalid) { return _node_it==INVALID; } + bool operator!=(Invalid) { return _node_it!=INVALID; } + /// Next edge + + /// Next edge. + /// + MinCutEdgeIt &operator++() + { + step(); + while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step(); + return *this; + } + /// Postfix incrementation + + /// Postfix incrementation. + /// + /// \warning This incrementation + /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect. + typename Graph::Arc operator++(int) + { + typename Graph::Arc e=*this; + ++(*this); + return e; + } + }; + + }; + +} + +#endif diff --git a/lemon/lemon/graph_to_eps.h b/lemon/lemon/graph_to_eps.h new file mode 100644 index 0000000..e8c4ad2 --- /dev/null +++ b/lemon/lemon/graph_to_eps.h @@ -0,0 +1,1187 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_GRAPH_TO_EPS_H +#define LEMON_GRAPH_TO_EPS_H + +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + + +///\ingroup eps_io +///\file +///\brief A well configurable tool for visualizing graphs + +namespace lemon { + + namespace _graph_to_eps_bits { + template + class _NegY { + public: + typedef typename MT::Key Key; + typedef typename MT::Value Value; + const MT ↦ + int yscale; + _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {} + Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);} + }; + } + +///Default traits class of GraphToEps + +///Default traits class of \ref GraphToEps. +/// +///\param GR is the type of the underlying graph. +template +struct DefaultGraphToEpsTraits +{ + typedef GR Graph; + typedef GR Digraph; + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Arc Arc; + typedef typename Graph::ArcIt ArcIt; + typedef typename Graph::InArcIt InArcIt; + typedef typename Graph::OutArcIt OutArcIt; + + + const Graph &g; + + std::ostream& os; + + typedef ConstMap > CoordsMapType; + CoordsMapType _coords; + ConstMap _nodeSizes; + ConstMap _nodeShapes; + + ConstMap _nodeColors; + ConstMap _arcColors; + + ConstMap _arcWidths; + + double _arcWidthScale; + + double _nodeScale; + double _xBorder, _yBorder; + double _scale; + double _nodeBorderQuotient; + + bool _drawArrows; + double _arrowLength, _arrowWidth; + + bool _showNodes, _showArcs; + + bool _enableParallel; + double _parArcDist; + + bool _showNodeText; + ConstMap _nodeTexts; + double _nodeTextSize; + + bool _showNodePsText; + ConstMap _nodePsTexts; + char *_nodePsTextsPreamble; + + bool _undirected; + + bool _pleaseRemoveOsStream; + + bool _scaleToA4; + + std::string _title; + std::string _copyright; + + enum NodeTextColorType + { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType; + ConstMap _nodeTextColors; + + bool _autoNodeScale; + bool _autoArcWidthScale; + + bool _absoluteNodeSizes; + bool _absoluteArcWidths; + + bool _negY; + + bool _preScale; + ///Constructor + + ///Constructor + ///\param gr Reference to the graph to be printed. + ///\param ost Reference to the output stream. + ///By default, it is std::cout. + ///\param pros If it is \c true, then the \c ostream referenced by \c os + ///will be explicitly deallocated by the destructor. + DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout, + bool pros = false) : + g(gr), os(ost), + _coords(dim2::Point(1,1)), _nodeSizes(1), _nodeShapes(0), + _nodeColors(WHITE), _arcColors(BLACK), + _arcWidths(1.0), _arcWidthScale(0.003), + _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0), + _nodeBorderQuotient(.1), + _drawArrows(false), _arrowLength(1), _arrowWidth(0.3), + _showNodes(true), _showArcs(true), + _enableParallel(false), _parArcDist(1), + _showNodeText(false), _nodeTexts(false), _nodeTextSize(1), + _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0), + _undirected(lemon::UndirectedTagIndicator::value), + _pleaseRemoveOsStream(pros), _scaleToA4(false), + _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK), + _autoNodeScale(false), + _autoArcWidthScale(false), + _absoluteNodeSizes(false), + _absoluteArcWidths(false), + _negY(false), + _preScale(true) + {} +}; + +///Auxiliary class to implement the named parameters of \ref graphToEps() + +///Auxiliary class to implement the named parameters of \ref graphToEps(). +/// +///For detailed examples see the \ref graph_to_eps_demo.cc demo file. +template class GraphToEps : public T +{ + // Can't believe it is required by the C++ standard + using T::g; + using T::os; + + using T::_coords; + using T::_nodeSizes; + using T::_nodeShapes; + using T::_nodeColors; + using T::_arcColors; + using T::_arcWidths; + + using T::_arcWidthScale; + using T::_nodeScale; + using T::_xBorder; + using T::_yBorder; + using T::_scale; + using T::_nodeBorderQuotient; + + using T::_drawArrows; + using T::_arrowLength; + using T::_arrowWidth; + + using T::_showNodes; + using T::_showArcs; + + using T::_enableParallel; + using T::_parArcDist; + + using T::_showNodeText; + using T::_nodeTexts; + using T::_nodeTextSize; + + using T::_showNodePsText; + using T::_nodePsTexts; + using T::_nodePsTextsPreamble; + + using T::_undirected; + + using T::_pleaseRemoveOsStream; + + using T::_scaleToA4; + + using T::_title; + using T::_copyright; + + using T::NodeTextColorType; + using T::CUST_COL; + using T::DIST_COL; + using T::DIST_BW; + using T::_nodeTextColorType; + using T::_nodeTextColors; + + using T::_autoNodeScale; + using T::_autoArcWidthScale; + + using T::_absoluteNodeSizes; + using T::_absoluteArcWidths; + + + using T::_negY; + using T::_preScale; + + // dradnats ++C eht yb deriuqer si ti eveileb t'naC + + typedef typename T::Graph Graph; + typedef typename T::Digraph Digraph; + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + typedef typename Graph::Arc Arc; + typedef typename Graph::ArcIt ArcIt; + typedef typename Graph::InArcIt InArcIt; + typedef typename Graph::OutArcIt OutArcIt; + + static const int INTERPOL_PREC; + static const double A4HEIGHT; + static const double A4WIDTH; + static const double A4BORDER; + + bool dontPrint; + +public: + ///Node shapes + + ///Node shapes. + /// + enum NodeShapes { + /// = 0 + ///\image html nodeshape_0.png + ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm + CIRCLE=0, + /// = 1 + ///\image html nodeshape_1.png + ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm + SQUARE=1, + /// = 2 + ///\image html nodeshape_2.png + ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm + DIAMOND=2, + /// = 3 + ///\image html nodeshape_3.png + ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm + MALE=3, + /// = 4 + ///\image html nodeshape_4.png + ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm + FEMALE=4 + }; + +private: + class arcLess { + const Graph &g; + public: + arcLess(const Graph &_g) : g(_g) {} + bool operator()(Arc a,Arc b) const + { + Node ai=std::min(g.source(a),g.target(a)); + Node aa=std::max(g.source(a),g.target(a)); + Node bi=std::min(g.source(b),g.target(b)); + Node ba=std::max(g.source(b),g.target(b)); + return ai + static std::string psOut(const dim2::Point &p) + { + std::ostringstream os; + os << p.x << ' ' << p.y; + return os.str(); + } + static std::string psOut(const Color &c) + { + std::ostringstream os; + os << c.red() << ' ' << c.green() << ' ' << c.blue(); + return os.str(); + } + +public: + GraphToEps(const T &t) : T(t), dontPrint(false) {}; + + template struct CoordsTraits : public T { + typedef X CoordsMapType; + const X &_coords; + CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {} + }; + ///Sets the map of the node coordinates + + ///Sets the map of the node coordinates. + ///\param x must be a node map with \ref dim2::Point "dim2::Point" or + ///\ref dim2::Point "dim2::Point" values. + template GraphToEps > coords(const X &x) { + dontPrint=true; + return GraphToEps >(CoordsTraits(*this,x)); + } + template struct NodeSizesTraits : public T { + const X &_nodeSizes; + NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {} + }; + ///Sets the map of the node sizes + + ///Sets the map of the node sizes. + ///\param x must be a node map with \c double (or convertible) values. + template GraphToEps > nodeSizes(const X &x) + { + dontPrint=true; + return GraphToEps >(NodeSizesTraits(*this,x)); + } + template struct NodeShapesTraits : public T { + const X &_nodeShapes; + NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {} + }; + ///Sets the map of the node shapes + + ///Sets the map of the node shapes. + ///The available shape values + ///can be found in \ref NodeShapes "enum NodeShapes". + ///\param x must be a node map with \c int (or convertible) values. + ///\sa NodeShapes + template GraphToEps > nodeShapes(const X &x) + { + dontPrint=true; + return GraphToEps >(NodeShapesTraits(*this,x)); + } + template struct NodeTextsTraits : public T { + const X &_nodeTexts; + NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {} + }; + ///Sets the text printed on the nodes + + ///Sets the text printed on the nodes. + ///\param x must be a node map with type that can be pushed to a standard + ///\c ostream. + template GraphToEps > nodeTexts(const X &x) + { + dontPrint=true; + _showNodeText=true; + return GraphToEps >(NodeTextsTraits(*this,x)); + } + template struct NodePsTextsTraits : public T { + const X &_nodePsTexts; + NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {} + }; + ///Inserts a PostScript block to the nodes + + ///With this command it is possible to insert a verbatim PostScript + ///block to the nodes. + ///The PS current point will be moved to the center of the node before + ///the PostScript block inserted. + /// + ///Before and after the block a newline character is inserted so you + ///don't have to bother with the separators. + /// + ///\param x must be a node map with type that can be pushed to a standard + ///\c ostream. + /// + ///\sa nodePsTextsPreamble() + template GraphToEps > nodePsTexts(const X &x) + { + dontPrint=true; + _showNodePsText=true; + return GraphToEps >(NodePsTextsTraits(*this,x)); + } + template struct ArcWidthsTraits : public T { + const X &_arcWidths; + ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {} + }; + ///Sets the map of the arc widths + + ///Sets the map of the arc widths. + ///\param x must be an arc map with \c double (or convertible) values. + template GraphToEps > arcWidths(const X &x) + { + dontPrint=true; + return GraphToEps >(ArcWidthsTraits(*this,x)); + } + + template struct NodeColorsTraits : public T { + const X &_nodeColors; + NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {} + }; + ///Sets the map of the node colors + + ///Sets the map of the node colors. + ///\param x must be a node map with \ref Color values. + /// + ///\sa Palette + template GraphToEps > + nodeColors(const X &x) + { + dontPrint=true; + return GraphToEps >(NodeColorsTraits(*this,x)); + } + template struct NodeTextColorsTraits : public T { + const X &_nodeTextColors; + NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {} + }; + ///Sets the map of the node text colors + + ///Sets the map of the node text colors. + ///\param x must be a node map with \ref Color values. + /// + ///\sa Palette + template GraphToEps > + nodeTextColors(const X &x) + { + dontPrint=true; + _nodeTextColorType=CUST_COL; + return GraphToEps > + (NodeTextColorsTraits(*this,x)); + } + template struct ArcColorsTraits : public T { + const X &_arcColors; + ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {} + }; + ///Sets the map of the arc colors + + ///Sets the map of the arc colors. + ///\param x must be an arc map with \ref Color values. + /// + ///\sa Palette + template GraphToEps > + arcColors(const X &x) + { + dontPrint=true; + return GraphToEps >(ArcColorsTraits(*this,x)); + } + ///Sets a global scale factor for node sizes + + ///Sets a global scale factor for node sizes. + /// + /// If nodeSizes() is not given, this function simply sets the node + /// sizes to \c d. If nodeSizes() is given, but + /// autoNodeScale() is not, then the node size given by + /// nodeSizes() will be multiplied by the value \c d. + /// If both nodeSizes() and autoNodeScale() are used, then the + /// node sizes will be scaled in such a way that the greatest size will be + /// equal to \c d. + /// \sa nodeSizes() + /// \sa autoNodeScale() + GraphToEps &nodeScale(double d=.01) {_nodeScale=d;return *this;} + ///Turns on/off the automatic node size scaling. + + ///Turns on/off the automatic node size scaling. + /// + ///\sa nodeScale() + /// + GraphToEps &autoNodeScale(bool b=true) { + _autoNodeScale=b;return *this; + } + + ///Turns on/off the absolutematic node size scaling. + + ///Turns on/off the absolutematic node size scaling. + /// + ///\sa nodeScale() + /// + GraphToEps &absoluteNodeSizes(bool b=true) { + _absoluteNodeSizes=b;return *this; + } + + ///Negates the Y coordinates. + GraphToEps &negateY(bool b=true) { + _negY=b;return *this; + } + + ///Turn on/off pre-scaling + + ///By default, graphToEps() rescales the whole image in order to avoid + ///very big or very small bounding boxes. + /// + ///This (p)rescaling can be turned off with this function. + /// + GraphToEps &preScale(bool b=true) { + _preScale=b;return *this; + } + + ///Sets a global scale factor for arc widths + + /// Sets a global scale factor for arc widths. + /// + /// If arcWidths() is not given, this function simply sets the arc + /// widths to \c d. If arcWidths() is given, but + /// autoArcWidthScale() is not, then the arc withs given by + /// arcWidths() will be multiplied by the value \c d. + /// If both arcWidths() and autoArcWidthScale() are used, then the + /// arc withs will be scaled in such a way that the greatest width will be + /// equal to \c d. + GraphToEps &arcWidthScale(double d=.003) {_arcWidthScale=d;return *this;} + ///Turns on/off the automatic arc width scaling. + + ///Turns on/off the automatic arc width scaling. + /// + ///\sa arcWidthScale() + /// + GraphToEps &autoArcWidthScale(bool b=true) { + _autoArcWidthScale=b;return *this; + } + ///Turns on/off the absolutematic arc width scaling. + + ///Turns on/off the absolutematic arc width scaling. + /// + ///\sa arcWidthScale() + /// + GraphToEps &absoluteArcWidths(bool b=true) { + _absoluteArcWidths=b;return *this; + } + ///Sets a global scale factor for the whole picture + GraphToEps &scale(double d) {_scale=d;return *this;} + ///Sets the width of the border around the picture + GraphToEps &border(double b=10) {_xBorder=_yBorder=b;return *this;} + ///Sets the width of the border around the picture + GraphToEps &border(double x, double y) { + _xBorder=x;_yBorder=y;return *this; + } + ///Sets whether to draw arrows + GraphToEps &drawArrows(bool b=true) {_drawArrows=b;return *this;} + ///Sets the length of the arrowheads + GraphToEps &arrowLength(double d=1.0) {_arrowLength*=d;return *this;} + ///Sets the width of the arrowheads + GraphToEps &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;} + + ///Scales the drawing to fit to A4 page + GraphToEps &scaleToA4() {_scaleToA4=true;return *this;} + + ///Enables parallel arcs + GraphToEps &enableParallel(bool b=true) {_enableParallel=b;return *this;} + + ///Sets the distance between parallel arcs + GraphToEps &parArcDist(double d) {_parArcDist*=d;return *this;} + + ///Hides the arcs + GraphToEps &hideArcs(bool b=true) {_showArcs=!b;return *this;} + ///Hides the nodes + GraphToEps &hideNodes(bool b=true) {_showNodes=!b;return *this;} + + ///Sets the size of the node texts + GraphToEps &nodeTextSize(double d) {_nodeTextSize=d;return *this;} + + ///Sets the color of the node texts to be different from the node color + + ///Sets the color of the node texts to be as different from the node color + ///as it is possible. + GraphToEps &distantColorNodeTexts() + {_nodeTextColorType=DIST_COL;return *this;} + ///Sets the color of the node texts to be black or white and always visible. + + ///Sets the color of the node texts to be black or white according to + ///which is more different from the node color. + GraphToEps &distantBWNodeTexts() + {_nodeTextColorType=DIST_BW;return *this;} + + ///Gives a preamble block for node Postscript block. + + ///Gives a preamble block for node Postscript block. + /// + ///\sa nodePsTexts() + GraphToEps & nodePsTextsPreamble(const char *str) { + _nodePsTextsPreamble=str ;return *this; + } + ///Sets whether the graph is undirected + + ///Sets whether the graph is undirected. + /// + ///This setting is the default for undirected graphs. + /// + ///\sa directed() + GraphToEps &undirected(bool b=true) {_undirected=b;return *this;} + + ///Sets whether the graph is directed + + ///Sets whether the graph is directed. + ///Use it to show the edges as a pair of directed ones. + /// + ///This setting is the default for digraphs. + /// + ///\sa undirected() + GraphToEps &directed(bool b=true) {_undirected=!b;return *this;} + + ///Sets the title. + + ///Sets the title of the generated image, + ///namely it inserts a %%Title: DSC field to the header of + ///the EPS file. + GraphToEps &title(const std::string &t) {_title=t;return *this;} + ///Sets the copyright statement. + + ///Sets the copyright statement of the generated image, + ///namely it inserts a %%Copyright: DSC field to the header of + ///the EPS file. + GraphToEps ©right(const std::string &t) {_copyright=t;return *this;} + +protected: + bool isInsideNode(dim2::Point p, double r,int t) + { + switch(t) { + case CIRCLE: + case MALE: + case FEMALE: + return p.normSquare()<=r*r; + case SQUARE: + return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r; + case DIAMOND: + return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r; + } + return false; + } + +public: + ~GraphToEps() { } + + ///Draws the graph. + + ///Like other functions using + ///\ref named-templ-func-param "named template parameters", + ///this function calls the algorithm itself, i.e. in this case + ///it draws the graph. + void run() { + const double EPSILON=1e-9; + if(dontPrint) return; + + _graph_to_eps_bits::_NegY + mycoords(_coords,_negY); + + os << "%!PS-Adobe-2.0 EPSF-2.0\n"; + if(_title.size()>0) os << "%%Title: " << _title << '\n'; + if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n'; + os << "%%Creator: LEMON, graphToEps()\n"; + + { + os << "%%CreationDate: "; +#ifndef WIN32 + timeval tv; + gettimeofday(&tv, 0); + + char cbuf[26]; + ctime_r(&tv.tv_sec,cbuf); + os << cbuf; +#else + os << bits::getWinFormattedDate(); + os << std::endl; +#endif + } + + if (_autoArcWidthScale) { + double max_w=0; + for(ArcIt e(g);e!=INVALID;++e) + max_w=std::max(double(_arcWidths[e]),max_w); + if(max_w>EPSILON) { + _arcWidthScale/=max_w; + } + } + + if (_autoNodeScale) { + double max_s=0; + for(NodeIt n(g);n!=INVALID;++n) + max_s=std::max(double(_nodeSizes[n]),max_s); + if(max_s>EPSILON) { + _nodeScale/=max_s; + } + } + + double diag_len = 1; + if(!(_absoluteNodeSizes&&_absoluteArcWidths)) { + dim2::Box bb; + for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]); + if (bb.empty()) { + bb = dim2::Box(dim2::Point(0,0)); + } + diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare()); + if(diag_len bb; + for(NodeIt n(g);n!=INVALID;++n) { + double ns=_nodeSizes[n]*_nodeScale; + dim2::Point p(ns,ns); + switch(_nodeShapes[n]) { + case CIRCLE: + case SQUARE: + case DIAMOND: + bb.add(p+mycoords[n]); + bb.add(-p+mycoords[n]); + break; + case MALE: + bb.add(-p+mycoords[n]); + bb.add(dim2::Point(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]); + break; + case FEMALE: + bb.add(p+mycoords[n]); + bb.add(dim2::Point(-ns,-3.01*ns)+mycoords[n]); + break; + } + } + if (bb.empty()) { + bb = dim2::Box(dim2::Point(0,0)); + } + + if(_scaleToA4) + os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n"; + else { + if(_preScale) { + //Rescale so that BoundingBox won't be neither to big nor too small. + while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10; + while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10; + } + + os << "%%BoundingBox: " + << int(floor(bb.left() * _scale - _xBorder)) << ' ' + << int(floor(bb.bottom() * _scale - _yBorder)) << ' ' + << int(ceil(bb.right() * _scale + _xBorder)) << ' ' + << int(ceil(bb.top() * _scale + _yBorder)) << '\n'; + } + + os << "%%EndComments\n"; + + //x1 y1 x2 y2 x3 y3 cr cg cb w + os << "/lb { setlinewidth setrgbcolor newpath moveto\n" + << " 4 2 roll 1 index 1 index curveto stroke } bind def\n"; + os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }" + << " bind def\n"; + //x y r + os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath }" + << " bind def\n"; + //x y r + os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n" + << " 2 index 1 index sub 2 index 2 index add lineto\n" + << " 2 index 1 index sub 2 index 2 index sub lineto\n" + << " 2 index 1 index add 2 index 2 index sub lineto\n" + << " closepath pop pop pop} bind def\n"; + //x y r + os << "/di { newpath 2 index 1 index add 2 index moveto\n" + << " 2 index 2 index 2 index add lineto\n" + << " 2 index 1 index sub 2 index lineto\n" + << " 2 index 2 index 2 index sub lineto\n" + << " closepath pop pop pop} bind def\n"; + // x y r cr cg cb + os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n" + << " setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n" + << " } bind def\n"; + os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n" + << " setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n" + << " } bind def\n"; + os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n" + << " setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n" + << " } bind def\n"; + os << "/nfemale { 0 0 0 setrgbcolor 3 index " + << _nodeBorderQuotient/(1+_nodeBorderQuotient) + << " 1.5 mul mul setlinewidth\n" + << " newpath 5 index 5 index moveto " + << "5 index 5 index 5 index 3.01 mul sub\n" + << " lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub" + << " moveto\n" + << " 5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto " + << "stroke\n" + << " 5 index 5 index 5 index c fill\n" + << " setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n" + << " } bind def\n"; + os << "/nmale {\n" + << " 0 0 0 setrgbcolor 3 index " + << _nodeBorderQuotient/(1+_nodeBorderQuotient) + <<" 1.5 mul mul setlinewidth\n" + << " newpath 5 index 5 index moveto\n" + << " 5 index 4 index 1 mul 1.5 mul add\n" + << " 5 index 5 index 3 sqrt 1.5 mul mul add\n" + << " 1 index 1 index lineto\n" + << " 1 index 1 index 7 index sub moveto\n" + << " 1 index 1 index lineto\n" + << " exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub" + << " lineto\n" + << " stroke\n" + << " 5 index 5 index 5 index c fill\n" + << " setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n" + << " } bind def\n"; + + + os << "/arrl " << _arrowLength << " def\n"; + os << "/arrw " << _arrowWidth << " def\n"; + // l dx_norm dy_norm + os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n"; + //len w dx_norm dy_norm x1 y1 cr cg cb + os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx " + << "exch def\n" + << " /w exch def /len exch def\n" + //<< "0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke" + << " newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n" + << " len w sub arrl sub dx dy lrl\n" + << " arrw dy dx neg lrl\n" + << " dx arrl w add mul dy w 2 div arrw add mul sub\n" + << " dy arrl w add mul dx w 2 div arrw add mul add rlineto\n" + << " dx arrl w add mul neg dy w 2 div arrw add mul sub\n" + << " dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n" + << " arrw dy dx neg lrl\n" + << " len w sub arrl sub neg dx dy lrl\n" + << " closepath fill } bind def\n"; + os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n" + << " neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n"; + + os << "\ngsave\n"; + if(_scaleToA4) + if(bb.height()>bb.width()) { + double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.height(), + (A4WIDTH-2*A4BORDER)/bb.width()); + os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' ' + << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER + << " translate\n" + << sc << " dup scale\n" + << -bb.left() << ' ' << -bb.bottom() << " translate\n"; + } + else { + double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.width(), + (A4WIDTH-2*A4BORDER)/bb.height()); + os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' ' + << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER + << " translate\n" + << sc << " dup scale\n90 rotate\n" + << -bb.left() << ' ' << -bb.top() << " translate\n"; + } + else if(_scale!=1.0) os << _scale << " dup scale\n"; + + if(_showArcs) { + os << "%Arcs:\ngsave\n"; + if(_enableParallel) { + std::vector el; + for(ArcIt e(g);e!=INVALID;++e) + if((!_undirected||g.source(e)0 + &&g.source(e)!=g.target(e)) + el.push_back(e); + std::sort(el.begin(),el.end(),arcLess(g)); + + typename std::vector::iterator j; + for(typename std::vector::iterator i=el.begin();i!=el.end();i=j) { + for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ; + + double sw=0; + for(typename std::vector::iterator e=i;e!=j;++e) + sw+=_arcWidths[*e]*_arcWidthScale+_parArcDist; + sw-=_parArcDist; + sw/=-2.0; + dim2::Point + dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]); + double l=std::sqrt(dvec.normSquare()); + dim2::Point d(dvec/std::max(l,EPSILON)); + dim2::Point m; +// m=dim2::Point(mycoords[g.target(*i)]+ +// mycoords[g.source(*i)])/2.0; + +// m=dim2::Point(mycoords[g.source(*i)])+ +// dvec*(double(_nodeSizes[g.source(*i)])/ +// (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)])); + + m=dim2::Point(mycoords[g.source(*i)])+ + d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0; + + for(typename std::vector::iterator e=i;e!=j;++e) { + sw+=_arcWidths[*e]*_arcWidthScale/2.0; + dim2::Point mm=m+rot90(d)*sw/.75; + if(_drawArrows) { + int node_shape; + dim2::Point s=mycoords[g.source(*e)]; + dim2::Point t=mycoords[g.target(*e)]; + double rn=_nodeSizes[g.target(*e)]*_nodeScale; + node_shape=_nodeShapes[g.target(*e)]; + dim2::Bezier3 bez(s,mm,mm,t); + double t1=0,t2=1; + for(int ii=0;ii apoint=bez((t1+t2)/2); + rn = _arrowLength+_arcWidths[*e]*_arcWidthScale; + rn*=rn; + t2=(t1+t2)/2;t1=0; + for(int ii=0;iirn) t1=(t1+t2)/2; + else t2=(t1+t2)/2; + dim2::Point linend=bez((t1+t2)/2); + bez=bez.before((t1+t2)/2); +// rn=_nodeSizes[g.source(*e)]*_nodeScale; +// node_shape=_nodeShapes[g.source(*e)]; +// t1=0;t2=1; +// for(int i=0;i dd(rot90(linend-apoint)); + dd*=(.5*_arcWidths[*e]*_arcWidthScale+_arrowWidth)/ + std::sqrt(dd.normSquare()); + os << "newpath " << psOut(apoint) << " moveto " + << psOut(linend+dd) << " lineto " + << psOut(linend-dd) << " lineto closepath fill\n"; + } + else { + os << mycoords[g.source(*e)].x << ' ' + << mycoords[g.source(*e)].y << ' ' + << mm.x << ' ' << mm.y << ' ' + << mycoords[g.target(*e)].x << ' ' + << mycoords[g.target(*e)].y << ' ' + << _arcColors[*e].red() << ' ' + << _arcColors[*e].green() << ' ' + << _arcColors[*e].blue() << ' ' + << _arcWidths[*e]*_arcWidthScale << " lb\n"; + } + sw+=_arcWidths[*e]*_arcWidthScale/2.0+_parArcDist; + } + } + } + else for(ArcIt e(g);e!=INVALID;++e) + if((!_undirected||g.source(e)0 + &&g.source(e)!=g.target(e)) { + if(_drawArrows) { + dim2::Point d(mycoords[g.target(e)]-mycoords[g.source(e)]); + double rn=_nodeSizes[g.target(e)]*_nodeScale; + int node_shape=_nodeShapes[g.target(e)]; + double t1=0,t2=1; + for(int i=0;i GraphToEps > edgeWidths(const X &x) + { + return arcWidths(x); + } + + ///An alias for arcColors() + template GraphToEps > + edgeColors(const X &x) + { + return arcColors(x); + } + + ///An alias for arcWidthScale() + GraphToEps &edgeWidthScale(double d) {return arcWidthScale(d);} + + ///An alias for autoArcWidthScale() + GraphToEps &autoEdgeWidthScale(bool b=true) + { + return autoArcWidthScale(b); + } + + ///An alias for absoluteArcWidths() + GraphToEps &absoluteEdgeWidths(bool b=true) + { + return absoluteArcWidths(b); + } + + ///An alias for parArcDist() + GraphToEps &parEdgeDist(double d) {return parArcDist(d);} + + ///An alias for hideArcs() + GraphToEps &hideEdges(bool b=true) {return hideArcs(b);} + + ///@} +}; + +template +const int GraphToEps::INTERPOL_PREC = 20; +template +const double GraphToEps::A4HEIGHT = 841.8897637795276; +template +const double GraphToEps::A4WIDTH = 595.275590551181; +template +const double GraphToEps::A4BORDER = 15; + + +///Generates an EPS file from a graph + +///\ingroup eps_io +///Generates an EPS file from a graph. +///\param g Reference to the graph to be printed. +///\param os Reference to the output stream. +///By default, it is std::cout. +/// +///This function also has a lot of +///\ref named-templ-func-param "named parameters", +///they are declared as the members of class \ref GraphToEps. The following +///example shows how to use these parameters. +///\code +/// graphToEps(g,os).scale(10).coords(coords) +/// .nodeScale(2).nodeSizes(sizes) +/// .arcWidthScale(.4).run(); +///\endcode +/// +///For more detailed examples, see the \ref graph_to_eps_demo.cc demo file. +/// +///\warning Don't forget to put the \ref GraphToEps::run() "run()" +///to the end of the parameter list. +///\sa GraphToEps +///\sa graphToEps(GR &g, const char *file_name) +template +GraphToEps > +graphToEps(GR &g, std::ostream& os=std::cout) +{ + return + GraphToEps >(DefaultGraphToEpsTraits(g,os)); +} + +///Generates an EPS file from a graph + +///\ingroup eps_io +///This function does the same as +///\ref graphToEps(GR &g,std::ostream& os) +///but it writes its output into the file \c file_name +///instead of a stream. +///\sa graphToEps(GR &g, std::ostream& os) +template +GraphToEps > +graphToEps(GR &g,const char *file_name) +{ + std::ostream* os = new std::ofstream(file_name); + if (!(*os)) { + delete os; + throw IoError("Cannot write file", file_name); + } + return GraphToEps > + (DefaultGraphToEpsTraits(g,*os,true)); +} + +///Generates an EPS file from a graph + +///\ingroup eps_io +///This function does the same as +///\ref graphToEps(GR &g,std::ostream& os) +///but it writes its output into the file \c file_name +///instead of a stream. +///\sa graphToEps(GR &g, std::ostream& os) +template +GraphToEps > +graphToEps(GR &g,const std::string& file_name) +{ + std::ostream* os = new std::ofstream(file_name.c_str()); + if (!(*os)) { + delete os; + throw IoError("Cannot write file", file_name); + } + return GraphToEps > + (DefaultGraphToEpsTraits(g,*os,true)); +} + +} //END OF NAMESPACE LEMON + +#endif // LEMON_GRAPH_TO_EPS_H diff --git a/lemon/lemon/grid_graph.h b/lemon/lemon/grid_graph.h new file mode 100644 index 0000000..a3dff0f --- /dev/null +++ b/lemon/lemon/grid_graph.h @@ -0,0 +1,699 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef GRID_GRAPH_H +#define GRID_GRAPH_H + +#include +#include +#include +#include + +///\ingroup graphs +///\file +///\brief GridGraph class. + +namespace lemon { + + class GridGraphBase { + + public: + + typedef GridGraphBase Graph; + + class Node; + class Edge; + class Arc; + + public: + + GridGraphBase() {} + + protected: + + void construct(int width, int height) { + _width = width; _height = height; + _node_num = width * height; + _edge_num = 2 * _node_num - width - height; + _edge_limit = _node_num - _width; + } + + public: + + Node operator()(int i, int j) const { + LEMON_DEBUG(0 <= i && i < _width && + 0 <= j && j < _height, "Index out of range"); + return Node(i + j * _width); + } + + int col(Node n) const { + return n._id % _width; + } + + int row(Node n) const { + return n._id / _width; + } + + dim2::Point pos(Node n) const { + return dim2::Point(col(n), row(n)); + } + + int width() const { + return _width; + } + + int height() const { + return _height; + } + + typedef True NodeNumTag; + typedef True EdgeNumTag; + typedef True ArcNumTag; + + int nodeNum() const { return _node_num; } + int edgeNum() const { return _edge_num; } + int arcNum() const { return 2 * _edge_num; } + + Node u(Edge edge) const { + if (edge._id < _edge_limit) { + return edge._id; + } else { + return (edge._id - _edge_limit) % (_width - 1) + + (edge._id - _edge_limit) / (_width - 1) * _width; + } + } + + Node v(Edge edge) const { + if (edge._id < _edge_limit) { + return edge._id + _width; + } else { + return (edge._id - _edge_limit) % (_width - 1) + + (edge._id - _edge_limit) / (_width - 1) * _width + 1; + } + } + + Node source(Arc arc) const { + return (arc._id & 1) == 1 ? u(arc) : v(arc); + } + + Node target(Arc arc) const { + return (arc._id & 1) == 1 ? v(arc) : u(arc); + } + + static int id(Node node) { return node._id; } + static int id(Edge edge) { return edge._id; } + static int id(Arc arc) { return arc._id; } + + int maxNodeId() const { return _node_num - 1; } + int maxEdgeId() const { return _edge_num - 1; } + int maxArcId() const { return 2 * _edge_num - 1; } + + static Node nodeFromId(int id) { return Node(id);} + static Edge edgeFromId(int id) { return Edge(id);} + static Arc arcFromId(int id) { return Arc(id);} + + typedef True FindEdgeTag; + typedef True FindArcTag; + + Edge findEdge(Node u, Node v, Edge prev = INVALID) const { + if (prev != INVALID) return INVALID; + if (v._id > u._id) { + if (v._id - u._id == _width) + return Edge(u._id); + if (v._id - u._id == 1 && u._id % _width < _width - 1) { + return Edge(u._id / _width * (_width - 1) + + u._id % _width + _edge_limit); + } + } else { + if (u._id - v._id == _width) + return Edge(v._id); + if (u._id - v._id == 1 && v._id % _width < _width - 1) { + return Edge(v._id / _width * (_width - 1) + + v._id % _width + _edge_limit); + } + } + return INVALID; + } + + Arc findArc(Node u, Node v, Arc prev = INVALID) const { + if (prev != INVALID) return INVALID; + if (v._id > u._id) { + if (v._id - u._id == _width) + return Arc((u._id << 1) | 1); + if (v._id - u._id == 1 && u._id % _width < _width - 1) { + return Arc(((u._id / _width * (_width - 1) + + u._id % _width + _edge_limit) << 1) | 1); + } + } else { + if (u._id - v._id == _width) + return Arc(v._id << 1); + if (u._id - v._id == 1 && v._id % _width < _width - 1) { + return Arc((v._id / _width * (_width - 1) + + v._id % _width + _edge_limit) << 1); + } + } + return INVALID; + } + + class Node { + friend class GridGraphBase; + + protected: + int _id; + Node(int id) : _id(id) {} + public: + Node() {} + Node (Invalid) : _id(-1) {} + bool operator==(const Node node) const {return _id == node._id;} + bool operator!=(const Node node) const {return _id != node._id;} + bool operator<(const Node node) const {return _id < node._id;} + }; + + class Edge { + friend class GridGraphBase; + friend class Arc; + + protected: + int _id; + + Edge(int id) : _id(id) {} + + public: + Edge() {} + Edge (Invalid) : _id(-1) {} + bool operator==(const Edge edge) const {return _id == edge._id;} + bool operator!=(const Edge edge) const {return _id != edge._id;} + bool operator<(const Edge edge) const {return _id < edge._id;} + }; + + class Arc { + friend class GridGraphBase; + + protected: + int _id; + + Arc(int id) : _id(id) {} + + public: + Arc() {} + Arc (Invalid) : _id(-1) {} + operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; } + bool operator==(const Arc arc) const {return _id == arc._id;} + bool operator!=(const Arc arc) const {return _id != arc._id;} + bool operator<(const Arc arc) const {return _id < arc._id;} + }; + + static bool direction(Arc arc) { + return (arc._id & 1) == 1; + } + + static Arc direct(Edge edge, bool dir) { + return Arc((edge._id << 1) | (dir ? 1 : 0)); + } + + void first(Node& node) const { + node._id = _node_num - 1; + } + + static void next(Node& node) { + --node._id; + } + + void first(Edge& edge) const { + edge._id = _edge_num - 1; + } + + static void next(Edge& edge) { + --edge._id; + } + + void first(Arc& arc) const { + arc._id = 2 * _edge_num - 1; + } + + static void next(Arc& arc) { + --arc._id; + } + + void firstOut(Arc& arc, const Node& node) const { + if (node._id % _width < _width - 1) { + arc._id = (_edge_limit + node._id % _width + + (node._id / _width) * (_width - 1)) << 1 | 1; + return; + } + if (node._id < _node_num - _width) { + arc._id = node._id << 1 | 1; + return; + } + if (node._id % _width > 0) { + arc._id = (_edge_limit + node._id % _width + + (node._id / _width) * (_width - 1) - 1) << 1; + return; + } + if (node._id >= _width) { + arc._id = (node._id - _width) << 1; + return; + } + arc._id = -1; + } + + void nextOut(Arc& arc) const { + int nid = arc._id >> 1; + if ((arc._id & 1) == 1) { + if (nid >= _edge_limit) { + nid = (nid - _edge_limit) % (_width - 1) + + (nid - _edge_limit) / (_width - 1) * _width; + if (nid < _node_num - _width) { + arc._id = nid << 1 | 1; + return; + } + } + if (nid % _width > 0) { + arc._id = (_edge_limit + nid % _width + + (nid / _width) * (_width - 1) - 1) << 1; + return; + } + if (nid >= _width) { + arc._id = (nid - _width) << 1; + return; + } + } else { + if (nid >= _edge_limit) { + nid = (nid - _edge_limit) % (_width - 1) + + (nid - _edge_limit) / (_width - 1) * _width + 1; + if (nid >= _width) { + arc._id = (nid - _width) << 1; + return; + } + } + } + arc._id = -1; + } + + void firstIn(Arc& arc, const Node& node) const { + if (node._id % _width < _width - 1) { + arc._id = (_edge_limit + node._id % _width + + (node._id / _width) * (_width - 1)) << 1; + return; + } + if (node._id < _node_num - _width) { + arc._id = node._id << 1; + return; + } + if (node._id % _width > 0) { + arc._id = (_edge_limit + node._id % _width + + (node._id / _width) * (_width - 1) - 1) << 1 | 1; + return; + } + if (node._id >= _width) { + arc._id = (node._id - _width) << 1 | 1; + return; + } + arc._id = -1; + } + + void nextIn(Arc& arc) const { + int nid = arc._id >> 1; + if ((arc._id & 1) == 0) { + if (nid >= _edge_limit) { + nid = (nid - _edge_limit) % (_width - 1) + + (nid - _edge_limit) / (_width - 1) * _width; + if (nid < _node_num - _width) { + arc._id = nid << 1; + return; + } + } + if (nid % _width > 0) { + arc._id = (_edge_limit + nid % _width + + (nid / _width) * (_width - 1) - 1) << 1 | 1; + return; + } + if (nid >= _width) { + arc._id = (nid - _width) << 1 | 1; + return; + } + } else { + if (nid >= _edge_limit) { + nid = (nid - _edge_limit) % (_width - 1) + + (nid - _edge_limit) / (_width - 1) * _width + 1; + if (nid >= _width) { + arc._id = (nid - _width) << 1 | 1; + return; + } + } + } + arc._id = -1; + } + + void firstInc(Edge& edge, bool& dir, const Node& node) const { + if (node._id % _width < _width - 1) { + edge._id = _edge_limit + node._id % _width + + (node._id / _width) * (_width - 1); + dir = true; + return; + } + if (node._id < _node_num - _width) { + edge._id = node._id; + dir = true; + return; + } + if (node._id % _width > 0) { + edge._id = _edge_limit + node._id % _width + + (node._id / _width) * (_width - 1) - 1; + dir = false; + return; + } + if (node._id >= _width) { + edge._id = node._id - _width; + dir = false; + return; + } + edge._id = -1; + dir = true; + } + + void nextInc(Edge& edge, bool& dir) const { + int nid = edge._id; + if (dir) { + if (nid >= _edge_limit) { + nid = (nid - _edge_limit) % (_width - 1) + + (nid - _edge_limit) / (_width - 1) * _width; + if (nid < _node_num - _width) { + edge._id = nid; + return; + } + } + if (nid % _width > 0) { + edge._id = _edge_limit + nid % _width + + (nid / _width) * (_width - 1) - 1; + dir = false; + return; + } + if (nid >= _width) { + edge._id = nid - _width; + dir = false; + return; + } + } else { + if (nid >= _edge_limit) { + nid = (nid - _edge_limit) % (_width - 1) + + (nid - _edge_limit) / (_width - 1) * _width + 1; + if (nid >= _width) { + edge._id = nid - _width; + return; + } + } + } + edge._id = -1; + dir = true; + } + + Arc right(Node n) const { + if (n._id % _width < _width - 1) { + return Arc(((_edge_limit + n._id % _width + + (n._id / _width) * (_width - 1)) << 1) | 1); + } else { + return INVALID; + } + } + + Arc left(Node n) const { + if (n._id % _width > 0) { + return Arc((_edge_limit + n._id % _width + + (n._id / _width) * (_width - 1) - 1) << 1); + } else { + return INVALID; + } + } + + Arc up(Node n) const { + if (n._id < _edge_limit) { + return Arc((n._id << 1) | 1); + } else { + return INVALID; + } + } + + Arc down(Node n) const { + if (n._id >= _width) { + return Arc((n._id - _width) << 1); + } else { + return INVALID; + } + } + + private: + int _width, _height; + int _node_num, _edge_num; + int _edge_limit; + }; + + + typedef GraphExtender ExtendedGridGraphBase; + + /// \ingroup graphs + /// + /// \brief Grid graph class + /// + /// GridGraph implements a special graph type. The nodes of the + /// graph can be indexed by two integer values \c (i,j) where \c i is + /// in the range [0..width()-1] and j is in the range + /// [0..height()-1]. Two nodes are connected in the graph if + /// the indices differ exactly on one position and the difference is + /// also exactly one. The nodes of the graph can be obtained by position + /// using the \c operator()() function and the indices of the nodes can + /// be obtained using \c pos(), \c col() and \c row() members. The outgoing + /// arcs can be retrieved with the \c right(), \c up(), \c left() + /// and \c down() functions, where the bottom-left corner is the + /// origin. + /// + /// This class is completely static and it needs constant memory space. + /// Thus you can neither add nor delete nodes or edges, however + /// the structure can be resized using resize(). + /// + /// \image html grid_graph.png + /// \image latex grid_graph.eps "Grid graph" width=\textwidth + /// + /// A short example about the basic usage: + ///\code + /// GridGraph graph(rows, cols); + /// GridGraph::NodeMap val(graph); + /// for (int i = 0; i < graph.width(); ++i) { + /// for (int j = 0; j < graph.height(); ++j) { + /// val[graph(i, j)] = i + j; + /// } + /// } + ///\endcode + /// + /// This type fully conforms to the \ref concepts::Graph "Graph concept". + /// Most of its member functions and nested classes are documented + /// only in the concept class. + /// + /// This class provides constant time counting for nodes, edges and arcs. + class GridGraph : public ExtendedGridGraphBase { + typedef ExtendedGridGraphBase Parent; + + public: + + /// \brief Map to get the indices of the nodes as \ref dim2::Point + /// "dim2::Point". + /// + /// Map to get the indices of the nodes as \ref dim2::Point + /// "dim2::Point". + class IndexMap { + public: + /// \brief The key type of the map + typedef GridGraph::Node Key; + /// \brief The value type of the map + typedef dim2::Point Value; + + /// \brief Constructor + IndexMap(const GridGraph& graph) : _graph(graph) {} + + /// \brief The subscript operator + Value operator[](Key key) const { + return _graph.pos(key); + } + + private: + const GridGraph& _graph; + }; + + /// \brief Map to get the column of the nodes. + /// + /// Map to get the column of the nodes. + class ColMap { + public: + /// \brief The key type of the map + typedef GridGraph::Node Key; + /// \brief The value type of the map + typedef int Value; + + /// \brief Constructor + ColMap(const GridGraph& graph) : _graph(graph) {} + + /// \brief The subscript operator + Value operator[](Key key) const { + return _graph.col(key); + } + + private: + const GridGraph& _graph; + }; + + /// \brief Map to get the row of the nodes. + /// + /// Map to get the row of the nodes. + class RowMap { + public: + /// \brief The key type of the map + typedef GridGraph::Node Key; + /// \brief The value type of the map + typedef int Value; + + /// \brief Constructor + RowMap(const GridGraph& graph) : _graph(graph) {} + + /// \brief The subscript operator + Value operator[](Key key) const { + return _graph.row(key); + } + + private: + const GridGraph& _graph; + }; + + /// \brief Constructor + /// + /// Construct a grid graph with the given size. + GridGraph(int width, int height) { construct(width, height); } + + /// \brief Resizes the graph + /// + /// This function resizes the graph. It fully destroys and + /// rebuilds the structure, therefore the maps of the graph will be + /// reallocated automatically and the previous values will be lost. + void resize(int width, int height) { + Parent::notifier(Arc()).clear(); + Parent::notifier(Edge()).clear(); + Parent::notifier(Node()).clear(); + construct(width, height); + Parent::notifier(Node()).build(); + Parent::notifier(Edge()).build(); + Parent::notifier(Arc()).build(); + } + + /// \brief The node on the given position. + /// + /// Gives back the node on the given position. + Node operator()(int i, int j) const { + return Parent::operator()(i, j); + } + + /// \brief The column index of the node. + /// + /// Gives back the column index of the node. + int col(Node n) const { + return Parent::col(n); + } + + /// \brief The row index of the node. + /// + /// Gives back the row index of the node. + int row(Node n) const { + return Parent::row(n); + } + + /// \brief The position of the node. + /// + /// Gives back the position of the node, ie. the (col,row) pair. + dim2::Point pos(Node n) const { + return Parent::pos(n); + } + + /// \brief The number of the columns. + /// + /// Gives back the number of the columns. + int width() const { + return Parent::width(); + } + + /// \brief The number of the rows. + /// + /// Gives back the number of the rows. + int height() const { + return Parent::height(); + } + + /// \brief The arc goes right from the node. + /// + /// Gives back the arc goes right from the node. If there is not + /// outgoing arc then it gives back INVALID. + Arc right(Node n) const { + return Parent::right(n); + } + + /// \brief The arc goes left from the node. + /// + /// Gives back the arc goes left from the node. If there is not + /// outgoing arc then it gives back INVALID. + Arc left(Node n) const { + return Parent::left(n); + } + + /// \brief The arc goes up from the node. + /// + /// Gives back the arc goes up from the node. If there is not + /// outgoing arc then it gives back INVALID. + Arc up(Node n) const { + return Parent::up(n); + } + + /// \brief The arc goes down from the node. + /// + /// Gives back the arc goes down from the node. If there is not + /// outgoing arc then it gives back INVALID. + Arc down(Node n) const { + return Parent::down(n); + } + + /// \brief Index map of the grid graph + /// + /// Just returns an IndexMap for the grid graph. + IndexMap indexMap() const { + return IndexMap(*this); + } + + /// \brief Row map of the grid graph + /// + /// Just returns a RowMap for the grid graph. + RowMap rowMap() const { + return RowMap(*this); + } + + /// \brief Column map of the grid graph + /// + /// Just returns a ColMap for the grid graph. + ColMap colMap() const { + return ColMap(*this); + } + + }; + +} +#endif diff --git a/lemon/lemon/hao_orlin.h b/lemon/lemon/hao_orlin.h new file mode 100644 index 0000000..696f5ea --- /dev/null +++ b/lemon/lemon/hao_orlin.h @@ -0,0 +1,1005 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_HAO_ORLIN_H +#define LEMON_HAO_ORLIN_H + +#include +#include +#include + +#include +#include +#include + +/// \file +/// \ingroup min_cut +/// \brief Implementation of the Hao-Orlin algorithm. +/// +/// Implementation of the Hao-Orlin algorithm for finding a minimum cut +/// in a digraph. + +namespace lemon { + + /// \ingroup min_cut + /// + /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph. + /// + /// This class implements the Hao-Orlin algorithm for finding a minimum + /// value cut in a directed graph \f$D=(V,A)\f$. + /// It takes a fixed node \f$ source \in V \f$ and + /// consists of two phases: in the first phase it determines a + /// minimum cut with \f$ source \f$ on the source-side (i.e. a set + /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing + /// capacity) and in the second phase it determines a minimum cut + /// with \f$ source \f$ on the sink-side (i.e. a set + /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing + /// capacity). Obviously, the smaller of these two cuts will be a + /// minimum cut of \f$ D \f$. The algorithm is a modified + /// preflow push-relabel algorithm. Our implementation calculates + /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the + /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The + /// purpose of such algorithm is e.g. testing network reliability. + /// + /// For an undirected graph you can run just the first phase of the + /// algorithm or you can use the algorithm of Nagamochi and Ibaraki, + /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$ + /// time. It is implemented in the NagamochiIbaraki algorithm class. + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// \tparam CAP The type of the arc map containing the capacities, + /// which can be any numreric type. The default map type is + /// \ref concepts::Digraph::ArcMap "GR::ArcMap". + /// \tparam TOL Tolerance class for handling inexact computations. The + /// default tolerance type is \ref Tolerance "Tolerance". +#ifdef DOXYGEN + template +#else + template , + typename TOL = Tolerance > +#endif + class HaoOrlin { + public: + + /// The digraph type of the algorithm + typedef GR Digraph; + /// The capacity map type of the algorithm + typedef CAP CapacityMap; + /// The tolerance type of the algorithm + typedef TOL Tolerance; + + private: + + typedef typename CapacityMap::Value Value; + + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + const Digraph& _graph; + const CapacityMap* _capacity; + + typedef typename Digraph::template ArcMap FlowMap; + FlowMap* _flow; + + Node _source; + + int _node_num; + + // Bucketing structure + std::vector _first, _last; + typename Digraph::template NodeMap* _next; + typename Digraph::template NodeMap* _prev; + typename Digraph::template NodeMap* _active; + typename Digraph::template NodeMap* _bucket; + + std::vector _dormant; + + std::list > _sets; + std::list::iterator _highest; + + typedef typename Digraph::template NodeMap ExcessMap; + ExcessMap* _excess; + + typedef typename Digraph::template NodeMap SourceSetMap; + SourceSetMap* _source_set; + + Value _min_cut; + + typedef typename Digraph::template NodeMap MinCutMap; + MinCutMap* _min_cut_map; + + Tolerance _tolerance; + + public: + + /// \brief Constructor + /// + /// Constructor of the algorithm class. + HaoOrlin(const Digraph& graph, const CapacityMap& capacity, + const Tolerance& tolerance = Tolerance()) : + _graph(graph), _capacity(&capacity), _flow(0), _source(), + _node_num(), _first(), _last(), _next(0), _prev(0), + _active(0), _bucket(0), _dormant(), _sets(), _highest(), + _excess(0), _source_set(0), _min_cut(), _min_cut_map(0), + _tolerance(tolerance) {} + + ~HaoOrlin() { + if (_min_cut_map) { + delete _min_cut_map; + } + if (_source_set) { + delete _source_set; + } + if (_excess) { + delete _excess; + } + if (_next) { + delete _next; + } + if (_prev) { + delete _prev; + } + if (_active) { + delete _active; + } + if (_bucket) { + delete _bucket; + } + if (_flow) { + delete _flow; + } + } + + /// \brief Set the tolerance used by the algorithm. + /// + /// This function sets the tolerance object used by the algorithm. + /// \return (*this) + HaoOrlin& tolerance(const Tolerance& tolerance) { + _tolerance = tolerance; + return *this; + } + + /// \brief Returns a const reference to the tolerance. + /// + /// This function returns a const reference to the tolerance object + /// used by the algorithm. + const Tolerance& tolerance() const { + return _tolerance; + } + + private: + + void activate(const Node& i) { + (*_active)[i] = true; + + int bucket = (*_bucket)[i]; + + if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return; + //unlace + (*_next)[(*_prev)[i]] = (*_next)[i]; + if ((*_next)[i] != INVALID) { + (*_prev)[(*_next)[i]] = (*_prev)[i]; + } else { + _last[bucket] = (*_prev)[i]; + } + //lace + (*_next)[i] = _first[bucket]; + (*_prev)[_first[bucket]] = i; + (*_prev)[i] = INVALID; + _first[bucket] = i; + } + + void deactivate(const Node& i) { + (*_active)[i] = false; + int bucket = (*_bucket)[i]; + + if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return; + + //unlace + (*_prev)[(*_next)[i]] = (*_prev)[i]; + if ((*_prev)[i] != INVALID) { + (*_next)[(*_prev)[i]] = (*_next)[i]; + } else { + _first[bucket] = (*_next)[i]; + } + //lace + (*_prev)[i] = _last[bucket]; + (*_next)[_last[bucket]] = i; + (*_next)[i] = INVALID; + _last[bucket] = i; + } + + void addItem(const Node& i, int bucket) { + (*_bucket)[i] = bucket; + if (_last[bucket] != INVALID) { + (*_prev)[i] = _last[bucket]; + (*_next)[_last[bucket]] = i; + (*_next)[i] = INVALID; + _last[bucket] = i; + } else { + (*_prev)[i] = INVALID; + _first[bucket] = i; + (*_next)[i] = INVALID; + _last[bucket] = i; + } + } + + void findMinCutOut() { + + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_excess)[n] = 0; + (*_source_set)[n] = false; + } + + for (ArcIt a(_graph); a != INVALID; ++a) { + (*_flow)[a] = 0; + } + + int bucket_num = 0; + std::vector queue(_node_num); + int qfirst = 0, qlast = 0, qsep = 0; + + { + typename Digraph::template NodeMap reached(_graph, false); + + reached[_source] = true; + bool first_set = true; + + for (NodeIt t(_graph); t != INVALID; ++t) { + if (reached[t]) continue; + _sets.push_front(std::list()); + + queue[qlast++] = t; + reached[t] = true; + + while (qfirst != qlast) { + if (qsep == qfirst) { + ++bucket_num; + _sets.front().push_front(bucket_num); + _dormant[bucket_num] = !first_set; + _first[bucket_num] = _last[bucket_num] = INVALID; + qsep = qlast; + } + + Node n = queue[qfirst++]; + addItem(n, bucket_num); + + for (InArcIt a(_graph, n); a != INVALID; ++a) { + Node u = _graph.source(a); + if (!reached[u] && _tolerance.positive((*_capacity)[a])) { + reached[u] = true; + queue[qlast++] = u; + } + } + } + first_set = false; + } + + ++bucket_num; + (*_bucket)[_source] = 0; + _dormant[0] = true; + } + (*_source_set)[_source] = true; + + Node target = _last[_sets.back().back()]; + { + for (OutArcIt a(_graph, _source); a != INVALID; ++a) { + if (_tolerance.positive((*_capacity)[a])) { + Node u = _graph.target(a); + (*_flow)[a] = (*_capacity)[a]; + (*_excess)[u] += (*_capacity)[a]; + if (!(*_active)[u] && u != _source) { + activate(u); + } + } + } + + if ((*_active)[target]) { + deactivate(target); + } + + _highest = _sets.back().begin(); + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } + + while (true) { + while (_highest != _sets.back().end()) { + Node n = _first[*_highest]; + Value excess = (*_excess)[n]; + int next_bucket = _node_num; + + int under_bucket; + if (++std::list::iterator(_highest) == _sets.back().end()) { + under_bucket = -1; + } else { + under_bucket = *(++std::list::iterator(_highest)); + } + + for (OutArcIt a(_graph, n); a != INVALID; ++a) { + Node v = _graph.target(a); + if (_dormant[(*_bucket)[v]]) continue; + Value rem = (*_capacity)[a] - (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + if ((*_bucket)[v] == under_bucket) { + if (!(*_active)[v] && v != target) { + activate(v); + } + if (!_tolerance.less(rem, excess)) { + (*_flow)[a] += excess; + (*_excess)[v] += excess; + excess = 0; + goto no_more_push; + } else { + excess -= rem; + (*_excess)[v] += rem; + (*_flow)[a] = (*_capacity)[a]; + } + } else if (next_bucket > (*_bucket)[v]) { + next_bucket = (*_bucket)[v]; + } + } + + for (InArcIt a(_graph, n); a != INVALID; ++a) { + Node v = _graph.source(a); + if (_dormant[(*_bucket)[v]]) continue; + Value rem = (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + if ((*_bucket)[v] == under_bucket) { + if (!(*_active)[v] && v != target) { + activate(v); + } + if (!_tolerance.less(rem, excess)) { + (*_flow)[a] -= excess; + (*_excess)[v] += excess; + excess = 0; + goto no_more_push; + } else { + excess -= rem; + (*_excess)[v] += rem; + (*_flow)[a] = 0; + } + } else if (next_bucket > (*_bucket)[v]) { + next_bucket = (*_bucket)[v]; + } + } + + no_more_push: + + (*_excess)[n] = excess; + + if (excess != 0) { + if ((*_next)[n] == INVALID) { + typename std::list >::iterator new_set = + _sets.insert(--_sets.end(), std::list()); + new_set->splice(new_set->end(), _sets.back(), + _sets.back().begin(), ++_highest); + for (std::list::iterator it = new_set->begin(); + it != new_set->end(); ++it) { + _dormant[*it] = true; + } + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } else if (next_bucket == _node_num) { + _first[(*_bucket)[n]] = (*_next)[n]; + (*_prev)[(*_next)[n]] = INVALID; + + std::list >::iterator new_set = + _sets.insert(--_sets.end(), std::list()); + + new_set->push_front(bucket_num); + (*_bucket)[n] = bucket_num; + _first[bucket_num] = _last[bucket_num] = n; + (*_next)[n] = INVALID; + (*_prev)[n] = INVALID; + _dormant[bucket_num] = true; + ++bucket_num; + + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } else { + _first[*_highest] = (*_next)[n]; + (*_prev)[(*_next)[n]] = INVALID; + + while (next_bucket != *_highest) { + --_highest; + } + + if (_highest == _sets.back().begin()) { + _sets.back().push_front(bucket_num); + _dormant[bucket_num] = false; + _first[bucket_num] = _last[bucket_num] = INVALID; + ++bucket_num; + } + --_highest; + + (*_bucket)[n] = *_highest; + (*_next)[n] = _first[*_highest]; + if (_first[*_highest] != INVALID) { + (*_prev)[_first[*_highest]] = n; + } else { + _last[*_highest] = n; + } + _first[*_highest] = n; + } + } else { + + deactivate(n); + if (!(*_active)[_first[*_highest]]) { + ++_highest; + if (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + _highest = _sets.back().end(); + } + } + } + } + + if ((*_excess)[target] < _min_cut) { + _min_cut = (*_excess)[target]; + for (NodeIt i(_graph); i != INVALID; ++i) { + (*_min_cut_map)[i] = true; + } + for (std::list::iterator it = _sets.back().begin(); + it != _sets.back().end(); ++it) { + Node n = _first[*it]; + while (n != INVALID) { + (*_min_cut_map)[n] = false; + n = (*_next)[n]; + } + } + } + + { + Node new_target; + if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) { + if ((*_next)[target] == INVALID) { + _last[(*_bucket)[target]] = (*_prev)[target]; + new_target = (*_prev)[target]; + } else { + (*_prev)[(*_next)[target]] = (*_prev)[target]; + new_target = (*_next)[target]; + } + if ((*_prev)[target] == INVALID) { + _first[(*_bucket)[target]] = (*_next)[target]; + } else { + (*_next)[(*_prev)[target]] = (*_next)[target]; + } + } else { + _sets.back().pop_back(); + if (_sets.back().empty()) { + _sets.pop_back(); + if (_sets.empty()) + break; + for (std::list::iterator it = _sets.back().begin(); + it != _sets.back().end(); ++it) { + _dormant[*it] = false; + } + } + new_target = _last[_sets.back().back()]; + } + + (*_bucket)[target] = 0; + + (*_source_set)[target] = true; + for (OutArcIt a(_graph, target); a != INVALID; ++a) { + Value rem = (*_capacity)[a] - (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.target(a); + if (!(*_active)[v] && !(*_source_set)[v]) { + activate(v); + } + (*_excess)[v] += rem; + (*_flow)[a] = (*_capacity)[a]; + } + + for (InArcIt a(_graph, target); a != INVALID; ++a) { + Value rem = (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.source(a); + if (!(*_active)[v] && !(*_source_set)[v]) { + activate(v); + } + (*_excess)[v] += rem; + (*_flow)[a] = 0; + } + + target = new_target; + if ((*_active)[target]) { + deactivate(target); + } + + _highest = _sets.back().begin(); + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } + } + } + + void findMinCutIn() { + + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_excess)[n] = 0; + (*_source_set)[n] = false; + } + + for (ArcIt a(_graph); a != INVALID; ++a) { + (*_flow)[a] = 0; + } + + int bucket_num = 0; + std::vector queue(_node_num); + int qfirst = 0, qlast = 0, qsep = 0; + + { + typename Digraph::template NodeMap reached(_graph, false); + + reached[_source] = true; + + bool first_set = true; + + for (NodeIt t(_graph); t != INVALID; ++t) { + if (reached[t]) continue; + _sets.push_front(std::list()); + + queue[qlast++] = t; + reached[t] = true; + + while (qfirst != qlast) { + if (qsep == qfirst) { + ++bucket_num; + _sets.front().push_front(bucket_num); + _dormant[bucket_num] = !first_set; + _first[bucket_num] = _last[bucket_num] = INVALID; + qsep = qlast; + } + + Node n = queue[qfirst++]; + addItem(n, bucket_num); + + for (OutArcIt a(_graph, n); a != INVALID; ++a) { + Node u = _graph.target(a); + if (!reached[u] && _tolerance.positive((*_capacity)[a])) { + reached[u] = true; + queue[qlast++] = u; + } + } + } + first_set = false; + } + + ++bucket_num; + (*_bucket)[_source] = 0; + _dormant[0] = true; + } + (*_source_set)[_source] = true; + + Node target = _last[_sets.back().back()]; + { + for (InArcIt a(_graph, _source); a != INVALID; ++a) { + if (_tolerance.positive((*_capacity)[a])) { + Node u = _graph.source(a); + (*_flow)[a] = (*_capacity)[a]; + (*_excess)[u] += (*_capacity)[a]; + if (!(*_active)[u] && u != _source) { + activate(u); + } + } + } + if ((*_active)[target]) { + deactivate(target); + } + + _highest = _sets.back().begin(); + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } + + + while (true) { + while (_highest != _sets.back().end()) { + Node n = _first[*_highest]; + Value excess = (*_excess)[n]; + int next_bucket = _node_num; + + int under_bucket; + if (++std::list::iterator(_highest) == _sets.back().end()) { + under_bucket = -1; + } else { + under_bucket = *(++std::list::iterator(_highest)); + } + + for (InArcIt a(_graph, n); a != INVALID; ++a) { + Node v = _graph.source(a); + if (_dormant[(*_bucket)[v]]) continue; + Value rem = (*_capacity)[a] - (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + if ((*_bucket)[v] == under_bucket) { + if (!(*_active)[v] && v != target) { + activate(v); + } + if (!_tolerance.less(rem, excess)) { + (*_flow)[a] += excess; + (*_excess)[v] += excess; + excess = 0; + goto no_more_push; + } else { + excess -= rem; + (*_excess)[v] += rem; + (*_flow)[a] = (*_capacity)[a]; + } + } else if (next_bucket > (*_bucket)[v]) { + next_bucket = (*_bucket)[v]; + } + } + + for (OutArcIt a(_graph, n); a != INVALID; ++a) { + Node v = _graph.target(a); + if (_dormant[(*_bucket)[v]]) continue; + Value rem = (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + if ((*_bucket)[v] == under_bucket) { + if (!(*_active)[v] && v != target) { + activate(v); + } + if (!_tolerance.less(rem, excess)) { + (*_flow)[a] -= excess; + (*_excess)[v] += excess; + excess = 0; + goto no_more_push; + } else { + excess -= rem; + (*_excess)[v] += rem; + (*_flow)[a] = 0; + } + } else if (next_bucket > (*_bucket)[v]) { + next_bucket = (*_bucket)[v]; + } + } + + no_more_push: + + (*_excess)[n] = excess; + + if (excess != 0) { + if ((*_next)[n] == INVALID) { + typename std::list >::iterator new_set = + _sets.insert(--_sets.end(), std::list()); + new_set->splice(new_set->end(), _sets.back(), + _sets.back().begin(), ++_highest); + for (std::list::iterator it = new_set->begin(); + it != new_set->end(); ++it) { + _dormant[*it] = true; + } + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } else if (next_bucket == _node_num) { + _first[(*_bucket)[n]] = (*_next)[n]; + (*_prev)[(*_next)[n]] = INVALID; + + std::list >::iterator new_set = + _sets.insert(--_sets.end(), std::list()); + + new_set->push_front(bucket_num); + (*_bucket)[n] = bucket_num; + _first[bucket_num] = _last[bucket_num] = n; + (*_next)[n] = INVALID; + (*_prev)[n] = INVALID; + _dormant[bucket_num] = true; + ++bucket_num; + + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } else { + _first[*_highest] = (*_next)[n]; + (*_prev)[(*_next)[n]] = INVALID; + + while (next_bucket != *_highest) { + --_highest; + } + if (_highest == _sets.back().begin()) { + _sets.back().push_front(bucket_num); + _dormant[bucket_num] = false; + _first[bucket_num] = _last[bucket_num] = INVALID; + ++bucket_num; + } + --_highest; + + (*_bucket)[n] = *_highest; + (*_next)[n] = _first[*_highest]; + if (_first[*_highest] != INVALID) { + (*_prev)[_first[*_highest]] = n; + } else { + _last[*_highest] = n; + } + _first[*_highest] = n; + } + } else { + + deactivate(n); + if (!(*_active)[_first[*_highest]]) { + ++_highest; + if (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + _highest = _sets.back().end(); + } + } + } + } + + if ((*_excess)[target] < _min_cut) { + _min_cut = (*_excess)[target]; + for (NodeIt i(_graph); i != INVALID; ++i) { + (*_min_cut_map)[i] = false; + } + for (std::list::iterator it = _sets.back().begin(); + it != _sets.back().end(); ++it) { + Node n = _first[*it]; + while (n != INVALID) { + (*_min_cut_map)[n] = true; + n = (*_next)[n]; + } + } + } + + { + Node new_target; + if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) { + if ((*_next)[target] == INVALID) { + _last[(*_bucket)[target]] = (*_prev)[target]; + new_target = (*_prev)[target]; + } else { + (*_prev)[(*_next)[target]] = (*_prev)[target]; + new_target = (*_next)[target]; + } + if ((*_prev)[target] == INVALID) { + _first[(*_bucket)[target]] = (*_next)[target]; + } else { + (*_next)[(*_prev)[target]] = (*_next)[target]; + } + } else { + _sets.back().pop_back(); + if (_sets.back().empty()) { + _sets.pop_back(); + if (_sets.empty()) + break; + for (std::list::iterator it = _sets.back().begin(); + it != _sets.back().end(); ++it) { + _dormant[*it] = false; + } + } + new_target = _last[_sets.back().back()]; + } + + (*_bucket)[target] = 0; + + (*_source_set)[target] = true; + for (InArcIt a(_graph, target); a != INVALID; ++a) { + Value rem = (*_capacity)[a] - (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.source(a); + if (!(*_active)[v] && !(*_source_set)[v]) { + activate(v); + } + (*_excess)[v] += rem; + (*_flow)[a] = (*_capacity)[a]; + } + + for (OutArcIt a(_graph, target); a != INVALID; ++a) { + Value rem = (*_flow)[a]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.target(a); + if (!(*_active)[v] && !(*_source_set)[v]) { + activate(v); + } + (*_excess)[v] += rem; + (*_flow)[a] = 0; + } + + target = new_target; + if ((*_active)[target]) { + deactivate(target); + } + + _highest = _sets.back().begin(); + while (_highest != _sets.back().end() && + !(*_active)[_first[*_highest]]) { + ++_highest; + } + } + } + } + + public: + + /// \name Execution Control + /// The simplest way to execute the algorithm is to use + /// one of the member functions called \ref run(). + /// \n + /// If you need better control on the execution, + /// you have to call one of the \ref init() functions first, then + /// \ref calculateOut() and/or \ref calculateIn(). + + /// @{ + + /// \brief Initialize the internal data structures. + /// + /// This function initializes the internal data structures. It creates + /// the maps and some bucket structures for the algorithm. + /// The first node is used as the source node for the push-relabel + /// algorithm. + void init() { + init(NodeIt(_graph)); + } + + /// \brief Initialize the internal data structures. + /// + /// This function initializes the internal data structures. It creates + /// the maps and some bucket structures for the algorithm. + /// The given node is used as the source node for the push-relabel + /// algorithm. + void init(const Node& source) { + _source = source; + + _node_num = countNodes(_graph); + + _first.resize(_node_num); + _last.resize(_node_num); + + _dormant.resize(_node_num); + + if (!_flow) { + _flow = new FlowMap(_graph); + } + if (!_next) { + _next = new typename Digraph::template NodeMap(_graph); + } + if (!_prev) { + _prev = new typename Digraph::template NodeMap(_graph); + } + if (!_active) { + _active = new typename Digraph::template NodeMap(_graph); + } + if (!_bucket) { + _bucket = new typename Digraph::template NodeMap(_graph); + } + if (!_excess) { + _excess = new ExcessMap(_graph); + } + if (!_source_set) { + _source_set = new SourceSetMap(_graph); + } + if (!_min_cut_map) { + _min_cut_map = new MinCutMap(_graph); + } + + _min_cut = std::numeric_limits::max(); + } + + + /// \brief Calculate a minimum cut with \f$ source \f$ on the + /// source-side. + /// + /// This function calculates a minimum cut with \f$ source \f$ on the + /// source-side (i.e. a set \f$ X\subsetneq V \f$ with + /// \f$ source \in X \f$ and minimal outgoing capacity). + /// + /// \pre \ref init() must be called before using this function. + void calculateOut() { + findMinCutOut(); + } + + /// \brief Calculate a minimum cut with \f$ source \f$ on the + /// sink-side. + /// + /// This function calculates a minimum cut with \f$ source \f$ on the + /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with + /// \f$ source \notin X \f$ and minimal outgoing capacity). + /// + /// \pre \ref init() must be called before using this function. + void calculateIn() { + findMinCutIn(); + } + + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. It finds nodes \c source and + /// \c target arbitrarily and then calls \ref init(), \ref calculateOut() + /// and \ref calculateIn(). + void run() { + init(); + calculateOut(); + calculateIn(); + } + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. It uses the given \c source node, + /// finds a proper \c target node and then calls the \ref init(), + /// \ref calculateOut() and \ref calculateIn(). + void run(const Node& s) { + init(s); + calculateOut(); + calculateIn(); + } + + /// @} + + /// \name Query Functions + /// The result of the %HaoOrlin algorithm + /// can be obtained using these functions.\n + /// \ref run(), \ref calculateOut() or \ref calculateIn() + /// should be called before using them. + + /// @{ + + /// \brief Return the value of the minimum cut. + /// + /// This function returns the value of the minimum cut. + /// + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() + /// must be called before using this function. + Value minCutValue() const { + return _min_cut; + } + + + /// \brief Return a minimum cut. + /// + /// This function sets \c cutMap to the characteristic vector of a + /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$ + /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly + /// for the nodes of \f$ X \f$). + /// + /// \param cutMap A \ref concepts::WriteMap "writable" node map with + /// \c bool (or convertible) value type. + /// + /// \return The value of the minimum cut. + /// + /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() + /// must be called before using this function. + template + Value minCutMap(CutMap& cutMap) const { + for (NodeIt it(_graph); it != INVALID; ++it) { + cutMap.set(it, (*_min_cut_map)[it]); + } + return _min_cut; + } + + /// @} + + }; //class HaoOrlin + +} //namespace lemon + +#endif //LEMON_HAO_ORLIN_H diff --git a/lemon/lemon/hartmann_orlin_mmc.h b/lemon/lemon/hartmann_orlin_mmc.h new file mode 100644 index 0000000..791959d --- /dev/null +++ b/lemon/lemon/hartmann_orlin_mmc.h @@ -0,0 +1,650 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_HARTMANN_ORLIN_MMC_H +#define LEMON_HARTMANN_ORLIN_MMC_H + +/// \ingroup min_mean_cycle +/// +/// \file +/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle. + +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \brief Default traits class of HartmannOrlinMmc class. + /// + /// Default traits class of HartmannOrlinMmc class. + /// \tparam GR The type of the digraph. + /// \tparam CM The type of the cost map. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. +#ifdef DOXYGEN + template +#else + template ::is_integer> +#endif + struct HartmannOrlinMmcDefaultTraits + { + /// The type of the digraph + typedef GR Digraph; + /// The type of the cost map + typedef CM CostMap; + /// The type of the arc costs + typedef typename CostMap::Value Cost; + + /// \brief The large cost type used for internal computations + /// + /// The large cost type used for internal computations. + /// It is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + /// \c Cost must be convertible to \c LargeCost. + typedef double LargeCost; + + /// The tolerance type used for internal computations + typedef lemon::Tolerance Tolerance; + + /// \brief The path type of the found cycles + /// + /// The path type of the found cycles. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addFront() function. + typedef lemon::Path Path; + }; + + // Default traits class for integer cost types + template + struct HartmannOrlinMmcDefaultTraits + { + typedef GR Digraph; + typedef CM CostMap; + typedef typename CostMap::Value Cost; +#ifdef LEMON_HAVE_LONG_LONG + typedef long long LargeCost; +#else + typedef long LargeCost; +#endif + typedef lemon::Tolerance Tolerance; + typedef lemon::Path Path; + }; + + + /// \addtogroup min_mean_cycle + /// @{ + + /// \brief Implementation of the Hartmann-Orlin algorithm for finding + /// a minimum mean cycle. + /// + /// This class implements the Hartmann-Orlin algorithm for finding + /// a directed cycle of minimum mean cost in a digraph + /// \ref amo93networkflows, \ref dasdan98minmeancycle. + /// It is an improved version of \ref KarpMmc "Karp"'s original algorithm, + /// it applies an efficient early termination scheme. + /// It runs in time O(ne) and uses space O(n2+e). + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// \tparam CM The type of the cost map. The default + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap". + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits + /// "HartmannOrlinMmcDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template < typename GR, + typename CM = typename GR::template ArcMap, + typename TR = HartmannOrlinMmcDefaultTraits > +#endif + class HartmannOrlinMmc + { + public: + + /// The type of the digraph + typedef typename TR::Digraph Digraph; + /// The type of the cost map + typedef typename TR::CostMap CostMap; + /// The type of the arc costs + typedef typename TR::Cost Cost; + + /// \brief The large cost type + /// + /// The large cost type used for internal computations. + /// By default, it is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + typedef typename TR::LargeCost LargeCost; + + /// The tolerance type + typedef typename TR::Tolerance Tolerance; + + /// \brief The path type of the found cycles + /// + /// The path type of the found cycles. + /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class", + /// it is \ref lemon::Path "Path". + typedef typename TR::Path Path; + + /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm + typedef TR Traits; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + // Data sturcture for path data + struct PathData + { + LargeCost dist; + Arc pred; + PathData(LargeCost d, Arc p = INVALID) : + dist(d), pred(p) {} + }; + + typedef typename Digraph::template NodeMap > + PathDataNodeMap; + + private: + + // The digraph the algorithm runs on + const Digraph &_gr; + // The cost of the arcs + const CostMap &_cost; + + // Data for storing the strongly connected components + int _comp_num; + typename Digraph::template NodeMap _comp; + std::vector > _comp_nodes; + std::vector* _nodes; + typename Digraph::template NodeMap > _out_arcs; + + // Data for the found cycles + bool _curr_found, _best_found; + LargeCost _curr_cost, _best_cost; + int _curr_size, _best_size; + Node _curr_node, _best_node; + int _curr_level, _best_level; + + Path *_cycle_path; + bool _local_path; + + // Node map for storing path data + PathDataNodeMap _data; + // The processed nodes in the last round + std::vector _process; + + Tolerance _tolerance; + + // Infinite constant + const LargeCost INF; + + public: + + /// \name Named Template Parameters + /// @{ + + template + struct SetLargeCostTraits : public Traits { + typedef T LargeCost; + typedef lemon::Tolerance Tolerance; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c LargeCost type. + /// + /// \ref named-templ-param "Named parameter" for setting \c LargeCost + /// type. It is used for internal computations in the algorithm. + template + struct SetLargeCost + : public HartmannOrlinMmc > { + typedef HartmannOrlinMmc > Create; + }; + + template + struct SetPathTraits : public Traits { + typedef T Path; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c %Path type. + /// + /// \ref named-templ-param "Named parameter" for setting the \c %Path + /// type of the found cycles. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addFront() function. + template + struct SetPath + : public HartmannOrlinMmc > { + typedef HartmannOrlinMmc > Create; + }; + + /// @} + + protected: + + HartmannOrlinMmc() {} + + public: + + /// \brief Constructor. + /// + /// The constructor of the class. + /// + /// \param digraph The digraph the algorithm runs on. + /// \param cost The costs of the arcs. + HartmannOrlinMmc( const Digraph &digraph, + const CostMap &cost ) : + _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph), + _best_found(false), _best_cost(0), _best_size(1), + _cycle_path(NULL), _local_path(false), _data(digraph), + INF(std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max()) + {} + + /// Destructor. + ~HartmannOrlinMmc() { + if (_local_path) delete _cycle_path; + } + + /// \brief Set the path structure for storing the found cycle. + /// + /// This function sets an external path structure for storing the + /// found cycle. + /// + /// If you don't call this function before calling \ref run() or + /// \ref findCycleMean(), it will allocate a local \ref Path "path" + /// structure. The destuctor deallocates this automatically + /// allocated object, of course. + /// + /// \note The algorithm calls only the \ref lemon::Path::addFront() + /// "addFront()" function of the given path structure. + /// + /// \return (*this) + HartmannOrlinMmc& cycle(Path &path) { + if (_local_path) { + delete _cycle_path; + _local_path = false; + } + _cycle_path = &path; + return *this; + } + + /// \brief Set the tolerance used by the algorithm. + /// + /// This function sets the tolerance object used by the algorithm. + /// + /// \return (*this) + HartmannOrlinMmc& tolerance(const Tolerance& tolerance) { + _tolerance = tolerance; + return *this; + } + + /// \brief Return a const reference to the tolerance. + /// + /// This function returns a const reference to the tolerance object + /// used by the algorithm. + const Tolerance& tolerance() const { + return _tolerance; + } + + /// \name Execution control + /// The simplest way to execute the algorithm is to call the \ref run() + /// function.\n + /// If you only need the minimum mean cost, you may call + /// \ref findCycleMean(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// It can be called more than once (e.g. if the underlying digraph + /// and/or the arc costs have been modified). + /// + /// \return \c true if a directed cycle exists in the digraph. + /// + /// \note mmc.run() is just a shortcut of the following code. + /// \code + /// return mmc.findCycleMean() && mmc.findCycle(); + /// \endcode + bool run() { + return findCycleMean() && findCycle(); + } + + /// \brief Find the minimum cycle mean. + /// + /// This function finds the minimum mean cost of the directed + /// cycles in the digraph. + /// + /// \return \c true if a directed cycle exists in the digraph. + bool findCycleMean() { + // Initialization and find strongly connected components + init(); + findComponents(); + + // Find the minimum cycle mean in the components + for (int comp = 0; comp < _comp_num; ++comp) { + if (!initComponent(comp)) continue; + processRounds(); + + // Update the best cycle (global minimum mean cycle) + if ( _curr_found && (!_best_found || + _curr_cost * _best_size < _best_cost * _curr_size) ) { + _best_found = true; + _best_cost = _curr_cost; + _best_size = _curr_size; + _best_node = _curr_node; + _best_level = _curr_level; + } + } + return _best_found; + } + + /// \brief Find a minimum mean directed cycle. + /// + /// This function finds a directed cycle of minimum mean cost + /// in the digraph using the data computed by findCycleMean(). + /// + /// \return \c true if a directed cycle exists in the digraph. + /// + /// \pre \ref findCycleMean() must be called before using this function. + bool findCycle() { + if (!_best_found) return false; + IntNodeMap reached(_gr, -1); + int r = _best_level + 1; + Node u = _best_node; + while (reached[u] < 0) { + reached[u] = --r; + u = _gr.source(_data[u][r].pred); + } + r = reached[u]; + Arc e = _data[u][r].pred; + _cycle_path->addFront(e); + _best_cost = _cost[e]; + _best_size = 1; + Node v; + while ((v = _gr.source(e)) != u) { + e = _data[v][--r].pred; + _cycle_path->addFront(e); + _best_cost += _cost[e]; + ++_best_size; + } + return true; + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions.\n + /// The algorithm should be executed before using them. + + /// @{ + + /// \brief Return the total cost of the found cycle. + /// + /// This function returns the total cost of the found cycle. + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + Cost cycleCost() const { + return static_cast(_best_cost); + } + + /// \brief Return the number of arcs on the found cycle. + /// + /// This function returns the number of arcs on the found cycle. + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + int cycleSize() const { + return _best_size; + } + + /// \brief Return the mean cost of the found cycle. + /// + /// This function returns the mean cost of the found cycle. + /// + /// \note alg.cycleMean() is just a shortcut of the + /// following code. + /// \code + /// return static_cast(alg.cycleCost()) / alg.cycleSize(); + /// \endcode + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + double cycleMean() const { + return static_cast(_best_cost) / _best_size; + } + + /// \brief Return the found cycle. + /// + /// This function returns a const reference to the path structure + /// storing the found cycle. + /// + /// \pre \ref run() or \ref findCycle() must be called before using + /// this function. + const Path& cycle() const { + return *_cycle_path; + } + + ///@} + + private: + + // Initialization + void init() { + if (!_cycle_path) { + _local_path = true; + _cycle_path = new Path; + } + _cycle_path->clear(); + _best_found = false; + _best_cost = 0; + _best_size = 1; + _cycle_path->clear(); + for (NodeIt u(_gr); u != INVALID; ++u) + _data[u].clear(); + } + + // Find strongly connected components and initialize _comp_nodes + // and _out_arcs + void findComponents() { + _comp_num = stronglyConnectedComponents(_gr, _comp); + _comp_nodes.resize(_comp_num); + if (_comp_num == 1) { + _comp_nodes[0].clear(); + for (NodeIt n(_gr); n != INVALID; ++n) { + _comp_nodes[0].push_back(n); + _out_arcs[n].clear(); + for (OutArcIt a(_gr, n); a != INVALID; ++a) { + _out_arcs[n].push_back(a); + } + } + } else { + for (int i = 0; i < _comp_num; ++i) + _comp_nodes[i].clear(); + for (NodeIt n(_gr); n != INVALID; ++n) { + int k = _comp[n]; + _comp_nodes[k].push_back(n); + _out_arcs[n].clear(); + for (OutArcIt a(_gr, n); a != INVALID; ++a) { + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a); + } + } + } + } + + // Initialize path data for the current component + bool initComponent(int comp) { + _nodes = &(_comp_nodes[comp]); + int n = _nodes->size(); + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) { + return false; + } + for (int i = 0; i < n; ++i) { + _data[(*_nodes)[i]].resize(n + 1, PathData(INF)); + } + return true; + } + + // Process all rounds of computing path data for the current component. + // _data[v][k] is the cost of a shortest directed walk from the root + // node to node v containing exactly k arcs. + void processRounds() { + Node start = (*_nodes)[0]; + _data[start][0] = PathData(0); + _process.clear(); + _process.push_back(start); + + int k, n = _nodes->size(); + int next_check = 4; + bool terminate = false; + for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) { + processNextBuildRound(k); + if (k == next_check || k == n) { + terminate = checkTermination(k); + next_check = next_check * 3 / 2; + } + } + for ( ; k <= n && !terminate; ++k) { + processNextFullRound(k); + if (k == next_check || k == n) { + terminate = checkTermination(k); + next_check = next_check * 3 / 2; + } + } + } + + // Process one round and rebuild _process + void processNextBuildRound(int k) { + std::vector next; + Node u, v; + Arc e; + LargeCost d; + for (int i = 0; i < int(_process.size()); ++i) { + u = _process[i]; + for (int j = 0; j < int(_out_arcs[u].size()); ++j) { + e = _out_arcs[u][j]; + v = _gr.target(e); + d = _data[u][k-1].dist + _cost[e]; + if (_tolerance.less(d, _data[v][k].dist)) { + if (_data[v][k].dist == INF) next.push_back(v); + _data[v][k] = PathData(d, e); + } + } + } + _process.swap(next); + } + + // Process one round using _nodes instead of _process + void processNextFullRound(int k) { + Node u, v; + Arc e; + LargeCost d; + for (int i = 0; i < int(_nodes->size()); ++i) { + u = (*_nodes)[i]; + for (int j = 0; j < int(_out_arcs[u].size()); ++j) { + e = _out_arcs[u][j]; + v = _gr.target(e); + d = _data[u][k-1].dist + _cost[e]; + if (_tolerance.less(d, _data[v][k].dist)) { + _data[v][k] = PathData(d, e); + } + } + } + } + + // Check early termination + bool checkTermination(int k) { + typedef std::pair Pair; + typename GR::template NodeMap level(_gr, Pair(-1, 0)); + typename GR::template NodeMap pi(_gr); + int n = _nodes->size(); + LargeCost cost; + int size; + Node u; + + // Search for cycles that are already found + _curr_found = false; + for (int i = 0; i < n; ++i) { + u = (*_nodes)[i]; + if (_data[u][k].dist == INF) continue; + for (int j = k; j >= 0; --j) { + if (level[u].first == i && level[u].second > 0) { + // A cycle is found + cost = _data[u][level[u].second].dist - _data[u][j].dist; + size = level[u].second - j; + if (!_curr_found || cost * _curr_size < _curr_cost * size) { + _curr_cost = cost; + _curr_size = size; + _curr_node = u; + _curr_level = level[u].second; + _curr_found = true; + } + } + level[u] = Pair(i, j); + if (j != 0) { + u = _gr.source(_data[u][j].pred); + } + } + } + + // If at least one cycle is found, check the optimality condition + LargeCost d; + if (_curr_found && k < n) { + // Find node potentials + for (int i = 0; i < n; ++i) { + u = (*_nodes)[i]; + pi[u] = INF; + for (int j = 0; j <= k; ++j) { + if (_data[u][j].dist < INF) { + d = _data[u][j].dist * _curr_size - j * _curr_cost; + if (_tolerance.less(d, pi[u])) pi[u] = d; + } + } + } + + // Check the optimality condition for all arcs + bool done = true; + for (ArcIt a(_gr); a != INVALID; ++a) { + if (_tolerance.less(_cost[a] * _curr_size - _curr_cost, + pi[_gr.target(a)] - pi[_gr.source(a)]) ) { + done = false; + break; + } + } + return done; + } + return (k == n); + } + + }; //class HartmannOrlinMmc + + ///@} + +} //namespace lemon + +#endif //LEMON_HARTMANN_ORLIN_MMC_H diff --git a/lemon/lemon/howard_mmc.h b/lemon/lemon/howard_mmc.h new file mode 100644 index 0000000..1ba17d7 --- /dev/null +++ b/lemon/lemon/howard_mmc.h @@ -0,0 +1,605 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_HOWARD_MMC_H +#define LEMON_HOWARD_MMC_H + +/// \ingroup min_mean_cycle +/// +/// \file +/// \brief Howard's algorithm for finding a minimum mean cycle. + +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \brief Default traits class of HowardMmc class. + /// + /// Default traits class of HowardMmc class. + /// \tparam GR The type of the digraph. + /// \tparam CM The type of the cost map. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. +#ifdef DOXYGEN + template +#else + template ::is_integer> +#endif + struct HowardMmcDefaultTraits + { + /// The type of the digraph + typedef GR Digraph; + /// The type of the cost map + typedef CM CostMap; + /// The type of the arc costs + typedef typename CostMap::Value Cost; + + /// \brief The large cost type used for internal computations + /// + /// The large cost type used for internal computations. + /// It is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + /// \c Cost must be convertible to \c LargeCost. + typedef double LargeCost; + + /// The tolerance type used for internal computations + typedef lemon::Tolerance Tolerance; + + /// \brief The path type of the found cycles + /// + /// The path type of the found cycles. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addBack() function. + typedef lemon::Path Path; + }; + + // Default traits class for integer cost types + template + struct HowardMmcDefaultTraits + { + typedef GR Digraph; + typedef CM CostMap; + typedef typename CostMap::Value Cost; +#ifdef LEMON_HAVE_LONG_LONG + typedef long long LargeCost; +#else + typedef long LargeCost; +#endif + typedef lemon::Tolerance Tolerance; + typedef lemon::Path Path; + }; + + + /// \addtogroup min_mean_cycle + /// @{ + + /// \brief Implementation of Howard's algorithm for finding a minimum + /// mean cycle. + /// + /// This class implements Howard's policy iteration algorithm for finding + /// a directed cycle of minimum mean cost in a digraph + /// \ref amo93networkflows, \ref dasdan98minmeancycle. + /// This class provides the most efficient algorithm for the + /// minimum mean cycle problem, though the best known theoretical + /// bound on its running time is exponential. + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// \tparam CM The type of the cost map. The default + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap". + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref HowardMmcDefaultTraits + /// "HowardMmcDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template < typename GR, + typename CM = typename GR::template ArcMap, + typename TR = HowardMmcDefaultTraits > +#endif + class HowardMmc + { + public: + + /// The type of the digraph + typedef typename TR::Digraph Digraph; + /// The type of the cost map + typedef typename TR::CostMap CostMap; + /// The type of the arc costs + typedef typename TR::Cost Cost; + + /// \brief The large cost type + /// + /// The large cost type used for internal computations. + /// By default, it is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + typedef typename TR::LargeCost LargeCost; + + /// The tolerance type + typedef typename TR::Tolerance Tolerance; + + /// \brief The path type of the found cycles + /// + /// The path type of the found cycles. + /// Using the \ref HowardMmcDefaultTraits "default traits class", + /// it is \ref lemon::Path "Path". + typedef typename TR::Path Path; + + /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm + typedef TR Traits; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + // The digraph the algorithm runs on + const Digraph &_gr; + // The cost of the arcs + const CostMap &_cost; + + // Data for the found cycles + bool _curr_found, _best_found; + LargeCost _curr_cost, _best_cost; + int _curr_size, _best_size; + Node _curr_node, _best_node; + + Path *_cycle_path; + bool _local_path; + + // Internal data used by the algorithm + typename Digraph::template NodeMap _policy; + typename Digraph::template NodeMap _reached; + typename Digraph::template NodeMap _level; + typename Digraph::template NodeMap _dist; + + // Data for storing the strongly connected components + int _comp_num; + typename Digraph::template NodeMap _comp; + std::vector > _comp_nodes; + std::vector* _nodes; + typename Digraph::template NodeMap > _in_arcs; + + // Queue used for BFS search + std::vector _queue; + int _qfront, _qback; + + Tolerance _tolerance; + + // Infinite constant + const LargeCost INF; + + public: + + /// \name Named Template Parameters + /// @{ + + template + struct SetLargeCostTraits : public Traits { + typedef T LargeCost; + typedef lemon::Tolerance Tolerance; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c LargeCost type. + /// + /// \ref named-templ-param "Named parameter" for setting \c LargeCost + /// type. It is used for internal computations in the algorithm. + template + struct SetLargeCost + : public HowardMmc > { + typedef HowardMmc > Create; + }; + + template + struct SetPathTraits : public Traits { + typedef T Path; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c %Path type. + /// + /// \ref named-templ-param "Named parameter" for setting the \c %Path + /// type of the found cycles. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addBack() function. + template + struct SetPath + : public HowardMmc > { + typedef HowardMmc > Create; + }; + + /// @} + + protected: + + HowardMmc() {} + + public: + + /// \brief Constructor. + /// + /// The constructor of the class. + /// + /// \param digraph The digraph the algorithm runs on. + /// \param cost The costs of the arcs. + HowardMmc( const Digraph &digraph, + const CostMap &cost ) : + _gr(digraph), _cost(cost), _best_found(false), + _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false), + _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph), + _comp(digraph), _in_arcs(digraph), + INF(std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max()) + {} + + /// Destructor. + ~HowardMmc() { + if (_local_path) delete _cycle_path; + } + + /// \brief Set the path structure for storing the found cycle. + /// + /// This function sets an external path structure for storing the + /// found cycle. + /// + /// If you don't call this function before calling \ref run() or + /// \ref findCycleMean(), it will allocate a local \ref Path "path" + /// structure. The destuctor deallocates this automatically + /// allocated object, of course. + /// + /// \note The algorithm calls only the \ref lemon::Path::addBack() + /// "addBack()" function of the given path structure. + /// + /// \return (*this) + HowardMmc& cycle(Path &path) { + if (_local_path) { + delete _cycle_path; + _local_path = false; + } + _cycle_path = &path; + return *this; + } + + /// \brief Set the tolerance used by the algorithm. + /// + /// This function sets the tolerance object used by the algorithm. + /// + /// \return (*this) + HowardMmc& tolerance(const Tolerance& tolerance) { + _tolerance = tolerance; + return *this; + } + + /// \brief Return a const reference to the tolerance. + /// + /// This function returns a const reference to the tolerance object + /// used by the algorithm. + const Tolerance& tolerance() const { + return _tolerance; + } + + /// \name Execution control + /// The simplest way to execute the algorithm is to call the \ref run() + /// function.\n + /// If you only need the minimum mean cost, you may call + /// \ref findCycleMean(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// It can be called more than once (e.g. if the underlying digraph + /// and/or the arc costs have been modified). + /// + /// \return \c true if a directed cycle exists in the digraph. + /// + /// \note mmc.run() is just a shortcut of the following code. + /// \code + /// return mmc.findCycleMean() && mmc.findCycle(); + /// \endcode + bool run() { + return findCycleMean() && findCycle(); + } + + /// \brief Find the minimum cycle mean. + /// + /// This function finds the minimum mean cost of the directed + /// cycles in the digraph. + /// + /// \return \c true if a directed cycle exists in the digraph. + bool findCycleMean() { + // Initialize and find strongly connected components + init(); + findComponents(); + + // Find the minimum cycle mean in the components + for (int comp = 0; comp < _comp_num; ++comp) { + // Find the minimum mean cycle in the current component + if (!buildPolicyGraph(comp)) continue; + while (true) { + findPolicyCycle(); + if (!computeNodeDistances()) break; + } + // Update the best cycle (global minimum mean cycle) + if ( _curr_found && (!_best_found || + _curr_cost * _best_size < _best_cost * _curr_size) ) { + _best_found = true; + _best_cost = _curr_cost; + _best_size = _curr_size; + _best_node = _curr_node; + } + } + return _best_found; + } + + /// \brief Find a minimum mean directed cycle. + /// + /// This function finds a directed cycle of minimum mean cost + /// in the digraph using the data computed by findCycleMean(). + /// + /// \return \c true if a directed cycle exists in the digraph. + /// + /// \pre \ref findCycleMean() must be called before using this function. + bool findCycle() { + if (!_best_found) return false; + _cycle_path->addBack(_policy[_best_node]); + for ( Node v = _best_node; + (v = _gr.target(_policy[v])) != _best_node; ) { + _cycle_path->addBack(_policy[v]); + } + return true; + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions.\n + /// The algorithm should be executed before using them. + + /// @{ + + /// \brief Return the total cost of the found cycle. + /// + /// This function returns the total cost of the found cycle. + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + Cost cycleCost() const { + return static_cast(_best_cost); + } + + /// \brief Return the number of arcs on the found cycle. + /// + /// This function returns the number of arcs on the found cycle. + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + int cycleSize() const { + return _best_size; + } + + /// \brief Return the mean cost of the found cycle. + /// + /// This function returns the mean cost of the found cycle. + /// + /// \note alg.cycleMean() is just a shortcut of the + /// following code. + /// \code + /// return static_cast(alg.cycleCost()) / alg.cycleSize(); + /// \endcode + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + double cycleMean() const { + return static_cast(_best_cost) / _best_size; + } + + /// \brief Return the found cycle. + /// + /// This function returns a const reference to the path structure + /// storing the found cycle. + /// + /// \pre \ref run() or \ref findCycle() must be called before using + /// this function. + const Path& cycle() const { + return *_cycle_path; + } + + ///@} + + private: + + // Initialize + void init() { + if (!_cycle_path) { + _local_path = true; + _cycle_path = new Path; + } + _queue.resize(countNodes(_gr)); + _best_found = false; + _best_cost = 0; + _best_size = 1; + _cycle_path->clear(); + } + + // Find strongly connected components and initialize _comp_nodes + // and _in_arcs + void findComponents() { + _comp_num = stronglyConnectedComponents(_gr, _comp); + _comp_nodes.resize(_comp_num); + if (_comp_num == 1) { + _comp_nodes[0].clear(); + for (NodeIt n(_gr); n != INVALID; ++n) { + _comp_nodes[0].push_back(n); + _in_arcs[n].clear(); + for (InArcIt a(_gr, n); a != INVALID; ++a) { + _in_arcs[n].push_back(a); + } + } + } else { + for (int i = 0; i < _comp_num; ++i) + _comp_nodes[i].clear(); + for (NodeIt n(_gr); n != INVALID; ++n) { + int k = _comp[n]; + _comp_nodes[k].push_back(n); + _in_arcs[n].clear(); + for (InArcIt a(_gr, n); a != INVALID; ++a) { + if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a); + } + } + } + } + + // Build the policy graph in the given strongly connected component + // (the out-degree of every node is 1) + bool buildPolicyGraph(int comp) { + _nodes = &(_comp_nodes[comp]); + if (_nodes->size() < 1 || + (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) { + return false; + } + for (int i = 0; i < int(_nodes->size()); ++i) { + _dist[(*_nodes)[i]] = INF; + } + Node u, v; + Arc e; + for (int i = 0; i < int(_nodes->size()); ++i) { + v = (*_nodes)[i]; + for (int j = 0; j < int(_in_arcs[v].size()); ++j) { + e = _in_arcs[v][j]; + u = _gr.source(e); + if (_cost[e] < _dist[u]) { + _dist[u] = _cost[e]; + _policy[u] = e; + } + } + } + return true; + } + + // Find the minimum mean cycle in the policy graph + void findPolicyCycle() { + for (int i = 0; i < int(_nodes->size()); ++i) { + _level[(*_nodes)[i]] = -1; + } + LargeCost ccost; + int csize; + Node u, v; + _curr_found = false; + for (int i = 0; i < int(_nodes->size()); ++i) { + u = (*_nodes)[i]; + if (_level[u] >= 0) continue; + for (; _level[u] < 0; u = _gr.target(_policy[u])) { + _level[u] = i; + } + if (_level[u] == i) { + // A cycle is found + ccost = _cost[_policy[u]]; + csize = 1; + for (v = u; (v = _gr.target(_policy[v])) != u; ) { + ccost += _cost[_policy[v]]; + ++csize; + } + if ( !_curr_found || + (ccost * _curr_size < _curr_cost * csize) ) { + _curr_found = true; + _curr_cost = ccost; + _curr_size = csize; + _curr_node = u; + } + } + } + } + + // Contract the policy graph and compute node distances + bool computeNodeDistances() { + // Find the component of the main cycle and compute node distances + // using reverse BFS + for (int i = 0; i < int(_nodes->size()); ++i) { + _reached[(*_nodes)[i]] = false; + } + _qfront = _qback = 0; + _queue[0] = _curr_node; + _reached[_curr_node] = true; + _dist[_curr_node] = 0; + Node u, v; + Arc e; + while (_qfront <= _qback) { + v = _queue[_qfront++]; + for (int j = 0; j < int(_in_arcs[v].size()); ++j) { + e = _in_arcs[v][j]; + u = _gr.source(e); + if (_policy[u] == e && !_reached[u]) { + _reached[u] = true; + _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost; + _queue[++_qback] = u; + } + } + } + + // Connect all other nodes to this component and compute node + // distances using reverse BFS + _qfront = 0; + while (_qback < int(_nodes->size())-1) { + v = _queue[_qfront++]; + for (int j = 0; j < int(_in_arcs[v].size()); ++j) { + e = _in_arcs[v][j]; + u = _gr.source(e); + if (!_reached[u]) { + _reached[u] = true; + _policy[u] = e; + _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost; + _queue[++_qback] = u; + } + } + } + + // Improve node distances + bool improved = false; + for (int i = 0; i < int(_nodes->size()); ++i) { + v = (*_nodes)[i]; + for (int j = 0; j < int(_in_arcs[v].size()); ++j) { + e = _in_arcs[v][j]; + u = _gr.source(e); + LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost; + if (_tolerance.less(delta, _dist[u])) { + _dist[u] = delta; + _policy[u] = e; + improved = true; + } + } + } + return improved; + } + + }; //class HowardMmc + + ///@} + +} //namespace lemon + +#endif //LEMON_HOWARD_MMC_H diff --git a/lemon/lemon/hypercube_graph.h b/lemon/lemon/hypercube_graph.h new file mode 100644 index 0000000..2cf37ad --- /dev/null +++ b/lemon/lemon/hypercube_graph.h @@ -0,0 +1,459 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef HYPERCUBE_GRAPH_H +#define HYPERCUBE_GRAPH_H + +#include +#include +#include +#include + +///\ingroup graphs +///\file +///\brief HypercubeGraph class. + +namespace lemon { + + class HypercubeGraphBase { + + public: + + typedef HypercubeGraphBase Graph; + + class Node; + class Edge; + class Arc; + + public: + + HypercubeGraphBase() {} + + protected: + + void construct(int dim) { + LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1."); + _dim = dim; + _node_num = 1 << dim; + _edge_num = dim * (1 << (dim-1)); + } + + public: + + typedef True NodeNumTag; + typedef True EdgeNumTag; + typedef True ArcNumTag; + + int nodeNum() const { return _node_num; } + int edgeNum() const { return _edge_num; } + int arcNum() const { return 2 * _edge_num; } + + int maxNodeId() const { return _node_num - 1; } + int maxEdgeId() const { return _edge_num - 1; } + int maxArcId() const { return 2 * _edge_num - 1; } + + static Node nodeFromId(int id) { return Node(id); } + static Edge edgeFromId(int id) { return Edge(id); } + static Arc arcFromId(int id) { return Arc(id); } + + static int id(Node node) { return node._id; } + static int id(Edge edge) { return edge._id; } + static int id(Arc arc) { return arc._id; } + + Node u(Edge edge) const { + int base = edge._id & ((1 << (_dim-1)) - 1); + int k = edge._id >> (_dim-1); + return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)); + } + + Node v(Edge edge) const { + int base = edge._id & ((1 << (_dim-1)) - 1); + int k = edge._id >> (_dim-1); + return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k); + } + + Node source(Arc arc) const { + return (arc._id & 1) == 1 ? u(arc) : v(arc); + } + + Node target(Arc arc) const { + return (arc._id & 1) == 1 ? v(arc) : u(arc); + } + + typedef True FindEdgeTag; + typedef True FindArcTag; + + Edge findEdge(Node u, Node v, Edge prev = INVALID) const { + if (prev != INVALID) return INVALID; + int d = u._id ^ v._id; + int k = 0; + if (d == 0) return INVALID; + for ( ; (d & 1) == 0; d >>= 1) ++k; + if (d >> 1 != 0) return INVALID; + return (k << (_dim-1)) | ((u._id >> (k+1)) << k) | + (u._id & ((1 << k) - 1)); + } + + Arc findArc(Node u, Node v, Arc prev = INVALID) const { + Edge edge = findEdge(u, v, prev); + if (edge == INVALID) return INVALID; + int k = edge._id >> (_dim-1); + return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1; + } + + class Node { + friend class HypercubeGraphBase; + + protected: + int _id; + Node(int id) : _id(id) {} + public: + Node() {} + Node (Invalid) : _id(-1) {} + bool operator==(const Node node) const {return _id == node._id;} + bool operator!=(const Node node) const {return _id != node._id;} + bool operator<(const Node node) const {return _id < node._id;} + }; + + class Edge { + friend class HypercubeGraphBase; + friend class Arc; + + protected: + int _id; + + Edge(int id) : _id(id) {} + + public: + Edge() {} + Edge (Invalid) : _id(-1) {} + bool operator==(const Edge edge) const {return _id == edge._id;} + bool operator!=(const Edge edge) const {return _id != edge._id;} + bool operator<(const Edge edge) const {return _id < edge._id;} + }; + + class Arc { + friend class HypercubeGraphBase; + + protected: + int _id; + + Arc(int id) : _id(id) {} + + public: + Arc() {} + Arc (Invalid) : _id(-1) {} + operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; } + bool operator==(const Arc arc) const {return _id == arc._id;} + bool operator!=(const Arc arc) const {return _id != arc._id;} + bool operator<(const Arc arc) const {return _id < arc._id;} + }; + + void first(Node& node) const { + node._id = _node_num - 1; + } + + static void next(Node& node) { + --node._id; + } + + void first(Edge& edge) const { + edge._id = _edge_num - 1; + } + + static void next(Edge& edge) { + --edge._id; + } + + void first(Arc& arc) const { + arc._id = 2 * _edge_num - 1; + } + + static void next(Arc& arc) { + --arc._id; + } + + void firstInc(Edge& edge, bool& dir, const Node& node) const { + edge._id = node._id >> 1; + dir = (node._id & 1) == 0; + } + + void nextInc(Edge& edge, bool& dir) const { + Node n = dir ? u(edge) : v(edge); + int k = (edge._id >> (_dim-1)) + 1; + if (k < _dim) { + edge._id = (k << (_dim-1)) | + ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1)); + dir = ((n._id >> k) & 1) == 0; + } else { + edge._id = -1; + dir = true; + } + } + + void firstOut(Arc& arc, const Node& node) const { + arc._id = ((node._id >> 1) << 1) | (~node._id & 1); + } + + void nextOut(Arc& arc) const { + Node n = (arc._id & 1) == 1 ? u(arc) : v(arc); + int k = (arc._id >> _dim) + 1; + if (k < _dim) { + arc._id = (k << (_dim-1)) | + ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1)); + arc._id = (arc._id << 1) | (~(n._id >> k) & 1); + } else { + arc._id = -1; + } + } + + void firstIn(Arc& arc, const Node& node) const { + arc._id = ((node._id >> 1) << 1) | (node._id & 1); + } + + void nextIn(Arc& arc) const { + Node n = (arc._id & 1) == 1 ? v(arc) : u(arc); + int k = (arc._id >> _dim) + 1; + if (k < _dim) { + arc._id = (k << (_dim-1)) | + ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1)); + arc._id = (arc._id << 1) | ((n._id >> k) & 1); + } else { + arc._id = -1; + } + } + + static bool direction(Arc arc) { + return (arc._id & 1) == 1; + } + + static Arc direct(Edge edge, bool dir) { + return Arc((edge._id << 1) | (dir ? 1 : 0)); + } + + int dimension() const { + return _dim; + } + + bool projection(Node node, int n) const { + return static_cast(node._id & (1 << n)); + } + + int dimension(Edge edge) const { + return edge._id >> (_dim-1); + } + + int dimension(Arc arc) const { + return arc._id >> _dim; + } + + static int index(Node node) { + return node._id; + } + + Node operator()(int ix) const { + return Node(ix); + } + + private: + int _dim; + int _node_num, _edge_num; + }; + + + typedef GraphExtender ExtendedHypercubeGraphBase; + + /// \ingroup graphs + /// + /// \brief Hypercube graph class + /// + /// HypercubeGraph implements a special graph type. The nodes of the + /// graph are indexed with integers having at most \c dim binary digits. + /// Two nodes are connected in the graph if and only if their indices + /// differ only on one position in the binary form. + /// This class is completely static and it needs constant memory space. + /// Thus you can neither add nor delete nodes or edges, however, + /// the structure can be resized using resize(). + /// + /// This type fully conforms to the \ref concepts::Graph "Graph concept". + /// Most of its member functions and nested classes are documented + /// only in the concept class. + /// + /// This class provides constant time counting for nodes, edges and arcs. + /// + /// \note The type of the indices is chosen to \c int for efficiency + /// reasons. Thus the maximum dimension of this implementation is 26 + /// (assuming that the size of \c int is 32 bit). + class HypercubeGraph : public ExtendedHypercubeGraphBase { + typedef ExtendedHypercubeGraphBase Parent; + + public: + + /// \brief Constructs a hypercube graph with \c dim dimensions. + /// + /// Constructs a hypercube graph with \c dim dimensions. + HypercubeGraph(int dim) { construct(dim); } + + /// \brief Resizes the graph + /// + /// This function resizes the graph. It fully destroys and + /// rebuilds the structure, therefore the maps of the graph will be + /// reallocated automatically and the previous values will be lost. + void resize(int dim) { + Parent::notifier(Arc()).clear(); + Parent::notifier(Edge()).clear(); + Parent::notifier(Node()).clear(); + construct(dim); + Parent::notifier(Node()).build(); + Parent::notifier(Edge()).build(); + Parent::notifier(Arc()).build(); + } + + /// \brief The number of dimensions. + /// + /// Gives back the number of dimensions. + int dimension() const { + return Parent::dimension(); + } + + /// \brief Returns \c true if the n'th bit of the node is one. + /// + /// Returns \c true if the n'th bit of the node is one. + bool projection(Node node, int n) const { + return Parent::projection(node, n); + } + + /// \brief The dimension id of an edge. + /// + /// Gives back the dimension id of the given edge. + /// It is in the range [0..dim-1]. + int dimension(Edge edge) const { + return Parent::dimension(edge); + } + + /// \brief The dimension id of an arc. + /// + /// Gives back the dimension id of the given arc. + /// It is in the range [0..dim-1]. + int dimension(Arc arc) const { + return Parent::dimension(arc); + } + + /// \brief The index of a node. + /// + /// Gives back the index of the given node. + /// The lower bits of the integer describes the node. + static int index(Node node) { + return Parent::index(node); + } + + /// \brief Gives back a node by its index. + /// + /// Gives back a node by its index. + Node operator()(int ix) const { + return Parent::operator()(ix); + } + + /// \brief Number of nodes. + int nodeNum() const { return Parent::nodeNum(); } + /// \brief Number of edges. + int edgeNum() const { return Parent::edgeNum(); } + /// \brief Number of arcs. + int arcNum() const { return Parent::arcNum(); } + + /// \brief Linear combination map. + /// + /// This map makes possible to give back a linear combination + /// for each node. It works like the \c std::accumulate function, + /// so it accumulates the \c bf binary function with the \c fv first + /// value. The map accumulates only on that positions (dimensions) + /// where the index of the node is one. The values that have to be + /// accumulated should be given by the \c begin and \c end iterators + /// and the length of this range should be equal to the dimension + /// number of the graph. + /// + ///\code + /// const int DIM = 3; + /// HypercubeGraph graph(DIM); + /// dim2::Point base[DIM]; + /// for (int k = 0; k < DIM; ++k) { + /// base[k].x = rnd(); + /// base[k].y = rnd(); + /// } + /// HypercubeGraph::HyperMap > + /// pos(graph, base, base + DIM, dim2::Point(0.0, 0.0)); + ///\endcode + /// + /// \see HypercubeGraph + template > + class HyperMap { + public: + + /// \brief The key type of the map + typedef Node Key; + /// \brief The value type of the map + typedef T Value; + + /// \brief Constructor for HyperMap. + /// + /// Construct a HyperMap for the given graph. The values that have + /// to be accumulated should be given by the \c begin and \c end + /// iterators and the length of this range should be equal to the + /// dimension number of the graph. + /// + /// This map accumulates the \c bf binary function with the \c fv + /// first value on that positions (dimensions) where the index of + /// the node is one. + template + HyperMap(const Graph& graph, It begin, It end, + T fv = 0, const BF& bf = BF()) + : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf) + { + LEMON_ASSERT(_values.size() == graph.dimension(), + "Wrong size of range"); + } + + /// \brief The partial accumulated value. + /// + /// Gives back the partial accumulated value. + Value operator[](const Key& k) const { + Value val = _first_value; + int id = _graph.index(k); + int n = 0; + while (id != 0) { + if (id & 1) { + val = _bin_func(val, _values[n]); + } + id >>= 1; + ++n; + } + return val; + } + + private: + const Graph& _graph; + std::vector _values; + T _first_value; + BF _bin_func; + }; + + }; + +} + +#endif diff --git a/lemon/lemon/karp_mmc.h b/lemon/lemon/karp_mmc.h new file mode 100644 index 0000000..9effebe --- /dev/null +++ b/lemon/lemon/karp_mmc.h @@ -0,0 +1,590 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_KARP_MMC_H +#define LEMON_KARP_MMC_H + +/// \ingroup min_mean_cycle +/// +/// \file +/// \brief Karp's algorithm for finding a minimum mean cycle. + +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \brief Default traits class of KarpMmc class. + /// + /// Default traits class of KarpMmc class. + /// \tparam GR The type of the digraph. + /// \tparam CM The type of the cost map. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. +#ifdef DOXYGEN + template +#else + template ::is_integer> +#endif + struct KarpMmcDefaultTraits + { + /// The type of the digraph + typedef GR Digraph; + /// The type of the cost map + typedef CM CostMap; + /// The type of the arc costs + typedef typename CostMap::Value Cost; + + /// \brief The large cost type used for internal computations + /// + /// The large cost type used for internal computations. + /// It is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + /// \c Cost must be convertible to \c LargeCost. + typedef double LargeCost; + + /// The tolerance type used for internal computations + typedef lemon::Tolerance Tolerance; + + /// \brief The path type of the found cycles + /// + /// The path type of the found cycles. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addFront() function. + typedef lemon::Path Path; + }; + + // Default traits class for integer cost types + template + struct KarpMmcDefaultTraits + { + typedef GR Digraph; + typedef CM CostMap; + typedef typename CostMap::Value Cost; +#ifdef LEMON_HAVE_LONG_LONG + typedef long long LargeCost; +#else + typedef long LargeCost; +#endif + typedef lemon::Tolerance Tolerance; + typedef lemon::Path Path; + }; + + + /// \addtogroup min_mean_cycle + /// @{ + + /// \brief Implementation of Karp's algorithm for finding a minimum + /// mean cycle. + /// + /// This class implements Karp's algorithm for finding a directed + /// cycle of minimum mean cost in a digraph + /// \ref amo93networkflows, \ref dasdan98minmeancycle. + /// It runs in time O(ne) and uses space O(n2+e). + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// \tparam CM The type of the cost map. The default + /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap". + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref KarpMmcDefaultTraits + /// "KarpMmcDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template < typename GR, + typename CM = typename GR::template ArcMap, + typename TR = KarpMmcDefaultTraits > +#endif + class KarpMmc + { + public: + + /// The type of the digraph + typedef typename TR::Digraph Digraph; + /// The type of the cost map + typedef typename TR::CostMap CostMap; + /// The type of the arc costs + typedef typename TR::Cost Cost; + + /// \brief The large cost type + /// + /// The large cost type used for internal computations. + /// By default, it is \c long \c long if the \c Cost type is integer, + /// otherwise it is \c double. + typedef typename TR::LargeCost LargeCost; + + /// The tolerance type + typedef typename TR::Tolerance Tolerance; + + /// \brief The path type of the found cycles + /// + /// The path type of the found cycles. + /// Using the \ref KarpMmcDefaultTraits "default traits class", + /// it is \ref lemon::Path "Path". + typedef typename TR::Path Path; + + /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm + typedef TR Traits; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + // Data sturcture for path data + struct PathData + { + LargeCost dist; + Arc pred; + PathData(LargeCost d, Arc p = INVALID) : + dist(d), pred(p) {} + }; + + typedef typename Digraph::template NodeMap > + PathDataNodeMap; + + private: + + // The digraph the algorithm runs on + const Digraph &_gr; + // The cost of the arcs + const CostMap &_cost; + + // Data for storing the strongly connected components + int _comp_num; + typename Digraph::template NodeMap _comp; + std::vector > _comp_nodes; + std::vector* _nodes; + typename Digraph::template NodeMap > _out_arcs; + + // Data for the found cycle + LargeCost _cycle_cost; + int _cycle_size; + Node _cycle_node; + + Path *_cycle_path; + bool _local_path; + + // Node map for storing path data + PathDataNodeMap _data; + // The processed nodes in the last round + std::vector _process; + + Tolerance _tolerance; + + // Infinite constant + const LargeCost INF; + + public: + + /// \name Named Template Parameters + /// @{ + + template + struct SetLargeCostTraits : public Traits { + typedef T LargeCost; + typedef lemon::Tolerance Tolerance; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c LargeCost type. + /// + /// \ref named-templ-param "Named parameter" for setting \c LargeCost + /// type. It is used for internal computations in the algorithm. + template + struct SetLargeCost + : public KarpMmc > { + typedef KarpMmc > Create; + }; + + template + struct SetPathTraits : public Traits { + typedef T Path; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c %Path type. + /// + /// \ref named-templ-param "Named parameter" for setting the \c %Path + /// type of the found cycles. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addFront() function. + template + struct SetPath + : public KarpMmc > { + typedef KarpMmc > Create; + }; + + /// @} + + protected: + + KarpMmc() {} + + public: + + /// \brief Constructor. + /// + /// The constructor of the class. + /// + /// \param digraph The digraph the algorithm runs on. + /// \param cost The costs of the arcs. + KarpMmc( const Digraph &digraph, + const CostMap &cost ) : + _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph), + _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID), + _cycle_path(NULL), _local_path(false), _data(digraph), + INF(std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : + std::numeric_limits::max()) + {} + + /// Destructor. + ~KarpMmc() { + if (_local_path) delete _cycle_path; + } + + /// \brief Set the path structure for storing the found cycle. + /// + /// This function sets an external path structure for storing the + /// found cycle. + /// + /// If you don't call this function before calling \ref run() or + /// \ref findCycleMean(), it will allocate a local \ref Path "path" + /// structure. The destuctor deallocates this automatically + /// allocated object, of course. + /// + /// \note The algorithm calls only the \ref lemon::Path::addFront() + /// "addFront()" function of the given path structure. + /// + /// \return (*this) + KarpMmc& cycle(Path &path) { + if (_local_path) { + delete _cycle_path; + _local_path = false; + } + _cycle_path = &path; + return *this; + } + + /// \brief Set the tolerance used by the algorithm. + /// + /// This function sets the tolerance object used by the algorithm. + /// + /// \return (*this) + KarpMmc& tolerance(const Tolerance& tolerance) { + _tolerance = tolerance; + return *this; + } + + /// \brief Return a const reference to the tolerance. + /// + /// This function returns a const reference to the tolerance object + /// used by the algorithm. + const Tolerance& tolerance() const { + return _tolerance; + } + + /// \name Execution control + /// The simplest way to execute the algorithm is to call the \ref run() + /// function.\n + /// If you only need the minimum mean cost, you may call + /// \ref findCycleMean(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// It can be called more than once (e.g. if the underlying digraph + /// and/or the arc costs have been modified). + /// + /// \return \c true if a directed cycle exists in the digraph. + /// + /// \note mmc.run() is just a shortcut of the following code. + /// \code + /// return mmc.findCycleMean() && mmc.findCycle(); + /// \endcode + bool run() { + return findCycleMean() && findCycle(); + } + + /// \brief Find the minimum cycle mean. + /// + /// This function finds the minimum mean cost of the directed + /// cycles in the digraph. + /// + /// \return \c true if a directed cycle exists in the digraph. + bool findCycleMean() { + // Initialization and find strongly connected components + init(); + findComponents(); + + // Find the minimum cycle mean in the components + for (int comp = 0; comp < _comp_num; ++comp) { + if (!initComponent(comp)) continue; + processRounds(); + updateMinMean(); + } + return (_cycle_node != INVALID); + } + + /// \brief Find a minimum mean directed cycle. + /// + /// This function finds a directed cycle of minimum mean cost + /// in the digraph using the data computed by findCycleMean(). + /// + /// \return \c true if a directed cycle exists in the digraph. + /// + /// \pre \ref findCycleMean() must be called before using this function. + bool findCycle() { + if (_cycle_node == INVALID) return false; + IntNodeMap reached(_gr, -1); + int r = _data[_cycle_node].size(); + Node u = _cycle_node; + while (reached[u] < 0) { + reached[u] = --r; + u = _gr.source(_data[u][r].pred); + } + r = reached[u]; + Arc e = _data[u][r].pred; + _cycle_path->addFront(e); + _cycle_cost = _cost[e]; + _cycle_size = 1; + Node v; + while ((v = _gr.source(e)) != u) { + e = _data[v][--r].pred; + _cycle_path->addFront(e); + _cycle_cost += _cost[e]; + ++_cycle_size; + } + return true; + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions.\n + /// The algorithm should be executed before using them. + + /// @{ + + /// \brief Return the total cost of the found cycle. + /// + /// This function returns the total cost of the found cycle. + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + Cost cycleCost() const { + return static_cast(_cycle_cost); + } + + /// \brief Return the number of arcs on the found cycle. + /// + /// This function returns the number of arcs on the found cycle. + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + int cycleSize() const { + return _cycle_size; + } + + /// \brief Return the mean cost of the found cycle. + /// + /// This function returns the mean cost of the found cycle. + /// + /// \note alg.cycleMean() is just a shortcut of the + /// following code. + /// \code + /// return static_cast(alg.cycleCost()) / alg.cycleSize(); + /// \endcode + /// + /// \pre \ref run() or \ref findCycleMean() must be called before + /// using this function. + double cycleMean() const { + return static_cast(_cycle_cost) / _cycle_size; + } + + /// \brief Return the found cycle. + /// + /// This function returns a const reference to the path structure + /// storing the found cycle. + /// + /// \pre \ref run() or \ref findCycle() must be called before using + /// this function. + const Path& cycle() const { + return *_cycle_path; + } + + ///@} + + private: + + // Initialization + void init() { + if (!_cycle_path) { + _local_path = true; + _cycle_path = new Path; + } + _cycle_path->clear(); + _cycle_cost = 0; + _cycle_size = 1; + _cycle_node = INVALID; + for (NodeIt u(_gr); u != INVALID; ++u) + _data[u].clear(); + } + + // Find strongly connected components and initialize _comp_nodes + // and _out_arcs + void findComponents() { + _comp_num = stronglyConnectedComponents(_gr, _comp); + _comp_nodes.resize(_comp_num); + if (_comp_num == 1) { + _comp_nodes[0].clear(); + for (NodeIt n(_gr); n != INVALID; ++n) { + _comp_nodes[0].push_back(n); + _out_arcs[n].clear(); + for (OutArcIt a(_gr, n); a != INVALID; ++a) { + _out_arcs[n].push_back(a); + } + } + } else { + for (int i = 0; i < _comp_num; ++i) + _comp_nodes[i].clear(); + for (NodeIt n(_gr); n != INVALID; ++n) { + int k = _comp[n]; + _comp_nodes[k].push_back(n); + _out_arcs[n].clear(); + for (OutArcIt a(_gr, n); a != INVALID; ++a) { + if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a); + } + } + } + } + + // Initialize path data for the current component + bool initComponent(int comp) { + _nodes = &(_comp_nodes[comp]); + int n = _nodes->size(); + if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) { + return false; + } + for (int i = 0; i < n; ++i) { + _data[(*_nodes)[i]].resize(n + 1, PathData(INF)); + } + return true; + } + + // Process all rounds of computing path data for the current component. + // _data[v][k] is the cost of a shortest directed walk from the root + // node to node v containing exactly k arcs. + void processRounds() { + Node start = (*_nodes)[0]; + _data[start][0] = PathData(0); + _process.clear(); + _process.push_back(start); + + int k, n = _nodes->size(); + for (k = 1; k <= n && int(_process.size()) < n; ++k) { + processNextBuildRound(k); + } + for ( ; k <= n; ++k) { + processNextFullRound(k); + } + } + + // Process one round and rebuild _process + void processNextBuildRound(int k) { + std::vector next; + Node u, v; + Arc e; + LargeCost d; + for (int i = 0; i < int(_process.size()); ++i) { + u = _process[i]; + for (int j = 0; j < int(_out_arcs[u].size()); ++j) { + e = _out_arcs[u][j]; + v = _gr.target(e); + d = _data[u][k-1].dist + _cost[e]; + if (_tolerance.less(d, _data[v][k].dist)) { + if (_data[v][k].dist == INF) next.push_back(v); + _data[v][k] = PathData(d, e); + } + } + } + _process.swap(next); + } + + // Process one round using _nodes instead of _process + void processNextFullRound(int k) { + Node u, v; + Arc e; + LargeCost d; + for (int i = 0; i < int(_nodes->size()); ++i) { + u = (*_nodes)[i]; + for (int j = 0; j < int(_out_arcs[u].size()); ++j) { + e = _out_arcs[u][j]; + v = _gr.target(e); + d = _data[u][k-1].dist + _cost[e]; + if (_tolerance.less(d, _data[v][k].dist)) { + _data[v][k] = PathData(d, e); + } + } + } + } + + // Update the minimum cycle mean + void updateMinMean() { + int n = _nodes->size(); + for (int i = 0; i < n; ++i) { + Node u = (*_nodes)[i]; + if (_data[u][n].dist == INF) continue; + LargeCost cost, max_cost = 0; + int size, max_size = 1; + bool found_curr = false; + for (int k = 0; k < n; ++k) { + if (_data[u][k].dist == INF) continue; + cost = _data[u][n].dist - _data[u][k].dist; + size = n - k; + if (!found_curr || cost * max_size > max_cost * size) { + found_curr = true; + max_cost = cost; + max_size = size; + } + } + if ( found_curr && (_cycle_node == INVALID || + max_cost * _cycle_size < _cycle_cost * max_size) ) { + _cycle_cost = max_cost; + _cycle_size = max_size; + _cycle_node = u; + } + } + } + + }; //class KarpMmc + + ///@} + +} //namespace lemon + +#endif //LEMON_KARP_MMC_H diff --git a/lemon/lemon/kruskal.h b/lemon/lemon/kruskal.h new file mode 100644 index 0000000..f184ad1 --- /dev/null +++ b/lemon/lemon/kruskal.h @@ -0,0 +1,327 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_KRUSKAL_H +#define LEMON_KRUSKAL_H + +#include +#include +#include +#include + +#include +#include + +///\ingroup spantree +///\file +///\brief Kruskal's algorithm to compute a minimum cost spanning tree +/// +///Kruskal's algorithm to compute a minimum cost spanning tree. +/// + +namespace lemon { + + namespace _kruskal_bits { + + // Kruskal for directed graphs. + + template + typename disable_if, + typename In::value_type::second_type >::type + kruskal(const Digraph& digraph, const In& in, Out& out,dummy<0> = 0) { + typedef typename In::value_type::second_type Value; + typedef typename Digraph::template NodeMap IndexMap; + typedef typename Digraph::Node Node; + + IndexMap index(digraph); + UnionFind uf(index); + for (typename Digraph::NodeIt it(digraph); it != INVALID; ++it) { + uf.insert(it); + } + + Value tree_value = 0; + for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) { + if (uf.join(digraph.target(it->first),digraph.source(it->first))) { + out.set(it->first, true); + tree_value += it->second; + } + else { + out.set(it->first, false); + } + } + return tree_value; + } + + // Kruskal for undirected graphs. + + template + typename enable_if, + typename In::value_type::second_type >::type + kruskal(const Graph& graph, const In& in, Out& out,dummy<1> = 1) { + typedef typename In::value_type::second_type Value; + typedef typename Graph::template NodeMap IndexMap; + typedef typename Graph::Node Node; + + IndexMap index(graph); + UnionFind uf(index); + for (typename Graph::NodeIt it(graph); it != INVALID; ++it) { + uf.insert(it); + } + + Value tree_value = 0; + for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) { + if (uf.join(graph.u(it->first),graph.v(it->first))) { + out.set(it->first, true); + tree_value += it->second; + } + else { + out.set(it->first, false); + } + } + return tree_value; + } + + + template + struct PairComp { + typedef typename Sequence::value_type Value; + bool operator()(const Value& left, const Value& right) { + return left.second < right.second; + } + }; + + template + struct SequenceInputIndicator { + static const bool value = false; + }; + + template + struct SequenceInputIndicator::type> { + static const bool value = true; + }; + + template + struct MapInputIndicator { + static const bool value = false; + }; + + template + struct MapInputIndicator::type> { + static const bool value = true; + }; + + template + struct SequenceOutputIndicator { + static const bool value = false; + }; + + template + struct SequenceOutputIndicator::type> { + static const bool value = true; + }; + + template + struct MapOutputIndicator { + static const bool value = false; + }; + + template + struct MapOutputIndicator::type> { + static const bool value = true; + }; + + template + struct KruskalValueSelector {}; + + template + struct KruskalValueSelector, void>::type> + { + typedef typename In::value_type::second_type Value; + }; + + template + struct KruskalValueSelector, void>::type> + { + typedef typename In::Value Value; + }; + + template + struct KruskalInputSelector {}; + + template + struct KruskalOutputSelector {}; + + template + struct KruskalInputSelector, void>::type > + { + typedef typename In::value_type::second_type Value; + + static Value kruskal(const Graph& graph, const In& in, Out& out) { + return KruskalOutputSelector:: + kruskal(graph, in, out); + } + + }; + + template + struct KruskalInputSelector, void>::type > + { + typedef typename In::Value Value; + static Value kruskal(const Graph& graph, const In& in, Out& out) { + typedef typename In::Key MapArc; + typedef typename In::Value Value; + typedef typename ItemSetTraits::ItemIt MapArcIt; + typedef std::vector > Sequence; + Sequence seq; + + for (MapArcIt it(graph); it != INVALID; ++it) { + seq.push_back(std::make_pair(it, in[it])); + } + + std::sort(seq.begin(), seq.end(), PairComp()); + return KruskalOutputSelector:: + kruskal(graph, seq, out); + } + }; + + template + struct RemoveConst { + typedef T type; + }; + + template + struct RemoveConst { + typedef T type; + }; + + template + struct KruskalOutputSelector, void>::type > + { + typedef typename In::value_type::second_type Value; + + static Value kruskal(const Graph& graph, const In& in, Out& out) { + typedef LoggerBoolMap::type> Map; + Map map(out); + return _kruskal_bits::kruskal(graph, in, map); + } + + }; + + template + struct KruskalOutputSelector, void>::type > + { + typedef typename In::value_type::second_type Value; + + static Value kruskal(const Graph& graph, const In& in, Out& out) { + return _kruskal_bits::kruskal(graph, in, out); + } + }; + + } + + /// \ingroup spantree + /// + /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of + /// a graph. + /// + /// This function runs Kruskal's algorithm to find a minimum cost + /// spanning tree of a graph. + /// Due to some C++ hacking, it accepts various input and output types. + /// + /// \param g The graph the algorithm runs on. + /// It can be either \ref concepts::Digraph "directed" or + /// \ref concepts::Graph "undirected". + /// If the graph is directed, the algorithm consider it to be + /// undirected by disregarding the direction of the arcs. + /// + /// \param in This object is used to describe the arc/edge costs. + /// It can be one of the following choices. + /// - An STL compatible 'Forward Container' with + /// std::pair or + /// std::pair as its value_type, where + /// \c C is the type of the costs. The pairs indicates the arcs/edges + /// along with the assigned cost. They must be in a + /// cost-ascending order. + /// - Any readable arc/edge map. The values of the map indicate the + /// arc/edge costs. + /// + /// \retval out Here we also have a choice. + /// - It can be a writable arc/edge map with \c bool value type. After + /// running the algorithm it will contain the found minimum cost spanning + /// tree: the value of an arc/edge will be set to \c true if it belongs + /// to the tree, otherwise it will be set to \c false. The value of + /// each arc/edge will be set exactly once. + /// - It can also be an iteraror of an STL Container with + /// GR::Arc or GR::Edge as its + /// value_type. The algorithm copies the elements of the + /// found tree into this sequence. For example, if we know that the + /// spanning tree of the graph \c g has say 53 arcs, then we can + /// put its arcs into an STL vector \c tree with a code like this. + ///\code + /// std::vector tree(53); + /// kruskal(g,cost,tree.begin()); + ///\endcode + /// Or if we don't know in advance the size of the tree, we can + /// write this. + ///\code + /// std::vector tree; + /// kruskal(g,cost,std::back_inserter(tree)); + ///\endcode + /// + /// \return The total cost of the found spanning tree. + /// + /// \note If the input graph is not (weakly) connected, a spanning + /// forest is calculated instead of a spanning tree. + +#ifdef DOXYGEN + template + Value kruskal(const Graph& g, const In& in, Out& out) +#else + template + inline typename _kruskal_bits::KruskalValueSelector::Value + kruskal(const Graph& graph, const In& in, Out& out) +#endif + { + return _kruskal_bits::KruskalInputSelector:: + kruskal(graph, in, out); + } + + + template + inline typename _kruskal_bits::KruskalValueSelector::Value + kruskal(const Graph& graph, const In& in, const Out& out) + { + return _kruskal_bits::KruskalInputSelector:: + kruskal(graph, in, out); + } + +} //namespace lemon + +#endif //LEMON_KRUSKAL_H diff --git a/lemon/lemon/lemon.pc b/lemon/lemon/lemon.pc new file mode 100644 index 0000000..1ed75ae --- /dev/null +++ b/lemon/lemon/lemon.pc @@ -0,0 +1,10 @@ +prefix=/usr/local +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include + +Name: LEMON +Description: Library for Efficient Modeling and Optimization in Networks +Version: 1.2.3 +Libs: -L${libdir} -lemon +Cflags: -I${includedir} diff --git a/lemon/lemon/lemon.pc.cmake b/lemon/lemon/lemon.pc.cmake new file mode 100644 index 0000000..e85bf76 --- /dev/null +++ b/lemon/lemon/lemon.pc.cmake @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@/bin +libdir=@CMAKE_INSTALL_PREFIX@/lib +includedir=@CMAKE_INSTALL_PREFIX@/include + +Name: @PROJECT_NAME@ +Description: Library for Efficient Modeling and Optimization in Networks +Version: @PROJECT_VERSION@ +Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@ +Cflags: -I${includedir} diff --git a/lemon/lemon/lemon.pc.in b/lemon/lemon/lemon.pc.in new file mode 100644 index 0000000..ae3735e --- /dev/null +++ b/lemon/lemon/lemon.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: @PACKAGE_NAME@ +Description: Library for Efficient Modeling and Optimization in Networks +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@ +Cflags: -I${includedir} diff --git a/lemon/lemon/lgf_reader.h b/lemon/lemon/lgf_reader.h new file mode 100644 index 0000000..80762cc --- /dev/null +++ b/lemon/lemon/lgf_reader.h @@ -0,0 +1,2750 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup lemon_io +///\file +///\brief \ref lgf-format "LEMON Graph Format" reader. + + +#ifndef LEMON_LGF_READER_H +#define LEMON_LGF_READER_H + +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include + +namespace lemon { + + namespace _reader_bits { + + template + struct DefaultConverter { + Value operator()(const std::string& str) { + std::istringstream is(str); + Value value; + if (!(is >> value)) { + throw FormatError("Cannot read token"); + } + + char c; + if (is >> std::ws >> c) { + throw FormatError("Remaining characters in token"); + } + return value; + } + }; + + template <> + struct DefaultConverter { + std::string operator()(const std::string& str) { + return str; + } + }; + + template + class MapStorageBase { + public: + typedef _Item Item; + + public: + MapStorageBase() {} + virtual ~MapStorageBase() {} + + virtual void set(const Item& item, const std::string& value) = 0; + + }; + + template > + class MapStorage : public MapStorageBase<_Item> { + public: + typedef _Map Map; + typedef _Converter Converter; + typedef _Item Item; + + private: + Map& _map; + Converter _converter; + + public: + MapStorage(Map& map, const Converter& converter = Converter()) + : _map(map), _converter(converter) {} + virtual ~MapStorage() {} + + virtual void set(const Item& item ,const std::string& value) { + _map.set(item, _converter(value)); + } + }; + + template > + class GraphArcMapStorage : public MapStorageBase { + public: + typedef _Map Map; + typedef _Converter Converter; + typedef _GR GR; + typedef typename GR::Edge Item; + static const bool dir = _dir; + + private: + const GR& _graph; + Map& _map; + Converter _converter; + + public: + GraphArcMapStorage(const GR& graph, Map& map, + const Converter& converter = Converter()) + : _graph(graph), _map(map), _converter(converter) {} + virtual ~GraphArcMapStorage() {} + + virtual void set(const Item& item ,const std::string& value) { + _map.set(_graph.direct(item, dir), _converter(value)); + } + }; + + class ValueStorageBase { + public: + ValueStorageBase() {} + virtual ~ValueStorageBase() {} + + virtual void set(const std::string&) = 0; + }; + + template > + class ValueStorage : public ValueStorageBase { + public: + typedef _Value Value; + typedef _Converter Converter; + + private: + Value& _value; + Converter _converter; + + public: + ValueStorage(Value& value, const Converter& converter = Converter()) + : _value(value), _converter(converter) {} + + virtual void set(const std::string& value) { + _value = _converter(value); + } + }; + + template + struct MapLookUpConverter { + const std::map& _map; + + MapLookUpConverter(const std::map& map) + : _map(map) {} + + Value operator()(const std::string& str) { + typename std::map::const_iterator it = + _map.find(str); + if (it == _map.end()) { + std::ostringstream msg; + msg << "Item not found: " << str; + throw FormatError(msg.str()); + } + return it->second; + } + }; + + template + struct GraphArcLookUpConverter { + const GR& _graph; + const std::map& _map; + + GraphArcLookUpConverter(const GR& graph, + const std::map& map) + : _graph(graph), _map(map) {} + + typename GR::Arc operator()(const std::string& str) { + if (str.empty() || (str[0] != '+' && str[0] != '-')) { + throw FormatError("Item must start with '+' or '-'"); + } + typename std::map + ::const_iterator it = _map.find(str.substr(1)); + if (it == _map.end()) { + throw FormatError("Item not found"); + } + return _graph.direct(it->second, str[0] == '+'); + } + }; + + inline bool isWhiteSpace(char c) { + return c == ' ' || c == '\t' || c == '\v' || + c == '\n' || c == '\r' || c == '\f'; + } + + inline bool isOct(char c) { + return '0' <= c && c <='7'; + } + + inline int valueOct(char c) { + LEMON_ASSERT(isOct(c), "The character is not octal."); + return c - '0'; + } + + inline bool isHex(char c) { + return ('0' <= c && c <= '9') || + ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z'); + } + + inline int valueHex(char c) { + LEMON_ASSERT(isHex(c), "The character is not hexadecimal."); + if ('0' <= c && c <= '9') return c - '0'; + if ('a' <= c && c <= 'z') return c - 'a' + 10; + return c - 'A' + 10; + } + + inline bool isIdentifierFirstChar(char c) { + return ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || c == '_'; + } + + inline bool isIdentifierChar(char c) { + return isIdentifierFirstChar(c) || + ('0' <= c && c <= '9'); + } + + inline char readEscape(std::istream& is) { + char c; + if (!is.get(c)) + throw FormatError("Escape format error"); + + switch (c) { + case '\\': + return '\\'; + case '\"': + return '\"'; + case '\'': + return '\''; + case '\?': + return '\?'; + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case 'x': + { + int code; + if (!is.get(c) || !isHex(c)) + throw FormatError("Escape format error"); + else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c); + else code = code * 16 + valueHex(c); + return code; + } + default: + { + int code; + if (!isOct(c)) + throw FormatError("Escape format error"); + else if (code = valueOct(c), !is.get(c) || !isOct(c)) + is.putback(c); + else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c)) + is.putback(c); + else code = code * 8 + valueOct(c); + return code; + } + } + } + + inline std::istream& readToken(std::istream& is, std::string& str) { + std::ostringstream os; + + char c; + is >> std::ws; + + if (!is.get(c)) + return is; + + if (c == '\"') { + while (is.get(c) && c != '\"') { + if (c == '\\') + c = readEscape(is); + os << c; + } + if (!is) + throw FormatError("Quoted format error"); + } else { + is.putback(c); + while (is.get(c) && !isWhiteSpace(c)) { + if (c == '\\') + c = readEscape(is); + os << c; + } + if (!is) { + is.clear(); + } else { + is.putback(c); + } + } + str = os.str(); + return is; + } + + class Section { + public: + virtual ~Section() {} + virtual void process(std::istream& is, int& line_num) = 0; + }; + + template + class LineSection : public Section { + private: + + Functor _functor; + + public: + + LineSection(const Functor& functor) : _functor(functor) {} + virtual ~LineSection() {} + + virtual void process(std::istream& is, int& line_num) { + char c; + std::string line; + while (is.get(c) && c != '@') { + if (c == '\n') { + ++line_num; + } else if (c == '#') { + getline(is, line); + ++line_num; + } else if (!isWhiteSpace(c)) { + is.putback(c); + getline(is, line); + _functor(line); + ++line_num; + } + } + if (is) is.putback(c); + else if (is.eof()) is.clear(); + } + }; + + template + class StreamSection : public Section { + private: + + Functor _functor; + + public: + + StreamSection(const Functor& functor) : _functor(functor) {} + virtual ~StreamSection() {} + + virtual void process(std::istream& is, int& line_num) { + _functor(is, line_num); + char c; + std::string line; + while (is.get(c) && c != '@') { + if (c == '\n') { + ++line_num; + } else if (!isWhiteSpace(c)) { + getline(is, line); + ++line_num; + } + } + if (is) is.putback(c); + else if (is.eof()) is.clear(); + } + }; + + } + + template + class DigraphReader; + + template + DigraphReader digraphReader(TDGR& digraph, std::istream& is = std::cin); + template + DigraphReader digraphReader(TDGR& digraph, const std::string& fn); + template + DigraphReader digraphReader(TDGR& digraph, const char *fn); + + /// \ingroup lemon_io + /// + /// \brief \ref lgf-format "LGF" reader for directed graphs + /// + /// This utility reads an \ref lgf-format "LGF" file. + /// + /// The reading method does a batch processing. The user creates a + /// reader object, then various reading rules can be added to the + /// reader, and eventually the reading is executed with the \c run() + /// member function. A map reading rule can be added to the reader + /// with the \c nodeMap() or \c arcMap() members. An optional + /// converter parameter can also be added as a standard functor + /// converting from \c std::string to the value type of the map. If it + /// is set, it will determine how the tokens in the file should be + /// converted to the value type of the map. If the functor is not set, + /// then a default conversion will be used. One map can be read into + /// multiple map objects at the same time. The \c attribute(), \c + /// node() and \c arc() functions are used to add attribute reading + /// rules. + /// + ///\code + /// DigraphReader(digraph, std::cin). + /// nodeMap("coordinates", coord_map). + /// arcMap("capacity", cap_map). + /// node("source", src). + /// node("target", trg). + /// attribute("caption", caption). + /// run(); + ///\endcode + /// + /// By default, the reader uses the first section in the file of the + /// proper type. If a section has an optional name, then it can be + /// selected for reading by giving an optional name parameter to the + /// \c nodes(), \c arcs() or \c attributes() functions. + /// + /// The \c useNodes() and \c useArcs() functions are used to tell the reader + /// that the nodes or arcs should not be constructed (added to the + /// graph) during the reading, but instead the label map of the items + /// are given as a parameter of these functions. An + /// application of these functions is multipass reading, which is + /// important if two \c \@arcs sections must be read from the + /// file. In this case the first phase would read the node set and one + /// of the arc sets, while the second phase would read the second arc + /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet). + /// The previously read label node map should be passed to the \c + /// useNodes() functions. Another application of multipass reading when + /// paths are given as a node map or an arc map. + /// It is impossible to read this in + /// a single pass, because the arcs are not constructed when the node + /// maps are read. + template + class DigraphReader { + public: + + typedef DGR Digraph; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(DGR); + + std::istream* _is; + bool local_is; + std::string _filename; + + DGR& _digraph; + + std::string _nodes_caption; + std::string _arcs_caption; + std::string _attributes_caption; + + typedef std::map NodeIndex; + NodeIndex _node_index; + typedef std::map ArcIndex; + ArcIndex _arc_index; + + typedef std::vector*> > NodeMaps; + NodeMaps _node_maps; + + typedef std::vector*> >ArcMaps; + ArcMaps _arc_maps; + + typedef std::multimap + Attributes; + Attributes _attributes; + + bool _use_nodes; + bool _use_arcs; + + bool _skip_nodes; + bool _skip_arcs; + + int line_num; + std::istringstream line; + + public: + + /// \brief Constructor + /// + /// Construct a directed graph reader, which reads from the given + /// input stream. + DigraphReader(DGR& digraph, std::istream& is = std::cin) + : _is(&is), local_is(false), _digraph(digraph), + _use_nodes(false), _use_arcs(false), + _skip_nodes(false), _skip_arcs(false) {} + + /// \brief Constructor + /// + /// Construct a directed graph reader, which reads from the given + /// file. + DigraphReader(DGR& digraph, const std::string& fn) + : _is(new std::ifstream(fn.c_str())), local_is(true), + _filename(fn), _digraph(digraph), + _use_nodes(false), _use_arcs(false), + _skip_nodes(false), _skip_arcs(false) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Constructor + /// + /// Construct a directed graph reader, which reads from the given + /// file. + DigraphReader(DGR& digraph, const char* fn) + : _is(new std::ifstream(fn)), local_is(true), + _filename(fn), _digraph(digraph), + _use_nodes(false), _use_arcs(false), + _skip_nodes(false), _skip_arcs(false) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Destructor + ~DigraphReader() { + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + delete it->second; + } + + for (typename ArcMaps::iterator it = _arc_maps.begin(); + it != _arc_maps.end(); ++it) { + delete it->second; + } + + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + delete it->second; + } + + if (local_is) { + delete _is; + } + + } + + private: + + template + friend DigraphReader digraphReader(TDGR& digraph, std::istream& is); + template + friend DigraphReader digraphReader(TDGR& digraph, + const std::string& fn); + template + friend DigraphReader digraphReader(TDGR& digraph, const char *fn); + + DigraphReader(DigraphReader& other) + : _is(other._is), local_is(other.local_is), _digraph(other._digraph), + _use_nodes(other._use_nodes), _use_arcs(other._use_arcs), + _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) { + + other._is = 0; + other.local_is = false; + + _node_index.swap(other._node_index); + _arc_index.swap(other._arc_index); + + _node_maps.swap(other._node_maps); + _arc_maps.swap(other._arc_maps); + _attributes.swap(other._attributes); + + _nodes_caption = other._nodes_caption; + _arcs_caption = other._arcs_caption; + _attributes_caption = other._attributes_caption; + + } + + DigraphReader& operator=(const DigraphReader&); + + public: + + /// \name Reading Rules + /// @{ + + /// \brief Node map reading rule + /// + /// Add a node map reading rule to the reader. + template + DigraphReader& nodeMap(const std::string& caption, Map& map) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node map reading rule + /// + /// Add a node map reading rule with specialized converter to the + /// reader. + template + DigraphReader& nodeMap(const std::string& caption, Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map, converter); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc map reading rule + /// + /// Add an arc map reading rule to the reader. + template + DigraphReader& arcMap(const std::string& caption, Map& map) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map); + _arc_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc map reading rule + /// + /// Add an arc map reading rule with specialized converter to the + /// reader. + template + DigraphReader& arcMap(const std::string& caption, Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map, converter); + _arc_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Attribute reading rule + /// + /// Add an attribute reading rule to the reader. + template + DigraphReader& attribute(const std::string& caption, Value& value) { + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(value); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Attribute reading rule + /// + /// Add an attribute reading rule with specialized converter to the + /// reader. + template + DigraphReader& attribute(const std::string& caption, Value& value, + const Converter& converter = Converter()) { + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(value, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node reading rule + /// + /// Add a node reading rule to reader. + DigraphReader& node(const std::string& caption, Node& node) { + typedef _reader_bits::MapLookUpConverter Converter; + Converter converter(_node_index); + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(node, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc reading rule + /// + /// Add an arc reading rule to reader. + DigraphReader& arc(const std::string& caption, Arc& arc) { + typedef _reader_bits::MapLookUpConverter Converter; + Converter converter(_arc_index); + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(arc, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// @} + + /// \name Select Section by Name + /// @{ + + /// \brief Set \c \@nodes section to be read + /// + /// Set \c \@nodes section to be read + DigraphReader& nodes(const std::string& caption) { + _nodes_caption = caption; + return *this; + } + + /// \brief Set \c \@arcs section to be read + /// + /// Set \c \@arcs section to be read + DigraphReader& arcs(const std::string& caption) { + _arcs_caption = caption; + return *this; + } + + /// \brief Set \c \@attributes section to be read + /// + /// Set \c \@attributes section to be read + DigraphReader& attributes(const std::string& caption) { + _attributes_caption = caption; + return *this; + } + + /// @} + + /// \name Using Previously Constructed Node or Arc Set + /// @{ + + /// \brief Use previously constructed node set + /// + /// Use previously constructed node set, and specify the node + /// label map. + template + DigraphReader& useNodes(const Map& map) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); + _use_nodes = true; + _writer_bits::DefaultConverter converter; + for (NodeIt n(_digraph); n != INVALID; ++n) { + _node_index.insert(std::make_pair(converter(map[n]), n)); + } + return *this; + } + + /// \brief Use previously constructed node set + /// + /// Use previously constructed node set, and specify the node + /// label map and a functor which converts the label map values to + /// \c std::string. + template + DigraphReader& useNodes(const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); + _use_nodes = true; + for (NodeIt n(_digraph); n != INVALID; ++n) { + _node_index.insert(std::make_pair(converter(map[n]), n)); + } + return *this; + } + + /// \brief Use previously constructed arc set + /// + /// Use previously constructed arc set, and specify the arc + /// label map. + template + DigraphReader& useArcs(const Map& map) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); + _use_arcs = true; + _writer_bits::DefaultConverter converter; + for (ArcIt a(_digraph); a != INVALID; ++a) { + _arc_index.insert(std::make_pair(converter(map[a]), a)); + } + return *this; + } + + /// \brief Use previously constructed arc set + /// + /// Use previously constructed arc set, and specify the arc + /// label map and a functor which converts the label map values to + /// \c std::string. + template + DigraphReader& useArcs(const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member"); + _use_arcs = true; + for (ArcIt a(_digraph); a != INVALID; ++a) { + _arc_index.insert(std::make_pair(converter(map[a]), a)); + } + return *this; + } + + /// \brief Skips the reading of node section + /// + /// Omit the reading of the node section. This implies that each node + /// map reading rule will be abandoned, and the nodes of the graph + /// will not be constructed, which usually cause that the arc set + /// could not be read due to lack of node name resolving. + /// Therefore \c skipArcs() function should also be used, or + /// \c useNodes() should be used to specify the label of the nodes. + DigraphReader& skipNodes() { + LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); + _skip_nodes = true; + return *this; + } + + /// \brief Skips the reading of arc section + /// + /// Omit the reading of the arc section. This implies that each arc + /// map reading rule will be abandoned, and the arcs of the graph + /// will not be constructed. + DigraphReader& skipArcs() { + LEMON_ASSERT(!_skip_arcs, "Skip arcs already set"); + _skip_arcs = true; + return *this; + } + + /// @} + + private: + + bool readLine() { + std::string str; + while(++line_num, std::getline(*_is, str)) { + line.clear(); line.str(str); + char c; + if (line >> std::ws >> c && c != '#') { + line.putback(c); + return true; + } + } + return false; + } + + bool readSuccess() { + return static_cast(*_is); + } + + void skipSection() { + char c; + while (readSuccess() && line >> c && c != '@') { + readLine(); + } + if (readSuccess()) { + line.putback(c); + } + } + + void readNodes() { + + std::vector map_index(_node_maps.size()); + int map_num, label_index; + + char c; + if (!readLine() || !(line >> c) || c == '@') { + if (readSuccess() && line) line.putback(c); + if (!_node_maps.empty()) + throw FormatError("Cannot find map names"); + return; + } + line.putback(c); + + { + std::map maps; + + std::string map; + int index = 0; + while (_reader_bits::readToken(line, map)) { + if (maps.find(map) != maps.end()) { + std::ostringstream msg; + msg << "Multiple occurence of node map: " << map; + throw FormatError(msg.str()); + } + maps.insert(std::make_pair(map, index)); + ++index; + } + + for (int i = 0; i < static_cast(_node_maps.size()); ++i) { + std::map::iterator jt = + maps.find(_node_maps[i].first); + if (jt == maps.end()) { + std::ostringstream msg; + msg << "Map not found: " << _node_maps[i].first; + throw FormatError(msg.str()); + } + map_index[i] = jt->second; + } + + { + std::map::iterator jt = maps.find("label"); + if (jt != maps.end()) { + label_index = jt->second; + } else { + label_index = -1; + } + } + map_num = maps.size(); + } + + while (readLine() && line >> c && c != '@') { + line.putback(c); + + std::vector tokens(map_num); + for (int i = 0; i < map_num; ++i) { + if (!_reader_bits::readToken(line, tokens[i])) { + std::ostringstream msg; + msg << "Column not found (" << i + 1 << ")"; + throw FormatError(msg.str()); + } + } + if (line >> std::ws >> c) + throw FormatError("Extra character at the end of line"); + + Node n; + if (!_use_nodes) { + n = _digraph.addNode(); + if (label_index != -1) + _node_index.insert(std::make_pair(tokens[label_index], n)); + } else { + if (label_index == -1) + throw FormatError("Label map not found"); + typename std::map::iterator it = + _node_index.find(tokens[label_index]); + if (it == _node_index.end()) { + std::ostringstream msg; + msg << "Node with label not found: " << tokens[label_index]; + throw FormatError(msg.str()); + } + n = it->second; + } + + for (int i = 0; i < static_cast(_node_maps.size()); ++i) { + _node_maps[i].second->set(n, tokens[map_index[i]]); + } + + } + if (readSuccess()) { + line.putback(c); + } + } + + void readArcs() { + + std::vector map_index(_arc_maps.size()); + int map_num, label_index; + + char c; + if (!readLine() || !(line >> c) || c == '@') { + if (readSuccess() && line) line.putback(c); + if (!_arc_maps.empty()) + throw FormatError("Cannot find map names"); + return; + } + line.putback(c); + + { + std::map maps; + + std::string map; + int index = 0; + while (_reader_bits::readToken(line, map)) { + if(map == "-") { + if(index!=0) + throw FormatError("'-' is not allowed as a map name"); + else if (line >> std::ws >> c) + throw FormatError("Extra character at the end of line"); + else break; + } + if (maps.find(map) != maps.end()) { + std::ostringstream msg; + msg << "Multiple occurence of arc map: " << map; + throw FormatError(msg.str()); + } + maps.insert(std::make_pair(map, index)); + ++index; + } + + for (int i = 0; i < static_cast(_arc_maps.size()); ++i) { + std::map::iterator jt = + maps.find(_arc_maps[i].first); + if (jt == maps.end()) { + std::ostringstream msg; + msg << "Map not found: " << _arc_maps[i].first; + throw FormatError(msg.str()); + } + map_index[i] = jt->second; + } + + { + std::map::iterator jt = maps.find("label"); + if (jt != maps.end()) { + label_index = jt->second; + } else { + label_index = -1; + } + } + map_num = maps.size(); + } + + while (readLine() && line >> c && c != '@') { + line.putback(c); + + std::string source_token; + std::string target_token; + + if (!_reader_bits::readToken(line, source_token)) + throw FormatError("Source not found"); + + if (!_reader_bits::readToken(line, target_token)) + throw FormatError("Target not found"); + + std::vector tokens(map_num); + for (int i = 0; i < map_num; ++i) { + if (!_reader_bits::readToken(line, tokens[i])) { + std::ostringstream msg; + msg << "Column not found (" << i + 1 << ")"; + throw FormatError(msg.str()); + } + } + if (line >> std::ws >> c) + throw FormatError("Extra character at the end of line"); + + Arc a; + if (!_use_arcs) { + + typename NodeIndex::iterator it; + + it = _node_index.find(source_token); + if (it == _node_index.end()) { + std::ostringstream msg; + msg << "Item not found: " << source_token; + throw FormatError(msg.str()); + } + Node source = it->second; + + it = _node_index.find(target_token); + if (it == _node_index.end()) { + std::ostringstream msg; + msg << "Item not found: " << target_token; + throw FormatError(msg.str()); + } + Node target = it->second; + + a = _digraph.addArc(source, target); + if (label_index != -1) + _arc_index.insert(std::make_pair(tokens[label_index], a)); + } else { + if (label_index == -1) + throw FormatError("Label map not found"); + typename std::map::iterator it = + _arc_index.find(tokens[label_index]); + if (it == _arc_index.end()) { + std::ostringstream msg; + msg << "Arc with label not found: " << tokens[label_index]; + throw FormatError(msg.str()); + } + a = it->second; + } + + for (int i = 0; i < static_cast(_arc_maps.size()); ++i) { + _arc_maps[i].second->set(a, tokens[map_index[i]]); + } + + } + if (readSuccess()) { + line.putback(c); + } + } + + void readAttributes() { + + std::set read_attr; + + char c; + while (readLine() && line >> c && c != '@') { + line.putback(c); + + std::string attr, token; + if (!_reader_bits::readToken(line, attr)) + throw FormatError("Attribute name not found"); + if (!_reader_bits::readToken(line, token)) + throw FormatError("Attribute value not found"); + if (line >> c) + throw FormatError("Extra character at the end of line"); + + { + std::set::iterator it = read_attr.find(attr); + if (it != read_attr.end()) { + std::ostringstream msg; + msg << "Multiple occurence of attribute: " << attr; + throw FormatError(msg.str()); + } + read_attr.insert(attr); + } + + { + typename Attributes::iterator it = _attributes.lower_bound(attr); + while (it != _attributes.end() && it->first == attr) { + it->second->set(token); + ++it; + } + } + + } + if (readSuccess()) { + line.putback(c); + } + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + if (read_attr.find(it->first) == read_attr.end()) { + std::ostringstream msg; + msg << "Attribute not found: " << it->first; + throw FormatError(msg.str()); + } + } + } + + public: + + /// \name Execution of the Reader + /// @{ + + /// \brief Start the batch processing + /// + /// This function starts the batch processing + void run() { + LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); + + bool nodes_done = _skip_nodes; + bool arcs_done = _skip_arcs; + bool attributes_done = false; + + line_num = 0; + readLine(); + skipSection(); + + while (readSuccess()) { + try { + char c; + std::string section, caption; + line >> c; + _reader_bits::readToken(line, section); + _reader_bits::readToken(line, caption); + + if (line >> c) + throw FormatError("Extra character at the end of line"); + + if (section == "nodes" && !nodes_done) { + if (_nodes_caption.empty() || _nodes_caption == caption) { + readNodes(); + nodes_done = true; + } + } else if ((section == "arcs" || section == "edges") && + !arcs_done) { + if (_arcs_caption.empty() || _arcs_caption == caption) { + readArcs(); + arcs_done = true; + } + } else if (section == "attributes" && !attributes_done) { + if (_attributes_caption.empty() || _attributes_caption == caption) { + readAttributes(); + attributes_done = true; + } + } else { + readLine(); + skipSection(); + } + } catch (FormatError& error) { + error.line(line_num); + error.file(_filename); + throw; + } + } + + if (!nodes_done) { + throw FormatError("Section @nodes not found"); + } + + if (!arcs_done) { + throw FormatError("Section @arcs not found"); + } + + if (!attributes_done && !_attributes.empty()) { + throw FormatError("Section @attributes not found"); + } + + } + + /// @} + + }; + + /// \ingroup lemon_io + /// + /// \brief Return a \ref DigraphReader class + /// + /// This function just returns a \ref DigraphReader class. + /// + /// With this function a digraph can be read from an + /// \ref lgf-format "LGF" file or input stream with several maps and + /// attributes. For example, there is network flow problem on a + /// digraph, i.e. a digraph with a \e capacity map on the arcs and + /// \e source and \e target nodes. This digraph can be read with the + /// following code: + /// + ///\code + ///ListDigraph digraph; + ///ListDigraph::ArcMap cm(digraph); + ///ListDigraph::Node src, trg; + ///digraphReader(digraph, std::cin). + /// arcMap("capacity", cap). + /// node("source", src). + /// node("target", trg). + /// run(); + ///\endcode + /// + /// For a complete documentation, please see the \ref DigraphReader + /// class documentation. + /// \warning Don't forget to put the \ref DigraphReader::run() "run()" + /// to the end of the parameter list. + /// \relates DigraphReader + /// \sa digraphReader(TDGR& digraph, const std::string& fn) + /// \sa digraphReader(TDGR& digraph, const char* fn) + template + DigraphReader digraphReader(TDGR& digraph, std::istream& is) { + DigraphReader tmp(digraph, is); + return tmp; + } + + /// \brief Return a \ref DigraphReader class + /// + /// This function just returns a \ref DigraphReader class. + /// \relates DigraphReader + /// \sa digraphReader(TDGR& digraph, std::istream& is) + template + DigraphReader digraphReader(TDGR& digraph, const std::string& fn) { + DigraphReader tmp(digraph, fn); + return tmp; + } + + /// \brief Return a \ref DigraphReader class + /// + /// This function just returns a \ref DigraphReader class. + /// \relates DigraphReader + /// \sa digraphReader(TDGR& digraph, std::istream& is) + template + DigraphReader digraphReader(TDGR& digraph, const char* fn) { + DigraphReader tmp(digraph, fn); + return tmp; + } + + template + class GraphReader; + + template + GraphReader graphReader(TGR& graph, std::istream& is = std::cin); + template + GraphReader graphReader(TGR& graph, const std::string& fn); + template + GraphReader graphReader(TGR& graph, const char *fn); + + /// \ingroup lemon_io + /// + /// \brief \ref lgf-format "LGF" reader for undirected graphs + /// + /// This utility reads an \ref lgf-format "LGF" file. + /// + /// It can be used almost the same way as \c DigraphReader. + /// The only difference is that this class can handle edges and + /// edge maps as well as arcs and arc maps. + /// + /// The columns in the \c \@edges (or \c \@arcs) section are the + /// edge maps. However, if there are two maps with the same name + /// prefixed with \c '+' and \c '-', then these can be read into an + /// arc map. Similarly, an attribute can be read into an arc, if + /// it's value is an edge label prefixed with \c '+' or \c '-'. + template + class GraphReader { + public: + + typedef GR Graph; + + private: + + TEMPLATE_GRAPH_TYPEDEFS(GR); + + std::istream* _is; + bool local_is; + std::string _filename; + + GR& _graph; + + std::string _nodes_caption; + std::string _edges_caption; + std::string _attributes_caption; + + typedef std::map NodeIndex; + NodeIndex _node_index; + typedef std::map EdgeIndex; + EdgeIndex _edge_index; + + typedef std::vector*> > NodeMaps; + NodeMaps _node_maps; + + typedef std::vector*> > EdgeMaps; + EdgeMaps _edge_maps; + + typedef std::multimap + Attributes; + Attributes _attributes; + + bool _use_nodes; + bool _use_edges; + + bool _skip_nodes; + bool _skip_edges; + + int line_num; + std::istringstream line; + + public: + + /// \brief Constructor + /// + /// Construct an undirected graph reader, which reads from the given + /// input stream. + GraphReader(GR& graph, std::istream& is = std::cin) + : _is(&is), local_is(false), _graph(graph), + _use_nodes(false), _use_edges(false), + _skip_nodes(false), _skip_edges(false) {} + + /// \brief Constructor + /// + /// Construct an undirected graph reader, which reads from the given + /// file. + GraphReader(GR& graph, const std::string& fn) + : _is(new std::ifstream(fn.c_str())), local_is(true), + _filename(fn), _graph(graph), + _use_nodes(false), _use_edges(false), + _skip_nodes(false), _skip_edges(false) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Constructor + /// + /// Construct an undirected graph reader, which reads from the given + /// file. + GraphReader(GR& graph, const char* fn) + : _is(new std::ifstream(fn)), local_is(true), + _filename(fn), _graph(graph), + _use_nodes(false), _use_edges(false), + _skip_nodes(false), _skip_edges(false) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Destructor + ~GraphReader() { + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + delete it->second; + } + + for (typename EdgeMaps::iterator it = _edge_maps.begin(); + it != _edge_maps.end(); ++it) { + delete it->second; + } + + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + delete it->second; + } + + if (local_is) { + delete _is; + } + + } + + private: + template + friend GraphReader graphReader(TGR& graph, std::istream& is); + template + friend GraphReader graphReader(TGR& graph, const std::string& fn); + template + friend GraphReader graphReader(TGR& graph, const char *fn); + + GraphReader(GraphReader& other) + : _is(other._is), local_is(other.local_is), _graph(other._graph), + _use_nodes(other._use_nodes), _use_edges(other._use_edges), + _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { + + other._is = 0; + other.local_is = false; + + _node_index.swap(other._node_index); + _edge_index.swap(other._edge_index); + + _node_maps.swap(other._node_maps); + _edge_maps.swap(other._edge_maps); + _attributes.swap(other._attributes); + + _nodes_caption = other._nodes_caption; + _edges_caption = other._edges_caption; + _attributes_caption = other._attributes_caption; + + } + + GraphReader& operator=(const GraphReader&); + + public: + + /// \name Reading Rules + /// @{ + + /// \brief Node map reading rule + /// + /// Add a node map reading rule to the reader. + template + GraphReader& nodeMap(const std::string& caption, Map& map) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node map reading rule + /// + /// Add a node map reading rule with specialized converter to the + /// reader. + template + GraphReader& nodeMap(const std::string& caption, Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map, converter); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Edge map reading rule + /// + /// Add an edge map reading rule to the reader. + template + GraphReader& edgeMap(const std::string& caption, Map& map) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map); + _edge_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Edge map reading rule + /// + /// Add an edge map reading rule with specialized converter to the + /// reader. + template + GraphReader& edgeMap(const std::string& caption, Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* storage = + new _reader_bits::MapStorage(map, converter); + _edge_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc map reading rule + /// + /// Add an arc map reading rule to the reader. + template + GraphReader& arcMap(const std::string& caption, Map& map) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* forward_storage = + new _reader_bits::GraphArcMapStorage(_graph, map); + _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); + _reader_bits::MapStorageBase* backward_storage = + new _reader_bits::GraphArcMapStorage(_graph, map); + _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); + return *this; + } + + /// \brief Arc map reading rule + /// + /// Add an arc map reading rule with specialized converter to the + /// reader. + template + GraphReader& arcMap(const std::string& caption, Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _reader_bits::MapStorageBase* forward_storage = + new _reader_bits::GraphArcMapStorage + (_graph, map, converter); + _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); + _reader_bits::MapStorageBase* backward_storage = + new _reader_bits::GraphArcMapStorage + (_graph, map, converter); + _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); + return *this; + } + + /// \brief Attribute reading rule + /// + /// Add an attribute reading rule to the reader. + template + GraphReader& attribute(const std::string& caption, Value& value) { + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(value); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Attribute reading rule + /// + /// Add an attribute reading rule with specialized converter to the + /// reader. + template + GraphReader& attribute(const std::string& caption, Value& value, + const Converter& converter = Converter()) { + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(value, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node reading rule + /// + /// Add a node reading rule to reader. + GraphReader& node(const std::string& caption, Node& node) { + typedef _reader_bits::MapLookUpConverter Converter; + Converter converter(_node_index); + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(node, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Edge reading rule + /// + /// Add an edge reading rule to reader. + GraphReader& edge(const std::string& caption, Edge& edge) { + typedef _reader_bits::MapLookUpConverter Converter; + Converter converter(_edge_index); + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(edge, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc reading rule + /// + /// Add an arc reading rule to reader. + GraphReader& arc(const std::string& caption, Arc& arc) { + typedef _reader_bits::GraphArcLookUpConverter Converter; + Converter converter(_graph, _edge_index); + _reader_bits::ValueStorageBase* storage = + new _reader_bits::ValueStorage(arc, converter); + _attributes.insert(std::make_pair(caption, storage)); + return *this; + } + + /// @} + + /// \name Select Section by Name + /// @{ + + /// \brief Set \c \@nodes section to be read + /// + /// Set \c \@nodes section to be read. + GraphReader& nodes(const std::string& caption) { + _nodes_caption = caption; + return *this; + } + + /// \brief Set \c \@edges section to be read + /// + /// Set \c \@edges section to be read. + GraphReader& edges(const std::string& caption) { + _edges_caption = caption; + return *this; + } + + /// \brief Set \c \@attributes section to be read + /// + /// Set \c \@attributes section to be read. + GraphReader& attributes(const std::string& caption) { + _attributes_caption = caption; + return *this; + } + + /// @} + + /// \name Using Previously Constructed Node or Edge Set + /// @{ + + /// \brief Use previously constructed node set + /// + /// Use previously constructed node set, and specify the node + /// label map. + template + GraphReader& useNodes(const Map& map) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); + _use_nodes = true; + _writer_bits::DefaultConverter converter; + for (NodeIt n(_graph); n != INVALID; ++n) { + _node_index.insert(std::make_pair(converter(map[n]), n)); + } + return *this; + } + + /// \brief Use previously constructed node set + /// + /// Use previously constructed node set, and specify the node + /// label map and a functor which converts the label map values to + /// \c std::string. + template + GraphReader& useNodes(const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); + _use_nodes = true; + for (NodeIt n(_graph); n != INVALID; ++n) { + _node_index.insert(std::make_pair(converter(map[n]), n)); + } + return *this; + } + + /// \brief Use previously constructed edge set + /// + /// Use previously constructed edge set, and specify the edge + /// label map. + template + GraphReader& useEdges(const Map& map) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); + _use_edges = true; + _writer_bits::DefaultConverter converter; + for (EdgeIt a(_graph); a != INVALID; ++a) { + _edge_index.insert(std::make_pair(converter(map[a]), a)); + } + return *this; + } + + /// \brief Use previously constructed edge set + /// + /// Use previously constructed edge set, and specify the edge + /// label map and a functor which converts the label map values to + /// \c std::string. + template + GraphReader& useEdges(const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member"); + _use_edges = true; + for (EdgeIt a(_graph); a != INVALID; ++a) { + _edge_index.insert(std::make_pair(converter(map[a]), a)); + } + return *this; + } + + /// \brief Skip the reading of node section + /// + /// Omit the reading of the node section. This implies that each node + /// map reading rule will be abandoned, and the nodes of the graph + /// will not be constructed, which usually cause that the edge set + /// could not be read due to lack of node name + /// could not be read due to lack of node name resolving. + /// Therefore \c skipEdges() function should also be used, or + /// \c useNodes() should be used to specify the label of the nodes. + GraphReader& skipNodes() { + LEMON_ASSERT(!_skip_nodes, "Skip nodes already set"); + _skip_nodes = true; + return *this; + } + + /// \brief Skip the reading of edge section + /// + /// Omit the reading of the edge section. This implies that each edge + /// map reading rule will be abandoned, and the edges of the graph + /// will not be constructed. + GraphReader& skipEdges() { + LEMON_ASSERT(!_skip_edges, "Skip edges already set"); + _skip_edges = true; + return *this; + } + + /// @} + + private: + + bool readLine() { + std::string str; + while(++line_num, std::getline(*_is, str)) { + line.clear(); line.str(str); + char c; + if (line >> std::ws >> c && c != '#') { + line.putback(c); + return true; + } + } + return false; + } + + bool readSuccess() { + return static_cast(*_is); + } + + void skipSection() { + char c; + while (readSuccess() && line >> c && c != '@') { + readLine(); + } + if (readSuccess()) { + line.putback(c); + } + } + + void readNodes() { + + std::vector map_index(_node_maps.size()); + int map_num, label_index; + + char c; + if (!readLine() || !(line >> c) || c == '@') { + if (readSuccess() && line) line.putback(c); + if (!_node_maps.empty()) + throw FormatError("Cannot find map names"); + return; + } + line.putback(c); + + { + std::map maps; + + std::string map; + int index = 0; + while (_reader_bits::readToken(line, map)) { + if (maps.find(map) != maps.end()) { + std::ostringstream msg; + msg << "Multiple occurence of node map: " << map; + throw FormatError(msg.str()); + } + maps.insert(std::make_pair(map, index)); + ++index; + } + + for (int i = 0; i < static_cast(_node_maps.size()); ++i) { + std::map::iterator jt = + maps.find(_node_maps[i].first); + if (jt == maps.end()) { + std::ostringstream msg; + msg << "Map not found: " << _node_maps[i].first; + throw FormatError(msg.str()); + } + map_index[i] = jt->second; + } + + { + std::map::iterator jt = maps.find("label"); + if (jt != maps.end()) { + label_index = jt->second; + } else { + label_index = -1; + } + } + map_num = maps.size(); + } + + while (readLine() && line >> c && c != '@') { + line.putback(c); + + std::vector tokens(map_num); + for (int i = 0; i < map_num; ++i) { + if (!_reader_bits::readToken(line, tokens[i])) { + std::ostringstream msg; + msg << "Column not found (" << i + 1 << ")"; + throw FormatError(msg.str()); + } + } + if (line >> std::ws >> c) + throw FormatError("Extra character at the end of line"); + + Node n; + if (!_use_nodes) { + n = _graph.addNode(); + if (label_index != -1) + _node_index.insert(std::make_pair(tokens[label_index], n)); + } else { + if (label_index == -1) + throw FormatError("Label map not found"); + typename std::map::iterator it = + _node_index.find(tokens[label_index]); + if (it == _node_index.end()) { + std::ostringstream msg; + msg << "Node with label not found: " << tokens[label_index]; + throw FormatError(msg.str()); + } + n = it->second; + } + + for (int i = 0; i < static_cast(_node_maps.size()); ++i) { + _node_maps[i].second->set(n, tokens[map_index[i]]); + } + + } + if (readSuccess()) { + line.putback(c); + } + } + + void readEdges() { + + std::vector map_index(_edge_maps.size()); + int map_num, label_index; + + char c; + if (!readLine() || !(line >> c) || c == '@') { + if (readSuccess() && line) line.putback(c); + if (!_edge_maps.empty()) + throw FormatError("Cannot find map names"); + return; + } + line.putback(c); + + { + std::map maps; + + std::string map; + int index = 0; + while (_reader_bits::readToken(line, map)) { + if(map == "-") { + if(index!=0) + throw FormatError("'-' is not allowed as a map name"); + else if (line >> std::ws >> c) + throw FormatError("Extra character at the end of line"); + else break; + } + if (maps.find(map) != maps.end()) { + std::ostringstream msg; + msg << "Multiple occurence of edge map: " << map; + throw FormatError(msg.str()); + } + maps.insert(std::make_pair(map, index)); + ++index; + } + + for (int i = 0; i < static_cast(_edge_maps.size()); ++i) { + std::map::iterator jt = + maps.find(_edge_maps[i].first); + if (jt == maps.end()) { + std::ostringstream msg; + msg << "Map not found: " << _edge_maps[i].first; + throw FormatError(msg.str()); + } + map_index[i] = jt->second; + } + + { + std::map::iterator jt = maps.find("label"); + if (jt != maps.end()) { + label_index = jt->second; + } else { + label_index = -1; + } + } + map_num = maps.size(); + } + + while (readLine() && line >> c && c != '@') { + line.putback(c); + + std::string source_token; + std::string target_token; + + if (!_reader_bits::readToken(line, source_token)) + throw FormatError("Node u not found"); + + if (!_reader_bits::readToken(line, target_token)) + throw FormatError("Node v not found"); + + std::vector tokens(map_num); + for (int i = 0; i < map_num; ++i) { + if (!_reader_bits::readToken(line, tokens[i])) { + std::ostringstream msg; + msg << "Column not found (" << i + 1 << ")"; + throw FormatError(msg.str()); + } + } + if (line >> std::ws >> c) + throw FormatError("Extra character at the end of line"); + + Edge e; + if (!_use_edges) { + + typename NodeIndex::iterator it; + + it = _node_index.find(source_token); + if (it == _node_index.end()) { + std::ostringstream msg; + msg << "Item not found: " << source_token; + throw FormatError(msg.str()); + } + Node source = it->second; + + it = _node_index.find(target_token); + if (it == _node_index.end()) { + std::ostringstream msg; + msg << "Item not found: " << target_token; + throw FormatError(msg.str()); + } + Node target = it->second; + + e = _graph.addEdge(source, target); + if (label_index != -1) + _edge_index.insert(std::make_pair(tokens[label_index], e)); + } else { + if (label_index == -1) + throw FormatError("Label map not found"); + typename std::map::iterator it = + _edge_index.find(tokens[label_index]); + if (it == _edge_index.end()) { + std::ostringstream msg; + msg << "Edge with label not found: " << tokens[label_index]; + throw FormatError(msg.str()); + } + e = it->second; + } + + for (int i = 0; i < static_cast(_edge_maps.size()); ++i) { + _edge_maps[i].second->set(e, tokens[map_index[i]]); + } + + } + if (readSuccess()) { + line.putback(c); + } + } + + void readAttributes() { + + std::set read_attr; + + char c; + while (readLine() && line >> c && c != '@') { + line.putback(c); + + std::string attr, token; + if (!_reader_bits::readToken(line, attr)) + throw FormatError("Attribute name not found"); + if (!_reader_bits::readToken(line, token)) + throw FormatError("Attribute value not found"); + if (line >> c) + throw FormatError("Extra character at the end of line"); + + { + std::set::iterator it = read_attr.find(attr); + if (it != read_attr.end()) { + std::ostringstream msg; + msg << "Multiple occurence of attribute: " << attr; + throw FormatError(msg.str()); + } + read_attr.insert(attr); + } + + { + typename Attributes::iterator it = _attributes.lower_bound(attr); + while (it != _attributes.end() && it->first == attr) { + it->second->set(token); + ++it; + } + } + + } + if (readSuccess()) { + line.putback(c); + } + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + if (read_attr.find(it->first) == read_attr.end()) { + std::ostringstream msg; + msg << "Attribute not found: " << it->first; + throw FormatError(msg.str()); + } + } + } + + public: + + /// \name Execution of the Reader + /// @{ + + /// \brief Start the batch processing + /// + /// This function starts the batch processing + void run() { + + LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); + + bool nodes_done = _skip_nodes; + bool edges_done = _skip_edges; + bool attributes_done = false; + + line_num = 0; + readLine(); + skipSection(); + + while (readSuccess()) { + try { + char c; + std::string section, caption; + line >> c; + _reader_bits::readToken(line, section); + _reader_bits::readToken(line, caption); + + if (line >> c) + throw FormatError("Extra character at the end of line"); + + if (section == "nodes" && !nodes_done) { + if (_nodes_caption.empty() || _nodes_caption == caption) { + readNodes(); + nodes_done = true; + } + } else if ((section == "edges" || section == "arcs") && + !edges_done) { + if (_edges_caption.empty() || _edges_caption == caption) { + readEdges(); + edges_done = true; + } + } else if (section == "attributes" && !attributes_done) { + if (_attributes_caption.empty() || _attributes_caption == caption) { + readAttributes(); + attributes_done = true; + } + } else { + readLine(); + skipSection(); + } + } catch (FormatError& error) { + error.line(line_num); + error.file(_filename); + throw; + } + } + + if (!nodes_done) { + throw FormatError("Section @nodes not found"); + } + + if (!edges_done) { + throw FormatError("Section @edges not found"); + } + + if (!attributes_done && !_attributes.empty()) { + throw FormatError("Section @attributes not found"); + } + + } + + /// @} + + }; + + /// \ingroup lemon_io + /// + /// \brief Return a \ref GraphReader class + /// + /// This function just returns a \ref GraphReader class. + /// + /// With this function a graph can be read from an + /// \ref lgf-format "LGF" file or input stream with several maps and + /// attributes. For example, there is weighted matching problem on a + /// graph, i.e. a graph with a \e weight map on the edges. This + /// graph can be read with the following code: + /// + ///\code + ///ListGraph graph; + ///ListGraph::EdgeMap weight(graph); + ///graphReader(graph, std::cin). + /// edgeMap("weight", weight). + /// run(); + ///\endcode + /// + /// For a complete documentation, please see the \ref GraphReader + /// class documentation. + /// \warning Don't forget to put the \ref GraphReader::run() "run()" + /// to the end of the parameter list. + /// \relates GraphReader + /// \sa graphReader(TGR& graph, const std::string& fn) + /// \sa graphReader(TGR& graph, const char* fn) + template + GraphReader graphReader(TGR& graph, std::istream& is) { + GraphReader tmp(graph, is); + return tmp; + } + + /// \brief Return a \ref GraphReader class + /// + /// This function just returns a \ref GraphReader class. + /// \relates GraphReader + /// \sa graphReader(TGR& graph, std::istream& is) + template + GraphReader graphReader(TGR& graph, const std::string& fn) { + GraphReader tmp(graph, fn); + return tmp; + } + + /// \brief Return a \ref GraphReader class + /// + /// This function just returns a \ref GraphReader class. + /// \relates GraphReader + /// \sa graphReader(TGR& graph, std::istream& is) + template + GraphReader graphReader(TGR& graph, const char* fn) { + GraphReader tmp(graph, fn); + return tmp; + } + + class SectionReader; + + SectionReader sectionReader(std::istream& is); + SectionReader sectionReader(const std::string& fn); + SectionReader sectionReader(const char* fn); + + /// \ingroup lemon_io + /// + /// \brief Section reader class + /// + /// In the \ref lgf-format "LGF" file extra sections can be placed, + /// which contain any data in arbitrary format. Such sections can be + /// read with this class. A reading rule can be added to the class + /// with two different functions. With the \c sectionLines() function a + /// functor can process the section line-by-line, while with the \c + /// sectionStream() member the section can be read from an input + /// stream. + class SectionReader { + private: + + std::istream* _is; + bool local_is; + std::string _filename; + + typedef std::map Sections; + Sections _sections; + + int line_num; + std::istringstream line; + + public: + + /// \brief Constructor + /// + /// Construct a section reader, which reads from the given input + /// stream. + SectionReader(std::istream& is) + : _is(&is), local_is(false) {} + + /// \brief Constructor + /// + /// Construct a section reader, which reads from the given file. + SectionReader(const std::string& fn) + : _is(new std::ifstream(fn.c_str())), local_is(true), + _filename(fn) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Constructor + /// + /// Construct a section reader, which reads from the given file. + SectionReader(const char* fn) + : _is(new std::ifstream(fn)), local_is(true), + _filename(fn) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Destructor + ~SectionReader() { + for (Sections::iterator it = _sections.begin(); + it != _sections.end(); ++it) { + delete it->second; + } + + if (local_is) { + delete _is; + } + + } + + private: + + friend SectionReader sectionReader(std::istream& is); + friend SectionReader sectionReader(const std::string& fn); + friend SectionReader sectionReader(const char* fn); + + SectionReader(SectionReader& other) + : _is(other._is), local_is(other.local_is) { + + other._is = 0; + other.local_is = false; + + _sections.swap(other._sections); + } + + SectionReader& operator=(const SectionReader&); + + public: + + /// \name Section Readers + /// @{ + + /// \brief Add a section processor with line oriented reading + /// + /// The first parameter is the type descriptor of the section, the + /// second is a functor, which takes just one \c std::string + /// parameter. At the reading process, each line of the section + /// will be given to the functor object. However, the empty lines + /// and the comment lines are filtered out, and the leading + /// whitespaces are trimmed from each processed string. + /// + /// For example, let's see a section, which contain several + /// integers, which should be inserted into a vector. + ///\code + /// @numbers + /// 12 45 23 + /// 4 + /// 23 6 + ///\endcode + /// + /// The functor is implemented as a struct: + ///\code + /// struct NumberSection { + /// std::vector& _data; + /// NumberSection(std::vector& data) : _data(data) {} + /// void operator()(const std::string& line) { + /// std::istringstream ls(line); + /// int value; + /// while (ls >> value) _data.push_back(value); + /// } + /// }; + /// + /// // ... + /// + /// reader.sectionLines("numbers", NumberSection(vec)); + ///\endcode + template + SectionReader& sectionLines(const std::string& type, Functor functor) { + LEMON_ASSERT(!type.empty(), "Type is empty."); + LEMON_ASSERT(_sections.find(type) == _sections.end(), + "Multiple reading of section."); + _sections.insert(std::make_pair(type, + new _reader_bits::LineSection(functor))); + return *this; + } + + + /// \brief Add a section processor with stream oriented reading + /// + /// The first parameter is the type of the section, the second is + /// a functor, which takes an \c std::istream& and an \c int& + /// parameter, the latter regard to the line number of stream. The + /// functor can read the input while the section go on, and the + /// line number should be modified accordingly. + template + SectionReader& sectionStream(const std::string& type, Functor functor) { + LEMON_ASSERT(!type.empty(), "Type is empty."); + LEMON_ASSERT(_sections.find(type) == _sections.end(), + "Multiple reading of section."); + _sections.insert(std::make_pair(type, + new _reader_bits::StreamSection(functor))); + return *this; + } + + /// @} + + private: + + bool readLine() { + std::string str; + while(++line_num, std::getline(*_is, str)) { + line.clear(); line.str(str); + char c; + if (line >> std::ws >> c && c != '#') { + line.putback(c); + return true; + } + } + return false; + } + + bool readSuccess() { + return static_cast(*_is); + } + + void skipSection() { + char c; + while (readSuccess() && line >> c && c != '@') { + readLine(); + } + if (readSuccess()) { + line.putback(c); + } + } + + public: + + + /// \name Execution of the Reader + /// @{ + + /// \brief Start the batch processing + /// + /// This function starts the batch processing. + void run() { + + LEMON_ASSERT(_is != 0, "This reader assigned to an other reader"); + + std::set extra_sections; + + line_num = 0; + readLine(); + skipSection(); + + while (readSuccess()) { + try { + char c; + std::string section, caption; + line >> c; + _reader_bits::readToken(line, section); + _reader_bits::readToken(line, caption); + + if (line >> c) + throw FormatError("Extra character at the end of line"); + + if (extra_sections.find(section) != extra_sections.end()) { + std::ostringstream msg; + msg << "Multiple occurence of section: " << section; + throw FormatError(msg.str()); + } + Sections::iterator it = _sections.find(section); + if (it != _sections.end()) { + extra_sections.insert(section); + it->second->process(*_is, line_num); + } + readLine(); + skipSection(); + } catch (FormatError& error) { + error.line(line_num); + error.file(_filename); + throw; + } + } + for (Sections::iterator it = _sections.begin(); + it != _sections.end(); ++it) { + if (extra_sections.find(it->first) == extra_sections.end()) { + std::ostringstream os; + os << "Cannot find section: " << it->first; + throw FormatError(os.str()); + } + } + } + + /// @} + + }; + + /// \ingroup lemon_io + /// + /// \brief Return a \ref SectionReader class + /// + /// This function just returns a \ref SectionReader class. + /// + /// Please see SectionReader documentation about the custom section + /// input. + /// + /// \relates SectionReader + /// \sa sectionReader(const std::string& fn) + /// \sa sectionReader(const char *fn) + inline SectionReader sectionReader(std::istream& is) { + SectionReader tmp(is); + return tmp; + } + + /// \brief Return a \ref SectionReader class + /// + /// This function just returns a \ref SectionReader class. + /// \relates SectionReader + /// \sa sectionReader(std::istream& is) + inline SectionReader sectionReader(const std::string& fn) { + SectionReader tmp(fn); + return tmp; + } + + /// \brief Return a \ref SectionReader class + /// + /// This function just returns a \ref SectionReader class. + /// \relates SectionReader + /// \sa sectionReader(std::istream& is) + inline SectionReader sectionReader(const char* fn) { + SectionReader tmp(fn); + return tmp; + } + + /// \ingroup lemon_io + /// + /// \brief Reader for the contents of the \ref lgf-format "LGF" file + /// + /// This class can be used to read the sections, the map names and + /// the attributes from a file. Usually, the LEMON programs know + /// that, which type of graph, which maps and which attributes + /// should be read from a file, but in general tools (like glemon) + /// the contents of an LGF file should be guessed somehow. This class + /// reads the graph and stores the appropriate information for + /// reading the graph. + /// + ///\code + /// LgfContents contents("graph.lgf"); + /// contents.run(); + /// + /// // Does it contain any node section and arc section? + /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) { + /// std::cerr << "Failure, cannot find graph." << std::endl; + /// return -1; + /// } + /// std::cout << "The name of the default node section: " + /// << contents.nodeSection(0) << std::endl; + /// std::cout << "The number of the arc maps: " + /// << contents.arcMaps(0).size() << std::endl; + /// std::cout << "The name of second arc map: " + /// << contents.arcMaps(0)[1] << std::endl; + ///\endcode + class LgfContents { + private: + + std::istream* _is; + bool local_is; + + std::vector _node_sections; + std::vector _edge_sections; + std::vector _attribute_sections; + std::vector _extra_sections; + + std::vector _arc_sections; + + std::vector > _node_maps; + std::vector > _edge_maps; + + std::vector > _attributes; + + + int line_num; + std::istringstream line; + + public: + + /// \brief Constructor + /// + /// Construct an \e LGF contents reader, which reads from the given + /// input stream. + LgfContents(std::istream& is) + : _is(&is), local_is(false) {} + + /// \brief Constructor + /// + /// Construct an \e LGF contents reader, which reads from the given + /// file. + LgfContents(const std::string& fn) + : _is(new std::ifstream(fn.c_str())), local_is(true) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Constructor + /// + /// Construct an \e LGF contents reader, which reads from the given + /// file. + LgfContents(const char* fn) + : _is(new std::ifstream(fn)), local_is(true) { + if (!(*_is)) { + delete _is; + throw IoError("Cannot open file", fn); + } + } + + /// \brief Destructor + ~LgfContents() { + if (local_is) delete _is; + } + + private: + + LgfContents(const LgfContents&); + LgfContents& operator=(const LgfContents&); + + public: + + + /// \name Node Sections + /// @{ + + /// \brief Gives back the number of node sections in the file. + /// + /// Gives back the number of node sections in the file. + int nodeSectionNum() const { + return _node_sections.size(); + } + + /// \brief Returns the node section name at the given position. + /// + /// Returns the node section name at the given position. + const std::string& nodeSection(int i) const { + return _node_sections[i]; + } + + /// \brief Gives back the node maps for the given section. + /// + /// Gives back the node maps for the given section. + const std::vector& nodeMapNames(int i) const { + return _node_maps[i]; + } + + /// @} + + /// \name Arc/Edge Sections + /// @{ + + /// \brief Gives back the number of arc/edge sections in the file. + /// + /// Gives back the number of arc/edge sections in the file. + /// \note It is synonym of \c edgeSectionNum(). + int arcSectionNum() const { + return _edge_sections.size(); + } + + /// \brief Returns the arc/edge section name at the given position. + /// + /// Returns the arc/edge section name at the given position. + /// \note It is synonym of \c edgeSection(). + const std::string& arcSection(int i) const { + return _edge_sections[i]; + } + + /// \brief Gives back the arc/edge maps for the given section. + /// + /// Gives back the arc/edge maps for the given section. + /// \note It is synonym of \c edgeMapNames(). + const std::vector& arcMapNames(int i) const { + return _edge_maps[i]; + } + + /// @} + + /// \name Synonyms + /// @{ + + /// \brief Gives back the number of arc/edge sections in the file. + /// + /// Gives back the number of arc/edge sections in the file. + /// \note It is synonym of \c arcSectionNum(). + int edgeSectionNum() const { + return _edge_sections.size(); + } + + /// \brief Returns the section name at the given position. + /// + /// Returns the section name at the given position. + /// \note It is synonym of \c arcSection(). + const std::string& edgeSection(int i) const { + return _edge_sections[i]; + } + + /// \brief Gives back the edge maps for the given section. + /// + /// Gives back the edge maps for the given section. + /// \note It is synonym of \c arcMapNames(). + const std::vector& edgeMapNames(int i) const { + return _edge_maps[i]; + } + + /// @} + + /// \name Attribute Sections + /// @{ + + /// \brief Gives back the number of attribute sections in the file. + /// + /// Gives back the number of attribute sections in the file. + int attributeSectionNum() const { + return _attribute_sections.size(); + } + + /// \brief Returns the attribute section name at the given position. + /// + /// Returns the attribute section name at the given position. + const std::string& attributeSectionNames(int i) const { + return _attribute_sections[i]; + } + + /// \brief Gives back the attributes for the given section. + /// + /// Gives back the attributes for the given section. + const std::vector& attributes(int i) const { + return _attributes[i]; + } + + /// @} + + /// \name Extra Sections + /// @{ + + /// \brief Gives back the number of extra sections in the file. + /// + /// Gives back the number of extra sections in the file. + int extraSectionNum() const { + return _extra_sections.size(); + } + + /// \brief Returns the extra section type at the given position. + /// + /// Returns the section type at the given position. + const std::string& extraSection(int i) const { + return _extra_sections[i]; + } + + /// @} + + private: + + bool readLine() { + std::string str; + while(++line_num, std::getline(*_is, str)) { + line.clear(); line.str(str); + char c; + if (line >> std::ws >> c && c != '#') { + line.putback(c); + return true; + } + } + return false; + } + + bool readSuccess() { + return static_cast(*_is); + } + + void skipSection() { + char c; + while (readSuccess() && line >> c && c != '@') { + readLine(); + } + if (readSuccess()) { + line.putback(c); + } + } + + void readMaps(std::vector& maps) { + char c; + if (!readLine() || !(line >> c) || c == '@') { + if (readSuccess() && line) line.putback(c); + return; + } + line.putback(c); + std::string map; + while (_reader_bits::readToken(line, map)) { + maps.push_back(map); + } + } + + void readAttributes(std::vector& attrs) { + readLine(); + char c; + while (readSuccess() && line >> c && c != '@') { + line.putback(c); + std::string attr; + _reader_bits::readToken(line, attr); + attrs.push_back(attr); + readLine(); + } + line.putback(c); + } + + public: + + /// \name Execution of the Contents Reader + /// @{ + + /// \brief Starts the reading + /// + /// This function starts the reading. + void run() { + + readLine(); + skipSection(); + + while (readSuccess()) { + + char c; + line >> c; + + std::string section, caption; + _reader_bits::readToken(line, section); + _reader_bits::readToken(line, caption); + + if (section == "nodes") { + _node_sections.push_back(caption); + _node_maps.push_back(std::vector()); + readMaps(_node_maps.back()); + readLine(); skipSection(); + } else if (section == "arcs" || section == "edges") { + _edge_sections.push_back(caption); + _arc_sections.push_back(section == "arcs"); + _edge_maps.push_back(std::vector()); + readMaps(_edge_maps.back()); + readLine(); skipSection(); + } else if (section == "attributes") { + _attribute_sections.push_back(caption); + _attributes.push_back(std::vector()); + readAttributes(_attributes.back()); + } else { + _extra_sections.push_back(section); + readLine(); skipSection(); + } + } + } + + /// @} + + }; +} + +#endif diff --git a/lemon/lemon/lgf_writer.h b/lemon/lemon/lgf_writer.h new file mode 100644 index 0000000..fab65f1 --- /dev/null +++ b/lemon/lemon/lgf_writer.h @@ -0,0 +1,1835 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup lemon_io +///\file +///\brief \ref lgf-format "LEMON Graph Format" writer. + + +#ifndef LEMON_LGF_WRITER_H +#define LEMON_LGF_WRITER_H + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include + +namespace lemon { + + namespace _writer_bits { + + template + struct DefaultConverter { + std::string operator()(const Value& value) { + std::ostringstream os; + os << value; + return os.str(); + } + }; + + template + bool operator<(const T&, const T&) { + throw FormatError("Label map is not comparable"); + } + + template + class MapLess { + public: + typedef _Map Map; + typedef typename Map::Key Item; + + private: + const Map& _map; + + public: + MapLess(const Map& map) : _map(map) {} + + bool operator()(const Item& left, const Item& right) { + return _map[left] < _map[right]; + } + }; + + template + class GraphArcMapLess { + public: + typedef _Map Map; + typedef _Graph Graph; + typedef typename Graph::Edge Item; + + private: + const Graph& _graph; + const Map& _map; + + public: + GraphArcMapLess(const Graph& graph, const Map& map) + : _graph(graph), _map(map) {} + + bool operator()(const Item& left, const Item& right) { + return _map[_graph.direct(left, _dir)] < + _map[_graph.direct(right, _dir)]; + } + }; + + template + class MapStorageBase { + public: + typedef _Item Item; + + public: + MapStorageBase() {} + virtual ~MapStorageBase() {} + + virtual std::string get(const Item& item) = 0; + virtual void sort(std::vector&) = 0; + }; + + template > + class MapStorage : public MapStorageBase<_Item> { + public: + typedef _Map Map; + typedef _Converter Converter; + typedef _Item Item; + + private: + const Map& _map; + Converter _converter; + + public: + MapStorage(const Map& map, const Converter& converter = Converter()) + : _map(map), _converter(converter) {} + virtual ~MapStorage() {} + + virtual std::string get(const Item& item) { + return _converter(_map[item]); + } + virtual void sort(std::vector& items) { + MapLess less(_map); + std::sort(items.begin(), items.end(), less); + } + }; + + template > + class GraphArcMapStorage : public MapStorageBase { + public: + typedef _Map Map; + typedef _Converter Converter; + typedef _Graph Graph; + typedef typename Graph::Edge Item; + static const bool dir = _dir; + + private: + const Graph& _graph; + const Map& _map; + Converter _converter; + + public: + GraphArcMapStorage(const Graph& graph, const Map& map, + const Converter& converter = Converter()) + : _graph(graph), _map(map), _converter(converter) {} + virtual ~GraphArcMapStorage() {} + + virtual std::string get(const Item& item) { + return _converter(_map[_graph.direct(item, dir)]); + } + virtual void sort(std::vector& items) { + GraphArcMapLess less(_graph, _map); + std::sort(items.begin(), items.end(), less); + } + }; + + class ValueStorageBase { + public: + ValueStorageBase() {} + virtual ~ValueStorageBase() {} + + virtual std::string get() = 0; + }; + + template > + class ValueStorage : public ValueStorageBase { + public: + typedef _Value Value; + typedef _Converter Converter; + + private: + const Value& _value; + Converter _converter; + + public: + ValueStorage(const Value& value, const Converter& converter = Converter()) + : _value(value), _converter(converter) {} + + virtual std::string get() { + return _converter(_value); + } + }; + + template + struct MapLookUpConverter { + const std::map& _map; + + MapLookUpConverter(const std::map& map) + : _map(map) {} + + std::string operator()(const Value& str) { + typename std::map::const_iterator it = + _map.find(str); + if (it == _map.end()) { + throw FormatError("Item not found"); + } + return it->second; + } + }; + + template + struct GraphArcLookUpConverter { + const Graph& _graph; + const std::map& _map; + + GraphArcLookUpConverter(const Graph& graph, + const std::map& map) + : _graph(graph), _map(map) {} + + std::string operator()(const typename Graph::Arc& val) { + typename std::map + ::const_iterator it = _map.find(val); + if (it == _map.end()) { + throw FormatError("Item not found"); + } + return (_graph.direction(val) ? '+' : '-') + it->second; + } + }; + + inline bool isWhiteSpace(char c) { + return c == ' ' || c == '\t' || c == '\v' || + c == '\n' || c == '\r' || c == '\f'; + } + + inline bool isEscaped(char c) { + return c == '\\' || c == '\"' || c == '\'' || + c == '\a' || c == '\b'; + } + + inline static void writeEscape(std::ostream& os, char c) { + switch (c) { + case '\\': + os << "\\\\"; + return; + case '\"': + os << "\\\""; + return; + case '\a': + os << "\\a"; + return; + case '\b': + os << "\\b"; + return; + case '\f': + os << "\\f"; + return; + case '\r': + os << "\\r"; + return; + case '\n': + os << "\\n"; + return; + case '\t': + os << "\\t"; + return; + case '\v': + os << "\\v"; + return; + default: + if (c < 0x20) { + std::ios::fmtflags flags = os.flags(); + os << '\\' << std::oct << static_cast(c); + os.flags(flags); + } else { + os << c; + } + return; + } + } + + inline bool requireEscape(const std::string& str) { + if (str.empty() || str[0] == '@') return true; + std::istringstream is(str); + char c; + while (is.get(c)) { + if (isWhiteSpace(c) || isEscaped(c)) { + return true; + } + } + return false; + } + + inline std::ostream& writeToken(std::ostream& os, const std::string& str) { + + if (requireEscape(str)) { + os << '\"'; + for (std::string::const_iterator it = str.begin(); + it != str.end(); ++it) { + writeEscape(os, *it); + } + os << '\"'; + } else { + os << str; + } + return os; + } + + class Section { + public: + virtual ~Section() {} + virtual void process(std::ostream& os) = 0; + }; + + template + class LineSection : public Section { + private: + + Functor _functor; + + public: + + LineSection(const Functor& functor) : _functor(functor) {} + virtual ~LineSection() {} + + virtual void process(std::ostream& os) { + std::string line; + while (!(line = _functor()).empty()) os << line << std::endl; + } + }; + + template + class StreamSection : public Section { + private: + + Functor _functor; + + public: + + StreamSection(const Functor& functor) : _functor(functor) {} + virtual ~StreamSection() {} + + virtual void process(std::ostream& os) { + _functor(os); + } + }; + + } + + template + class DigraphWriter; + + template + DigraphWriter digraphWriter(const TDGR& digraph, + std::ostream& os = std::cout); + template + DigraphWriter digraphWriter(const TDGR& digraph, const std::string& fn); + + template + DigraphWriter digraphWriter(const TDGR& digraph, const char* fn); + + + /// \ingroup lemon_io + /// + /// \brief \ref lgf-format "LGF" writer for directed graphs + /// + /// This utility writes an \ref lgf-format "LGF" file. + /// + /// The writing method does a batch processing. The user creates a + /// writer object, then various writing rules can be added to the + /// writer, and eventually the writing is executed with the \c run() + /// member function. A map writing rule can be added to the writer + /// with the \c nodeMap() or \c arcMap() members. An optional + /// converter parameter can also be added as a standard functor + /// converting from the value type of the map to \c std::string. If it + /// is set, it will determine how the value type of the map is written to + /// the output stream. If the functor is not set, then a default + /// conversion will be used. The \c attribute(), \c node() and \c + /// arc() functions are used to add attribute writing rules. + /// + ///\code + /// DigraphWriter(digraph, std::cout). + /// nodeMap("coordinates", coord_map). + /// nodeMap("size", size). + /// nodeMap("title", title). + /// arcMap("capacity", cap_map). + /// node("source", src). + /// node("target", trg). + /// attribute("caption", caption). + /// run(); + ///\endcode + /// + /// + /// By default, the writer does not write additional captions to the + /// sections, but they can be give as an optional parameter of + /// the \c nodes(), \c arcs() or \c + /// attributes() functions. + /// + /// The \c skipNodes() and \c skipArcs() functions forbid the + /// writing of the sections. If two arc sections should be written + /// to the output, it can be done in two passes, the first pass + /// writes the node section and the first arc section, then the + /// second pass skips the node section and writes just the arc + /// section to the stream. The output stream can be retrieved with + /// the \c ostream() function, hence the second pass can append its + /// output to the output of the first pass. + template + class DigraphWriter { + public: + + typedef DGR Digraph; + TEMPLATE_DIGRAPH_TYPEDEFS(DGR); + + private: + + + std::ostream* _os; + bool local_os; + + const DGR& _digraph; + + std::string _nodes_caption; + std::string _arcs_caption; + std::string _attributes_caption; + + typedef std::map NodeIndex; + NodeIndex _node_index; + typedef std::map ArcIndex; + ArcIndex _arc_index; + + typedef std::vector* > > NodeMaps; + NodeMaps _node_maps; + + typedef std::vector* > >ArcMaps; + ArcMaps _arc_maps; + + typedef std::vector > Attributes; + Attributes _attributes; + + bool _skip_nodes; + bool _skip_arcs; + + public: + + /// \brief Constructor + /// + /// Construct a directed graph writer, which writes to the given + /// output stream. + DigraphWriter(const DGR& digraph, std::ostream& os = std::cout) + : _os(&os), local_os(false), _digraph(digraph), + _skip_nodes(false), _skip_arcs(false) {} + + /// \brief Constructor + /// + /// Construct a directed graph writer, which writes to the given + /// output file. + DigraphWriter(const DGR& digraph, const std::string& fn) + : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph), + _skip_nodes(false), _skip_arcs(false) { + if (!(*_os)) { + delete _os; + throw IoError("Cannot write file", fn); + } + } + + /// \brief Constructor + /// + /// Construct a directed graph writer, which writes to the given + /// output file. + DigraphWriter(const DGR& digraph, const char* fn) + : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph), + _skip_nodes(false), _skip_arcs(false) { + if (!(*_os)) { + delete _os; + throw IoError("Cannot write file", fn); + } + } + + /// \brief Destructor + ~DigraphWriter() { + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + delete it->second; + } + + for (typename ArcMaps::iterator it = _arc_maps.begin(); + it != _arc_maps.end(); ++it) { + delete it->second; + } + + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + delete it->second; + } + + if (local_os) { + delete _os; + } + } + + private: + + template + friend DigraphWriter digraphWriter(const TDGR& digraph, + std::ostream& os); + template + friend DigraphWriter digraphWriter(const TDGR& digraph, + const std::string& fn); + template + friend DigraphWriter digraphWriter(const TDGR& digraph, + const char *fn); + + DigraphWriter(DigraphWriter& other) + : _os(other._os), local_os(other.local_os), _digraph(other._digraph), + _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) { + + other._os = 0; + other.local_os = false; + + _node_index.swap(other._node_index); + _arc_index.swap(other._arc_index); + + _node_maps.swap(other._node_maps); + _arc_maps.swap(other._arc_maps); + _attributes.swap(other._attributes); + + _nodes_caption = other._nodes_caption; + _arcs_caption = other._arcs_caption; + _attributes_caption = other._attributes_caption; + } + + DigraphWriter& operator=(const DigraphWriter&); + + public: + + /// \name Writing Rules + /// @{ + + /// \brief Node map writing rule + /// + /// Add a node map writing rule to the writer. + template + DigraphWriter& nodeMap(const std::string& caption, const Map& map) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node map writing rule + /// + /// Add a node map writing rule with specialized converter to the + /// writer. + template + DigraphWriter& nodeMap(const std::string& caption, const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map, converter); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc map writing rule + /// + /// Add an arc map writing rule to the writer. + template + DigraphWriter& arcMap(const std::string& caption, const Map& map) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map); + _arc_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc map writing rule + /// + /// Add an arc map writing rule with specialized converter to the + /// writer. + template + DigraphWriter& arcMap(const std::string& caption, const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map, converter); + _arc_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Attribute writing rule + /// + /// Add an attribute writing rule to the writer. + template + DigraphWriter& attribute(const std::string& caption, const Value& value) { + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(value); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Attribute writing rule + /// + /// Add an attribute writing rule with specialized converter to the + /// writer. + template + DigraphWriter& attribute(const std::string& caption, const Value& value, + const Converter& converter = Converter()) { + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(value, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node writing rule + /// + /// Add a node writing rule to the writer. + DigraphWriter& node(const std::string& caption, const Node& node) { + typedef _writer_bits::MapLookUpConverter Converter; + Converter converter(_node_index); + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(node, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc writing rule + /// + /// Add an arc writing rule to writer. + DigraphWriter& arc(const std::string& caption, const Arc& arc) { + typedef _writer_bits::MapLookUpConverter Converter; + Converter converter(_arc_index); + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(arc, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \name Section Captions + /// @{ + + /// \brief Add an additional caption to the \c \@nodes section + /// + /// Add an additional caption to the \c \@nodes section. + DigraphWriter& nodes(const std::string& caption) { + _nodes_caption = caption; + return *this; + } + + /// \brief Add an additional caption to the \c \@arcs section + /// + /// Add an additional caption to the \c \@arcs section. + DigraphWriter& arcs(const std::string& caption) { + _arcs_caption = caption; + return *this; + } + + /// \brief Add an additional caption to the \c \@attributes section + /// + /// Add an additional caption to the \c \@attributes section. + DigraphWriter& attributes(const std::string& caption) { + _attributes_caption = caption; + return *this; + } + + /// \name Skipping Section + /// @{ + + /// \brief Skip writing the node set + /// + /// The \c \@nodes section will not be written to the stream. + DigraphWriter& skipNodes() { + LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member"); + _skip_nodes = true; + return *this; + } + + /// \brief Skip writing arc set + /// + /// The \c \@arcs section will not be written to the stream. + DigraphWriter& skipArcs() { + LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member"); + _skip_arcs = true; + return *this; + } + + /// @} + + private: + + void writeNodes() { + _writer_bits::MapStorageBase* label = 0; + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + *_os << "@nodes"; + if (!_nodes_caption.empty()) { + _writer_bits::writeToken(*_os << ' ', _nodes_caption); + } + *_os << std::endl; + + if (label == 0) { + *_os << "label" << '\t'; + } + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + _writer_bits::writeToken(*_os, it->first) << '\t'; + } + *_os << std::endl; + + std::vector nodes; + for (NodeIt n(_digraph); n != INVALID; ++n) { + nodes.push_back(n); + } + + if (label == 0) { + IdMap id_map(_digraph); + _writer_bits::MapLess > id_less(id_map); + std::sort(nodes.begin(), nodes.end(), id_less); + } else { + label->sort(nodes); + } + + for (int i = 0; i < static_cast(nodes.size()); ++i) { + Node n = nodes[i]; + if (label == 0) { + std::ostringstream os; + os << _digraph.id(n); + _writer_bits::writeToken(*_os, os.str()); + *_os << '\t'; + _node_index.insert(std::make_pair(n, os.str())); + } + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + std::string value = it->second->get(n); + _writer_bits::writeToken(*_os, value); + if (it->first == "label") { + _node_index.insert(std::make_pair(n, value)); + } + *_os << '\t'; + } + *_os << std::endl; + } + } + + void createNodeIndex() { + _writer_bits::MapStorageBase* label = 0; + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + if (label == 0) { + for (NodeIt n(_digraph); n != INVALID; ++n) { + std::ostringstream os; + os << _digraph.id(n); + _node_index.insert(std::make_pair(n, os.str())); + } + } else { + for (NodeIt n(_digraph); n != INVALID; ++n) { + std::string value = label->get(n); + _node_index.insert(std::make_pair(n, value)); + } + } + } + + void writeArcs() { + _writer_bits::MapStorageBase* label = 0; + for (typename ArcMaps::iterator it = _arc_maps.begin(); + it != _arc_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + *_os << "@arcs"; + if (!_arcs_caption.empty()) { + _writer_bits::writeToken(*_os << ' ', _arcs_caption); + } + *_os << std::endl; + + *_os << '\t' << '\t'; + if (label == 0) { + *_os << "label" << '\t'; + } + for (typename ArcMaps::iterator it = _arc_maps.begin(); + it != _arc_maps.end(); ++it) { + _writer_bits::writeToken(*_os, it->first) << '\t'; + } + *_os << std::endl; + + std::vector arcs; + for (ArcIt n(_digraph); n != INVALID; ++n) { + arcs.push_back(n); + } + + if (label == 0) { + IdMap id_map(_digraph); + _writer_bits::MapLess > id_less(id_map); + std::sort(arcs.begin(), arcs.end(), id_less); + } else { + label->sort(arcs); + } + + for (int i = 0; i < static_cast(arcs.size()); ++i) { + Arc a = arcs[i]; + _writer_bits::writeToken(*_os, _node_index. + find(_digraph.source(a))->second); + *_os << '\t'; + _writer_bits::writeToken(*_os, _node_index. + find(_digraph.target(a))->second); + *_os << '\t'; + if (label == 0) { + std::ostringstream os; + os << _digraph.id(a); + _writer_bits::writeToken(*_os, os.str()); + *_os << '\t'; + _arc_index.insert(std::make_pair(a, os.str())); + } + for (typename ArcMaps::iterator it = _arc_maps.begin(); + it != _arc_maps.end(); ++it) { + std::string value = it->second->get(a); + _writer_bits::writeToken(*_os, value); + if (it->first == "label") { + _arc_index.insert(std::make_pair(a, value)); + } + *_os << '\t'; + } + *_os << std::endl; + } + } + + void createArcIndex() { + _writer_bits::MapStorageBase* label = 0; + for (typename ArcMaps::iterator it = _arc_maps.begin(); + it != _arc_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + if (label == 0) { + for (ArcIt a(_digraph); a != INVALID; ++a) { + std::ostringstream os; + os << _digraph.id(a); + _arc_index.insert(std::make_pair(a, os.str())); + } + } else { + for (ArcIt a(_digraph); a != INVALID; ++a) { + std::string value = label->get(a); + _arc_index.insert(std::make_pair(a, value)); + } + } + } + + void writeAttributes() { + if (_attributes.empty()) return; + *_os << "@attributes"; + if (!_attributes_caption.empty()) { + _writer_bits::writeToken(*_os << ' ', _attributes_caption); + } + *_os << std::endl; + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + _writer_bits::writeToken(*_os, it->first) << ' '; + _writer_bits::writeToken(*_os, it->second->get()); + *_os << std::endl; + } + } + + public: + + /// \name Execution of the Writer + /// @{ + + /// \brief Start the batch processing + /// + /// This function starts the batch processing. + void run() { + if (!_skip_nodes) { + writeNodes(); + } else { + createNodeIndex(); + } + if (!_skip_arcs) { + writeArcs(); + } else { + createArcIndex(); + } + writeAttributes(); + } + + /// \brief Give back the stream of the writer + /// + /// Give back the stream of the writer. + std::ostream& ostream() { + return *_os; + } + + /// @} + }; + + /// \ingroup lemon_io + /// + /// \brief Return a \ref DigraphWriter class + /// + /// This function just returns a \ref DigraphWriter class. + /// + /// With this function a digraph can be write to a file or output + /// stream in \ref lgf-format "LGF" format with several maps and + /// attributes. For example, with the following code a network flow + /// problem can be written to the standard output, i.e. a digraph + /// with a \e capacity map on the arcs and \e source and \e target + /// nodes: + /// + ///\code + ///ListDigraph digraph; + ///ListDigraph::ArcMap cap(digraph); + ///ListDigraph::Node src, trg; + /// // Setting the capacity map and source and target nodes + ///digraphWriter(digraph, std::cout). + /// arcMap("capacity", cap). + /// node("source", src). + /// node("target", trg). + /// run(); + ///\endcode + /// + /// For a complete documentation, please see the \ref DigraphWriter + /// class documentation. + /// \warning Don't forget to put the \ref DigraphWriter::run() "run()" + /// to the end of the parameter list. + /// \relates DigraphWriter + /// \sa digraphWriter(const TDGR& digraph, const std::string& fn) + /// \sa digraphWriter(const TDGR& digraph, const char* fn) + template + DigraphWriter digraphWriter(const TDGR& digraph, std::ostream& os) { + DigraphWriter tmp(digraph, os); + return tmp; + } + + /// \brief Return a \ref DigraphWriter class + /// + /// This function just returns a \ref DigraphWriter class. + /// \relates DigraphWriter + /// \sa digraphWriter(const TDGR& digraph, std::ostream& os) + template + DigraphWriter digraphWriter(const TDGR& digraph, + const std::string& fn) { + DigraphWriter tmp(digraph, fn); + return tmp; + } + + /// \brief Return a \ref DigraphWriter class + /// + /// This function just returns a \ref DigraphWriter class. + /// \relates DigraphWriter + /// \sa digraphWriter(const TDGR& digraph, std::ostream& os) + template + DigraphWriter digraphWriter(const TDGR& digraph, const char* fn) { + DigraphWriter tmp(digraph, fn); + return tmp; + } + + template + class GraphWriter; + + template + GraphWriter graphWriter(const TGR& graph, std::ostream& os = std::cout); + template + GraphWriter graphWriter(const TGR& graph, const std::string& fn); + template + GraphWriter graphWriter(const TGR& graph, const char* fn); + + /// \ingroup lemon_io + /// + /// \brief \ref lgf-format "LGF" writer for directed graphs + /// + /// This utility writes an \ref lgf-format "LGF" file. + /// + /// It can be used almost the same way as \c DigraphWriter. + /// The only difference is that this class can handle edges and + /// edge maps as well as arcs and arc maps. + /// + /// The arc maps are written into the file as two columns, the + /// caption of the columns are the name of the map prefixed with \c + /// '+' and \c '-'. The arcs are written into the \c \@attributes + /// section as a \c '+' or a \c '-' prefix (depends on the direction + /// of the arc) and the label of corresponding edge. + template + class GraphWriter { + public: + + typedef GR Graph; + TEMPLATE_GRAPH_TYPEDEFS(GR); + + private: + + + std::ostream* _os; + bool local_os; + + const GR& _graph; + + std::string _nodes_caption; + std::string _edges_caption; + std::string _attributes_caption; + + typedef std::map NodeIndex; + NodeIndex _node_index; + typedef std::map EdgeIndex; + EdgeIndex _edge_index; + + typedef std::vector* > > NodeMaps; + NodeMaps _node_maps; + + typedef std::vector* > >EdgeMaps; + EdgeMaps _edge_maps; + + typedef std::vector > Attributes; + Attributes _attributes; + + bool _skip_nodes; + bool _skip_edges; + + public: + + /// \brief Constructor + /// + /// Construct a directed graph writer, which writes to the given + /// output stream. + GraphWriter(const GR& graph, std::ostream& os = std::cout) + : _os(&os), local_os(false), _graph(graph), + _skip_nodes(false), _skip_edges(false) {} + + /// \brief Constructor + /// + /// Construct a directed graph writer, which writes to the given + /// output file. + GraphWriter(const GR& graph, const std::string& fn) + : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph), + _skip_nodes(false), _skip_edges(false) { + if (!(*_os)) { + delete _os; + throw IoError("Cannot write file", fn); + } + } + + /// \brief Constructor + /// + /// Construct a directed graph writer, which writes to the given + /// output file. + GraphWriter(const GR& graph, const char* fn) + : _os(new std::ofstream(fn)), local_os(true), _graph(graph), + _skip_nodes(false), _skip_edges(false) { + if (!(*_os)) { + delete _os; + throw IoError("Cannot write file", fn); + } + } + + /// \brief Destructor + ~GraphWriter() { + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + delete it->second; + } + + for (typename EdgeMaps::iterator it = _edge_maps.begin(); + it != _edge_maps.end(); ++it) { + delete it->second; + } + + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + delete it->second; + } + + if (local_os) { + delete _os; + } + } + + private: + + template + friend GraphWriter graphWriter(const TGR& graph, std::ostream& os); + template + friend GraphWriter graphWriter(const TGR& graph, + const std::string& fn); + template + friend GraphWriter graphWriter(const TGR& graph, const char *fn); + + GraphWriter(GraphWriter& other) + : _os(other._os), local_os(other.local_os), _graph(other._graph), + _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) { + + other._os = 0; + other.local_os = false; + + _node_index.swap(other._node_index); + _edge_index.swap(other._edge_index); + + _node_maps.swap(other._node_maps); + _edge_maps.swap(other._edge_maps); + _attributes.swap(other._attributes); + + _nodes_caption = other._nodes_caption; + _edges_caption = other._edges_caption; + _attributes_caption = other._attributes_caption; + } + + GraphWriter& operator=(const GraphWriter&); + + public: + + /// \name Writing Rules + /// @{ + + /// \brief Node map writing rule + /// + /// Add a node map writing rule to the writer. + template + GraphWriter& nodeMap(const std::string& caption, const Map& map) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node map writing rule + /// + /// Add a node map writing rule with specialized converter to the + /// writer. + template + GraphWriter& nodeMap(const std::string& caption, const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map, converter); + _node_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Edge map writing rule + /// + /// Add an edge map writing rule to the writer. + template + GraphWriter& edgeMap(const std::string& caption, const Map& map) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map); + _edge_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Edge map writing rule + /// + /// Add an edge map writing rule with specialized converter to the + /// writer. + template + GraphWriter& edgeMap(const std::string& caption, const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* storage = + new _writer_bits::MapStorage(map, converter); + _edge_maps.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc map writing rule + /// + /// Add an arc map writing rule to the writer. + template + GraphWriter& arcMap(const std::string& caption, const Map& map) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* forward_storage = + new _writer_bits::GraphArcMapStorage(_graph, map); + _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); + _writer_bits::MapStorageBase* backward_storage = + new _writer_bits::GraphArcMapStorage(_graph, map); + _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); + return *this; + } + + /// \brief Arc map writing rule + /// + /// Add an arc map writing rule with specialized converter to the + /// writer. + template + GraphWriter& arcMap(const std::string& caption, const Map& map, + const Converter& converter = Converter()) { + checkConcept, Map>(); + _writer_bits::MapStorageBase* forward_storage = + new _writer_bits::GraphArcMapStorage + (_graph, map, converter); + _edge_maps.push_back(std::make_pair('+' + caption, forward_storage)); + _writer_bits::MapStorageBase* backward_storage = + new _writer_bits::GraphArcMapStorage + (_graph, map, converter); + _edge_maps.push_back(std::make_pair('-' + caption, backward_storage)); + return *this; + } + + /// \brief Attribute writing rule + /// + /// Add an attribute writing rule to the writer. + template + GraphWriter& attribute(const std::string& caption, const Value& value) { + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(value); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Attribute writing rule + /// + /// Add an attribute writing rule with specialized converter to the + /// writer. + template + GraphWriter& attribute(const std::string& caption, const Value& value, + const Converter& converter = Converter()) { + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(value, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Node writing rule + /// + /// Add a node writing rule to the writer. + GraphWriter& node(const std::string& caption, const Node& node) { + typedef _writer_bits::MapLookUpConverter Converter; + Converter converter(_node_index); + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(node, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Edge writing rule + /// + /// Add an edge writing rule to writer. + GraphWriter& edge(const std::string& caption, const Edge& edge) { + typedef _writer_bits::MapLookUpConverter Converter; + Converter converter(_edge_index); + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(edge, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \brief Arc writing rule + /// + /// Add an arc writing rule to writer. + GraphWriter& arc(const std::string& caption, const Arc& arc) { + typedef _writer_bits::GraphArcLookUpConverter Converter; + Converter converter(_graph, _edge_index); + _writer_bits::ValueStorageBase* storage = + new _writer_bits::ValueStorage(arc, converter); + _attributes.push_back(std::make_pair(caption, storage)); + return *this; + } + + /// \name Section Captions + /// @{ + + /// \brief Add an additional caption to the \c \@nodes section + /// + /// Add an additional caption to the \c \@nodes section. + GraphWriter& nodes(const std::string& caption) { + _nodes_caption = caption; + return *this; + } + + /// \brief Add an additional caption to the \c \@arcs section + /// + /// Add an additional caption to the \c \@arcs section. + GraphWriter& edges(const std::string& caption) { + _edges_caption = caption; + return *this; + } + + /// \brief Add an additional caption to the \c \@attributes section + /// + /// Add an additional caption to the \c \@attributes section. + GraphWriter& attributes(const std::string& caption) { + _attributes_caption = caption; + return *this; + } + + /// \name Skipping Section + /// @{ + + /// \brief Skip writing the node set + /// + /// The \c \@nodes section will not be written to the stream. + GraphWriter& skipNodes() { + LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member"); + _skip_nodes = true; + return *this; + } + + /// \brief Skip writing edge set + /// + /// The \c \@edges section will not be written to the stream. + GraphWriter& skipEdges() { + LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member"); + _skip_edges = true; + return *this; + } + + /// @} + + private: + + void writeNodes() { + _writer_bits::MapStorageBase* label = 0; + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + *_os << "@nodes"; + if (!_nodes_caption.empty()) { + _writer_bits::writeToken(*_os << ' ', _nodes_caption); + } + *_os << std::endl; + + if (label == 0) { + *_os << "label" << '\t'; + } + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + _writer_bits::writeToken(*_os, it->first) << '\t'; + } + *_os << std::endl; + + std::vector nodes; + for (NodeIt n(_graph); n != INVALID; ++n) { + nodes.push_back(n); + } + + if (label == 0) { + IdMap id_map(_graph); + _writer_bits::MapLess > id_less(id_map); + std::sort(nodes.begin(), nodes.end(), id_less); + } else { + label->sort(nodes); + } + + for (int i = 0; i < static_cast(nodes.size()); ++i) { + Node n = nodes[i]; + if (label == 0) { + std::ostringstream os; + os << _graph.id(n); + _writer_bits::writeToken(*_os, os.str()); + *_os << '\t'; + _node_index.insert(std::make_pair(n, os.str())); + } + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + std::string value = it->second->get(n); + _writer_bits::writeToken(*_os, value); + if (it->first == "label") { + _node_index.insert(std::make_pair(n, value)); + } + *_os << '\t'; + } + *_os << std::endl; + } + } + + void createNodeIndex() { + _writer_bits::MapStorageBase* label = 0; + for (typename NodeMaps::iterator it = _node_maps.begin(); + it != _node_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + if (label == 0) { + for (NodeIt n(_graph); n != INVALID; ++n) { + std::ostringstream os; + os << _graph.id(n); + _node_index.insert(std::make_pair(n, os.str())); + } + } else { + for (NodeIt n(_graph); n != INVALID; ++n) { + std::string value = label->get(n); + _node_index.insert(std::make_pair(n, value)); + } + } + } + + void writeEdges() { + _writer_bits::MapStorageBase* label = 0; + for (typename EdgeMaps::iterator it = _edge_maps.begin(); + it != _edge_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + *_os << "@edges"; + if (!_edges_caption.empty()) { + _writer_bits::writeToken(*_os << ' ', _edges_caption); + } + *_os << std::endl; + + *_os << '\t' << '\t'; + if (label == 0) { + *_os << "label" << '\t'; + } + for (typename EdgeMaps::iterator it = _edge_maps.begin(); + it != _edge_maps.end(); ++it) { + _writer_bits::writeToken(*_os, it->first) << '\t'; + } + *_os << std::endl; + + std::vector edges; + for (EdgeIt n(_graph); n != INVALID; ++n) { + edges.push_back(n); + } + + if (label == 0) { + IdMap id_map(_graph); + _writer_bits::MapLess > id_less(id_map); + std::sort(edges.begin(), edges.end(), id_less); + } else { + label->sort(edges); + } + + for (int i = 0; i < static_cast(edges.size()); ++i) { + Edge e = edges[i]; + _writer_bits::writeToken(*_os, _node_index. + find(_graph.u(e))->second); + *_os << '\t'; + _writer_bits::writeToken(*_os, _node_index. + find(_graph.v(e))->second); + *_os << '\t'; + if (label == 0) { + std::ostringstream os; + os << _graph.id(e); + _writer_bits::writeToken(*_os, os.str()); + *_os << '\t'; + _edge_index.insert(std::make_pair(e, os.str())); + } + for (typename EdgeMaps::iterator it = _edge_maps.begin(); + it != _edge_maps.end(); ++it) { + std::string value = it->second->get(e); + _writer_bits::writeToken(*_os, value); + if (it->first == "label") { + _edge_index.insert(std::make_pair(e, value)); + } + *_os << '\t'; + } + *_os << std::endl; + } + } + + void createEdgeIndex() { + _writer_bits::MapStorageBase* label = 0; + for (typename EdgeMaps::iterator it = _edge_maps.begin(); + it != _edge_maps.end(); ++it) { + if (it->first == "label") { + label = it->second; + break; + } + } + + if (label == 0) { + for (EdgeIt e(_graph); e != INVALID; ++e) { + std::ostringstream os; + os << _graph.id(e); + _edge_index.insert(std::make_pair(e, os.str())); + } + } else { + for (EdgeIt e(_graph); e != INVALID; ++e) { + std::string value = label->get(e); + _edge_index.insert(std::make_pair(e, value)); + } + } + } + + void writeAttributes() { + if (_attributes.empty()) return; + *_os << "@attributes"; + if (!_attributes_caption.empty()) { + _writer_bits::writeToken(*_os << ' ', _attributes_caption); + } + *_os << std::endl; + for (typename Attributes::iterator it = _attributes.begin(); + it != _attributes.end(); ++it) { + _writer_bits::writeToken(*_os, it->first) << ' '; + _writer_bits::writeToken(*_os, it->second->get()); + *_os << std::endl; + } + } + + public: + + /// \name Execution of the Writer + /// @{ + + /// \brief Start the batch processing + /// + /// This function starts the batch processing. + void run() { + if (!_skip_nodes) { + writeNodes(); + } else { + createNodeIndex(); + } + if (!_skip_edges) { + writeEdges(); + } else { + createEdgeIndex(); + } + writeAttributes(); + } + + /// \brief Give back the stream of the writer + /// + /// Give back the stream of the writer + std::ostream& ostream() { + return *_os; + } + + /// @} + }; + + /// \ingroup lemon_io + /// + /// \brief Return a \ref GraphWriter class + /// + /// This function just returns a \ref GraphWriter class. + /// + /// With this function a graph can be write to a file or output + /// stream in \ref lgf-format "LGF" format with several maps and + /// attributes. For example, with the following code a weighted + /// matching problem can be written to the standard output, i.e. a + /// graph with a \e weight map on the edges: + /// + ///\code + ///ListGraph graph; + ///ListGraph::EdgeMap weight(graph); + /// // Setting the weight map + ///graphWriter(graph, std::cout). + /// edgeMap("weight", weight). + /// run(); + ///\endcode + /// + /// For a complete documentation, please see the \ref GraphWriter + /// class documentation. + /// \warning Don't forget to put the \ref GraphWriter::run() "run()" + /// to the end of the parameter list. + /// \relates GraphWriter + /// \sa graphWriter(const TGR& graph, const std::string& fn) + /// \sa graphWriter(const TGR& graph, const char* fn) + template + GraphWriter graphWriter(const TGR& graph, std::ostream& os) { + GraphWriter tmp(graph, os); + return tmp; + } + + /// \brief Return a \ref GraphWriter class + /// + /// This function just returns a \ref GraphWriter class. + /// \relates GraphWriter + /// \sa graphWriter(const TGR& graph, std::ostream& os) + template + GraphWriter graphWriter(const TGR& graph, const std::string& fn) { + GraphWriter tmp(graph, fn); + return tmp; + } + + /// \brief Return a \ref GraphWriter class + /// + /// This function just returns a \ref GraphWriter class. + /// \relates GraphWriter + /// \sa graphWriter(const TGR& graph, std::ostream& os) + template + GraphWriter graphWriter(const TGR& graph, const char* fn) { + GraphWriter tmp(graph, fn); + return tmp; + } + + class SectionWriter; + + SectionWriter sectionWriter(std::istream& is); + SectionWriter sectionWriter(const std::string& fn); + SectionWriter sectionWriter(const char* fn); + + /// \ingroup lemon_io + /// + /// \brief Section writer class + /// + /// In the \ref lgf-format "LGF" file extra sections can be placed, + /// which contain any data in arbitrary format. Such sections can be + /// written with this class. A writing rule can be added to the + /// class with two different functions. With the \c sectionLines() + /// function a generator can write the section line-by-line, while + /// with the \c sectionStream() member the section can be written to + /// an output stream. + class SectionWriter { + private: + + std::ostream* _os; + bool local_os; + + typedef std::vector > + Sections; + + Sections _sections; + + public: + + /// \brief Constructor + /// + /// Construct a section writer, which writes to the given output + /// stream. + SectionWriter(std::ostream& os) + : _os(&os), local_os(false) {} + + /// \brief Constructor + /// + /// Construct a section writer, which writes into the given file. + SectionWriter(const std::string& fn) + : _os(new std::ofstream(fn.c_str())), local_os(true) { + if (!(*_os)) { + delete _os; + throw IoError("Cannot write file", fn); + } + } + + /// \brief Constructor + /// + /// Construct a section writer, which writes into the given file. + SectionWriter(const char* fn) + : _os(new std::ofstream(fn)), local_os(true) { + if (!(*_os)) { + delete _os; + throw IoError("Cannot write file", fn); + } + } + + /// \brief Destructor + ~SectionWriter() { + for (Sections::iterator it = _sections.begin(); + it != _sections.end(); ++it) { + delete it->second; + } + + if (local_os) { + delete _os; + } + + } + + private: + + friend SectionWriter sectionWriter(std::ostream& os); + friend SectionWriter sectionWriter(const std::string& fn); + friend SectionWriter sectionWriter(const char* fn); + + SectionWriter(SectionWriter& other) + : _os(other._os), local_os(other.local_os) { + + other._os = 0; + other.local_os = false; + + _sections.swap(other._sections); + } + + SectionWriter& operator=(const SectionWriter&); + + public: + + /// \name Section Writers + /// @{ + + /// \brief Add a section writer with line oriented writing + /// + /// The first parameter is the type descriptor of the section, the + /// second is a generator with std::string values. At the writing + /// process, the returned \c std::string will be written into the + /// output file until it is an empty string. + /// + /// For example, an integer vector is written into a section. + ///\code + /// @numbers + /// 12 45 23 78 + /// 4 28 38 28 + /// 23 6 16 + ///\endcode + /// + /// The generator is implemented as a struct. + ///\code + /// struct NumberSection { + /// std::vector::const_iterator _it, _end; + /// NumberSection(const std::vector& data) + /// : _it(data.begin()), _end(data.end()) {} + /// std::string operator()() { + /// int rem_in_line = 4; + /// std::ostringstream ls; + /// while (rem_in_line > 0 && _it != _end) { + /// ls << *(_it++) << ' '; + /// --rem_in_line; + /// } + /// return ls.str(); + /// } + /// }; + /// + /// // ... + /// + /// writer.sectionLines("numbers", NumberSection(vec)); + ///\endcode + template + SectionWriter& sectionLines(const std::string& type, Functor functor) { + LEMON_ASSERT(!type.empty(), "Type is empty."); + _sections.push_back(std::make_pair(type, + new _writer_bits::LineSection(functor))); + return *this; + } + + + /// \brief Add a section writer with stream oriented writing + /// + /// The first parameter is the type of the section, the second is + /// a functor, which takes a \c std::ostream& parameter. The + /// functor writes the section to the output stream. + /// \warning The last line must be closed with end-line character. + template + SectionWriter& sectionStream(const std::string& type, Functor functor) { + LEMON_ASSERT(!type.empty(), "Type is empty."); + _sections.push_back(std::make_pair(type, + new _writer_bits::StreamSection(functor))); + return *this; + } + + /// @} + + public: + + + /// \name Execution of the Writer + /// @{ + + /// \brief Start the batch processing + /// + /// This function starts the batch processing. + void run() { + + LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer"); + + for (Sections::iterator it = _sections.begin(); + it != _sections.end(); ++it) { + (*_os) << '@' << it->first << std::endl; + it->second->process(*_os); + } + } + + /// \brief Give back the stream of the writer + /// + /// Returns the stream of the writer + std::ostream& ostream() { + return *_os; + } + + /// @} + + }; + + /// \ingroup lemon_io + /// + /// \brief Return a \ref SectionWriter class + /// + /// This function just returns a \ref SectionWriter class. + /// + /// Please see SectionWriter documentation about the custom section + /// output. + /// + /// \relates SectionWriter + /// \sa sectionWriter(const std::string& fn) + /// \sa sectionWriter(const char *fn) + inline SectionWriter sectionWriter(std::ostream& os) { + SectionWriter tmp(os); + return tmp; + } + + /// \brief Return a \ref SectionWriter class + /// + /// This function just returns a \ref SectionWriter class. + /// \relates SectionWriter + /// \sa sectionWriter(std::ostream& os) + inline SectionWriter sectionWriter(const std::string& fn) { + SectionWriter tmp(fn); + return tmp; + } + + /// \brief Return a \ref SectionWriter class + /// + /// This function just returns a \ref SectionWriter class. + /// \relates SectionWriter + /// \sa sectionWriter(std::ostream& os) + inline SectionWriter sectionWriter(const char* fn) { + SectionWriter tmp(fn); + return tmp; + } +} + +#endif diff --git a/lemon/lemon/list_graph.h b/lemon/lemon/list_graph.h new file mode 100644 index 0000000..235aecc --- /dev/null +++ b/lemon/lemon/list_graph.h @@ -0,0 +1,1605 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_LIST_GRAPH_H +#define LEMON_LIST_GRAPH_H + +///\ingroup graphs +///\file +///\brief ListDigraph and ListGraph classes. + +#include +#include +#include + +#include +#include + +namespace lemon { + + class ListDigraph; + + class ListDigraphBase { + + protected: + struct NodeT { + int first_in, first_out; + int prev, next; + }; + + struct ArcT { + int target, source; + int prev_in, prev_out; + int next_in, next_out; + }; + + std::vector nodes; + + int first_node; + + int first_free_node; + + std::vector arcs; + + int first_free_arc; + + public: + + typedef ListDigraphBase Digraph; + + class Node { + friend class ListDigraphBase; + friend class ListDigraph; + protected: + + int id; + explicit Node(int pid) { id = pid;} + + public: + Node() {} + Node (Invalid) { id = -1; } + bool operator==(const Node& node) const {return id == node.id;} + bool operator!=(const Node& node) const {return id != node.id;} + bool operator<(const Node& node) const {return id < node.id;} + }; + + class Arc { + friend class ListDigraphBase; + friend class ListDigraph; + protected: + + int id; + explicit Arc(int pid) { id = pid;} + + public: + Arc() {} + Arc (Invalid) { id = -1; } + bool operator==(const Arc& arc) const {return id == arc.id;} + bool operator!=(const Arc& arc) const {return id != arc.id;} + bool operator<(const Arc& arc) const {return id < arc.id;} + }; + + + + ListDigraphBase() + : nodes(), first_node(-1), + first_free_node(-1), arcs(), first_free_arc(-1) {} + + + int maxNodeId() const { return nodes.size()-1; } + int maxArcId() const { return arcs.size()-1; } + + Node source(Arc e) const { return Node(arcs[e.id].source); } + Node target(Arc e) const { return Node(arcs[e.id].target); } + + + void first(Node& node) const { + node.id = first_node; + } + + void next(Node& node) const { + node.id = nodes[node.id].next; + } + + + void first(Arc& arc) const { + int n; + for(n = first_node; + n != -1 && nodes[n].first_out == -1; + n = nodes[n].next) {} + arc.id = (n == -1) ? -1 : nodes[n].first_out; + } + + void next(Arc& arc) const { + if (arcs[arc.id].next_out != -1) { + arc.id = arcs[arc.id].next_out; + } else { + int n; + for(n = nodes[arcs[arc.id].source].next; + n != -1 && nodes[n].first_out == -1; + n = nodes[n].next) {} + arc.id = (n == -1) ? -1 : nodes[n].first_out; + } + } + + void firstOut(Arc &e, const Node& v) const { + e.id = nodes[v.id].first_out; + } + void nextOut(Arc &e) const { + e.id=arcs[e.id].next_out; + } + + void firstIn(Arc &e, const Node& v) const { + e.id = nodes[v.id].first_in; + } + void nextIn(Arc &e) const { + e.id=arcs[e.id].next_in; + } + + + static int id(Node v) { return v.id; } + static int id(Arc e) { return e.id; } + + static Node nodeFromId(int id) { return Node(id);} + static Arc arcFromId(int id) { return Arc(id);} + + bool valid(Node n) const { + return n.id >= 0 && n.id < static_cast(nodes.size()) && + nodes[n.id].prev != -2; + } + + bool valid(Arc a) const { + return a.id >= 0 && a.id < static_cast(arcs.size()) && + arcs[a.id].prev_in != -2; + } + + Node addNode() { + int n; + + if(first_free_node==-1) { + n = nodes.size(); + nodes.push_back(NodeT()); + } else { + n = first_free_node; + first_free_node = nodes[n].next; + } + + nodes[n].next = first_node; + if(first_node != -1) nodes[first_node].prev = n; + first_node = n; + nodes[n].prev = -1; + + nodes[n].first_in = nodes[n].first_out = -1; + + return Node(n); + } + + Arc addArc(Node u, Node v) { + int n; + + if (first_free_arc == -1) { + n = arcs.size(); + arcs.push_back(ArcT()); + } else { + n = first_free_arc; + first_free_arc = arcs[n].next_in; + } + + arcs[n].source = u.id; + arcs[n].target = v.id; + + arcs[n].next_out = nodes[u.id].first_out; + if(nodes[u.id].first_out != -1) { + arcs[nodes[u.id].first_out].prev_out = n; + } + + arcs[n].next_in = nodes[v.id].first_in; + if(nodes[v.id].first_in != -1) { + arcs[nodes[v.id].first_in].prev_in = n; + } + + arcs[n].prev_in = arcs[n].prev_out = -1; + + nodes[u.id].first_out = nodes[v.id].first_in = n; + + return Arc(n); + } + + void erase(const Node& node) { + int n = node.id; + + if(nodes[n].next != -1) { + nodes[nodes[n].next].prev = nodes[n].prev; + } + + if(nodes[n].prev != -1) { + nodes[nodes[n].prev].next = nodes[n].next; + } else { + first_node = nodes[n].next; + } + + nodes[n].next = first_free_node; + first_free_node = n; + nodes[n].prev = -2; + + } + + void erase(const Arc& arc) { + int n = arc.id; + + if(arcs[n].next_in!=-1) { + arcs[arcs[n].next_in].prev_in = arcs[n].prev_in; + } + + if(arcs[n].prev_in!=-1) { + arcs[arcs[n].prev_in].next_in = arcs[n].next_in; + } else { + nodes[arcs[n].target].first_in = arcs[n].next_in; + } + + + if(arcs[n].next_out!=-1) { + arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; + } + + if(arcs[n].prev_out!=-1) { + arcs[arcs[n].prev_out].next_out = arcs[n].next_out; + } else { + nodes[arcs[n].source].first_out = arcs[n].next_out; + } + + arcs[n].next_in = first_free_arc; + first_free_arc = n; + arcs[n].prev_in = -2; + } + + void clear() { + arcs.clear(); + nodes.clear(); + first_node = first_free_node = first_free_arc = -1; + } + + protected: + void changeTarget(Arc e, Node n) + { + if(arcs[e.id].next_in != -1) + arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in; + if(arcs[e.id].prev_in != -1) + arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in; + else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in; + if (nodes[n.id].first_in != -1) { + arcs[nodes[n.id].first_in].prev_in = e.id; + } + arcs[e.id].target = n.id; + arcs[e.id].prev_in = -1; + arcs[e.id].next_in = nodes[n.id].first_in; + nodes[n.id].first_in = e.id; + } + void changeSource(Arc e, Node n) + { + if(arcs[e.id].next_out != -1) + arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out; + if(arcs[e.id].prev_out != -1) + arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out; + else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out; + if (nodes[n.id].first_out != -1) { + arcs[nodes[n.id].first_out].prev_out = e.id; + } + arcs[e.id].source = n.id; + arcs[e.id].prev_out = -1; + arcs[e.id].next_out = nodes[n.id].first_out; + nodes[n.id].first_out = e.id; + } + + }; + + typedef DigraphExtender ExtendedListDigraphBase; + + /// \addtogroup graphs + /// @{ + + ///A general directed graph structure. + + ///\ref ListDigraph is a versatile and fast directed graph + ///implementation based on linked lists that are stored in + ///\c std::vector structures. + /// + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept" + ///and it also provides several useful additional functionalities. + ///Most of its member functions and nested classes are documented + ///only in the concept class. + /// + ///This class provides only linear time counting for nodes and arcs. + /// + ///\sa concepts::Digraph + ///\sa ListGraph + class ListDigraph : public ExtendedListDigraphBase { + typedef ExtendedListDigraphBase Parent; + + private: + /// Digraphs are \e not copy constructible. Use DigraphCopy instead. + ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {}; + /// \brief Assignment of a digraph to another one is \e not allowed. + /// Use DigraphCopy instead. + void operator=(const ListDigraph &) {} + public: + + /// Constructor + + /// Constructor. + /// + ListDigraph() {} + + ///Add a new node to the digraph. + + ///This function adds a new node to the digraph. + ///\return The new node. + Node addNode() { return Parent::addNode(); } + + ///Add a new arc to the digraph. + + ///This function adds a new arc to the digraph with source node \c s + ///and target node \c t. + ///\return The new arc. + Arc addArc(Node s, Node t) { + return Parent::addArc(s, t); + } + + ///\brief Erase a node from the digraph. + /// + ///This function erases the given node along with its outgoing and + ///incoming arcs from the digraph. + /// + ///\note All iterators referencing the removed node or the connected + ///arcs are invalidated, of course. + void erase(Node n) { Parent::erase(n); } + + ///\brief Erase an arc from the digraph. + /// + ///This function erases the given arc from the digraph. + /// + ///\note All iterators referencing the removed arc are invalidated, + ///of course. + void erase(Arc a) { Parent::erase(a); } + + /// Node validity check + + /// This function gives back \c true if the given node is valid, + /// i.e. it is a real node of the digraph. + /// + /// \warning A removed node could become valid again if new nodes are + /// added to the digraph. + bool valid(Node n) const { return Parent::valid(n); } + + /// Arc validity check + + /// This function gives back \c true if the given arc is valid, + /// i.e. it is a real arc of the digraph. + /// + /// \warning A removed arc could become valid again if new arcs are + /// added to the digraph. + bool valid(Arc a) const { return Parent::valid(a); } + + /// Change the target node of an arc + + /// This function changes the target node of the given arc \c a to \c n. + /// + ///\note \c ArcIt and \c OutArcIt iterators referencing the changed + ///arc remain valid, but \c InArcIt iterators are invalidated. + /// + ///\warning This functionality cannot be used together with the Snapshot + ///feature. + void changeTarget(Arc a, Node n) { + Parent::changeTarget(a,n); + } + /// Change the source node of an arc + + /// This function changes the source node of the given arc \c a to \c n. + /// + ///\note \c InArcIt iterators referencing the changed arc remain + ///valid, but \c ArcIt and \c OutArcIt iterators are invalidated. + /// + ///\warning This functionality cannot be used together with the Snapshot + ///feature. + void changeSource(Arc a, Node n) { + Parent::changeSource(a,n); + } + + /// Reverse the direction of an arc. + + /// This function reverses the direction of the given arc. + ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing + ///the changed arc are invalidated. + /// + ///\warning This functionality cannot be used together with the Snapshot + ///feature. + void reverseArc(Arc a) { + Node t=target(a); + changeTarget(a,source(a)); + changeSource(a,t); + } + + ///Contract two nodes. + + ///This function contracts the given two nodes. + ///Node \c v is removed, but instead of deleting its + ///incident arcs, they are joined to node \c u. + ///If the last parameter \c r is \c true (this is the default value), + ///then the newly created loops are removed. + /// + ///\note The moved arcs are joined to node \c u using changeSource() + ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are + ///invalidated for the outgoing arcs of node \c v and \c InArcIt + ///iterators are invalidated for the incomming arcs of \c v. + ///Moreover all iterators referencing node \c v or the removed + ///loops are also invalidated. Other iterators remain valid. + /// + ///\warning This functionality cannot be used together with the Snapshot + ///feature. + void contract(Node u, Node v, bool r = true) + { + for(OutArcIt e(*this,v);e!=INVALID;) { + OutArcIt f=e; + ++f; + if(r && target(e)==u) erase(e); + else changeSource(e,u); + e=f; + } + for(InArcIt e(*this,v);e!=INVALID;) { + InArcIt f=e; + ++f; + if(r && source(e)==u) erase(e); + else changeTarget(e,u); + e=f; + } + erase(v); + } + + ///Split a node. + + ///This function splits the given node. First, a new node is added + ///to the digraph, then the source of each outgoing arc of node \c n + ///is moved to this new node. + ///If the second parameter \c connect is \c true (this is the default + ///value), then a new arc from node \c n to the newly created node + ///is also added. + ///\return The newly created node. + /// + ///\note All iterators remain valid. + /// + ///\warning This functionality cannot be used together with the + ///Snapshot feature. + Node split(Node n, bool connect = true) { + Node b = addNode(); + nodes[b.id].first_out=nodes[n.id].first_out; + nodes[n.id].first_out=-1; + for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) { + arcs[i].source=b.id; + } + if (connect) addArc(n,b); + return b; + } + + ///Split an arc. + + ///This function splits the given arc. First, a new node \c v is + ///added to the digraph, then the target node of the original arc + ///is set to \c v. Finally, an arc from \c v to the original target + ///is added. + ///\return The newly created node. + /// + ///\note \c InArcIt iterators referencing the original arc are + ///invalidated. Other iterators remain valid. + /// + ///\warning This functionality cannot be used together with the + ///Snapshot feature. + Node split(Arc a) { + Node v = addNode(); + addArc(v,target(a)); + changeTarget(a,v); + return v; + } + + ///Clear the digraph. + + ///This function erases all nodes and arcs from the digraph. + /// + ///\note All iterators of the digraph are invalidated, of course. + void clear() { + Parent::clear(); + } + + /// Reserve memory for nodes. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the digraph you want to build will + /// be large (e.g. it will contain millions of nodes and/or arcs), + /// then it is worth reserving space for this amount before starting + /// to build the digraph. + /// \sa reserveArc() + void reserveNode(int n) { nodes.reserve(n); }; + + /// Reserve memory for arcs. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the digraph you want to build will + /// be large (e.g. it will contain millions of nodes and/or arcs), + /// then it is worth reserving space for this amount before starting + /// to build the digraph. + /// \sa reserveNode() + void reserveArc(int m) { arcs.reserve(m); }; + + /// \brief Class to make a snapshot of the digraph and restore + /// it later. + /// + /// Class to make a snapshot of the digraph and restore it later. + /// + /// The newly added nodes and arcs can be removed using the + /// restore() function. + /// + /// \note After a state is restored, you cannot restore a later state, + /// i.e. you cannot add the removed nodes and arcs again using + /// another Snapshot instance. + /// + /// \warning Node and arc deletions and other modifications (e.g. + /// reversing, contracting, splitting arcs or nodes) cannot be + /// restored. These events invalidate the snapshot. + /// However, the arcs and nodes that were added to the digraph after + /// making the current snapshot can be removed without invalidating it. + class Snapshot { + protected: + + typedef Parent::NodeNotifier NodeNotifier; + + class NodeObserverProxy : public NodeNotifier::ObserverBase { + public: + + NodeObserverProxy(Snapshot& _snapshot) + : snapshot(_snapshot) {} + + using NodeNotifier::ObserverBase::attach; + using NodeNotifier::ObserverBase::detach; + using NodeNotifier::ObserverBase::attached; + + protected: + + virtual void add(const Node& node) { + snapshot.addNode(node); + } + virtual void add(const std::vector& nodes) { + for (int i = nodes.size() - 1; i >= 0; ++i) { + snapshot.addNode(nodes[i]); + } + } + virtual void erase(const Node& node) { + snapshot.eraseNode(node); + } + virtual void erase(const std::vector& nodes) { + for (int i = 0; i < int(nodes.size()); ++i) { + snapshot.eraseNode(nodes[i]); + } + } + virtual void build() { + Node node; + std::vector nodes; + for (notifier()->first(node); node != INVALID; + notifier()->next(node)) { + nodes.push_back(node); + } + for (int i = nodes.size() - 1; i >= 0; --i) { + snapshot.addNode(nodes[i]); + } + } + virtual void clear() { + Node node; + for (notifier()->first(node); node != INVALID; + notifier()->next(node)) { + snapshot.eraseNode(node); + } + } + + Snapshot& snapshot; + }; + + class ArcObserverProxy : public ArcNotifier::ObserverBase { + public: + + ArcObserverProxy(Snapshot& _snapshot) + : snapshot(_snapshot) {} + + using ArcNotifier::ObserverBase::attach; + using ArcNotifier::ObserverBase::detach; + using ArcNotifier::ObserverBase::attached; + + protected: + + virtual void add(const Arc& arc) { + snapshot.addArc(arc); + } + virtual void add(const std::vector& arcs) { + for (int i = arcs.size() - 1; i >= 0; ++i) { + snapshot.addArc(arcs[i]); + } + } + virtual void erase(const Arc& arc) { + snapshot.eraseArc(arc); + } + virtual void erase(const std::vector& arcs) { + for (int i = 0; i < int(arcs.size()); ++i) { + snapshot.eraseArc(arcs[i]); + } + } + virtual void build() { + Arc arc; + std::vector arcs; + for (notifier()->first(arc); arc != INVALID; + notifier()->next(arc)) { + arcs.push_back(arc); + } + for (int i = arcs.size() - 1; i >= 0; --i) { + snapshot.addArc(arcs[i]); + } + } + virtual void clear() { + Arc arc; + for (notifier()->first(arc); arc != INVALID; + notifier()->next(arc)) { + snapshot.eraseArc(arc); + } + } + + Snapshot& snapshot; + }; + + ListDigraph *digraph; + + NodeObserverProxy node_observer_proxy; + ArcObserverProxy arc_observer_proxy; + + std::list added_nodes; + std::list added_arcs; + + + void addNode(const Node& node) { + added_nodes.push_front(node); + } + void eraseNode(const Node& node) { + std::list::iterator it = + std::find(added_nodes.begin(), added_nodes.end(), node); + if (it == added_nodes.end()) { + clear(); + arc_observer_proxy.detach(); + throw NodeNotifier::ImmediateDetach(); + } else { + added_nodes.erase(it); + } + } + + void addArc(const Arc& arc) { + added_arcs.push_front(arc); + } + void eraseArc(const Arc& arc) { + std::list::iterator it = + std::find(added_arcs.begin(), added_arcs.end(), arc); + if (it == added_arcs.end()) { + clear(); + node_observer_proxy.detach(); + throw ArcNotifier::ImmediateDetach(); + } else { + added_arcs.erase(it); + } + } + + void attach(ListDigraph &_digraph) { + digraph = &_digraph; + node_observer_proxy.attach(digraph->notifier(Node())); + arc_observer_proxy.attach(digraph->notifier(Arc())); + } + + void detach() { + node_observer_proxy.detach(); + arc_observer_proxy.detach(); + } + + bool attached() const { + return node_observer_proxy.attached(); + } + + void clear() { + added_nodes.clear(); + added_arcs.clear(); + } + + public: + + /// \brief Default constructor. + /// + /// Default constructor. + /// You have to call save() to actually make a snapshot. + Snapshot() + : digraph(0), node_observer_proxy(*this), + arc_observer_proxy(*this) {} + + /// \brief Constructor that immediately makes a snapshot. + /// + /// This constructor immediately makes a snapshot of the given digraph. + Snapshot(ListDigraph &gr) + : node_observer_proxy(*this), + arc_observer_proxy(*this) { + attach(gr); + } + + /// \brief Make a snapshot. + /// + /// This function makes a snapshot of the given digraph. + /// It can be called more than once. In case of a repeated + /// call, the previous snapshot gets lost. + void save(ListDigraph &gr) { + if (attached()) { + detach(); + clear(); + } + attach(gr); + } + + /// \brief Undo the changes until the last snapshot. + /// + /// This function undos the changes until the last snapshot + /// created by save() or Snapshot(ListDigraph&). + /// + /// \warning This method invalidates the snapshot, i.e. repeated + /// restoring is not supported unless you call save() again. + void restore() { + detach(); + for(std::list::iterator it = added_arcs.begin(); + it != added_arcs.end(); ++it) { + digraph->erase(*it); + } + for(std::list::iterator it = added_nodes.begin(); + it != added_nodes.end(); ++it) { + digraph->erase(*it); + } + clear(); + } + + /// \brief Returns \c true if the snapshot is valid. + /// + /// This function returns \c true if the snapshot is valid. + bool valid() const { + return attached(); + } + }; + + }; + + ///@} + + class ListGraphBase { + + protected: + + struct NodeT { + int first_out; + int prev, next; + }; + + struct ArcT { + int target; + int prev_out, next_out; + }; + + std::vector nodes; + + int first_node; + + int first_free_node; + + std::vector arcs; + + int first_free_arc; + + public: + + typedef ListGraphBase Graph; + + class Node { + friend class ListGraphBase; + protected: + + int id; + explicit Node(int pid) { id = pid;} + + public: + Node() {} + Node (Invalid) { id = -1; } + bool operator==(const Node& node) const {return id == node.id;} + bool operator!=(const Node& node) const {return id != node.id;} + bool operator<(const Node& node) const {return id < node.id;} + }; + + class Edge { + friend class ListGraphBase; + protected: + + int id; + explicit Edge(int pid) { id = pid;} + + public: + Edge() {} + Edge (Invalid) { id = -1; } + bool operator==(const Edge& edge) const {return id == edge.id;} + bool operator!=(const Edge& edge) const {return id != edge.id;} + bool operator<(const Edge& edge) const {return id < edge.id;} + }; + + class Arc { + friend class ListGraphBase; + protected: + + int id; + explicit Arc(int pid) { id = pid;} + + public: + operator Edge() const { + return id != -1 ? edgeFromId(id / 2) : INVALID; + } + + Arc() {} + Arc (Invalid) { id = -1; } + bool operator==(const Arc& arc) const {return id == arc.id;} + bool operator!=(const Arc& arc) const {return id != arc.id;} + bool operator<(const Arc& arc) const {return id < arc.id;} + }; + + ListGraphBase() + : nodes(), first_node(-1), + first_free_node(-1), arcs(), first_free_arc(-1) {} + + + int maxNodeId() const { return nodes.size()-1; } + int maxEdgeId() const { return arcs.size() / 2 - 1; } + int maxArcId() const { return arcs.size()-1; } + + Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); } + Node target(Arc e) const { return Node(arcs[e.id].target); } + + Node u(Edge e) const { return Node(arcs[2 * e.id].target); } + Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); } + + static bool direction(Arc e) { + return (e.id & 1) == 1; + } + + static Arc direct(Edge e, bool d) { + return Arc(e.id * 2 + (d ? 1 : 0)); + } + + void first(Node& node) const { + node.id = first_node; + } + + void next(Node& node) const { + node.id = nodes[node.id].next; + } + + void first(Arc& e) const { + int n = first_node; + while (n != -1 && nodes[n].first_out == -1) { + n = nodes[n].next; + } + e.id = (n == -1) ? -1 : nodes[n].first_out; + } + + void next(Arc& e) const { + if (arcs[e.id].next_out != -1) { + e.id = arcs[e.id].next_out; + } else { + int n = nodes[arcs[e.id ^ 1].target].next; + while(n != -1 && nodes[n].first_out == -1) { + n = nodes[n].next; + } + e.id = (n == -1) ? -1 : nodes[n].first_out; + } + } + + void first(Edge& e) const { + int n = first_node; + while (n != -1) { + e.id = nodes[n].first_out; + while ((e.id & 1) != 1) { + e.id = arcs[e.id].next_out; + } + if (e.id != -1) { + e.id /= 2; + return; + } + n = nodes[n].next; + } + e.id = -1; + } + + void next(Edge& e) const { + int n = arcs[e.id * 2].target; + e.id = arcs[(e.id * 2) | 1].next_out; + while ((e.id & 1) != 1) { + e.id = arcs[e.id].next_out; + } + if (e.id != -1) { + e.id /= 2; + return; + } + n = nodes[n].next; + while (n != -1) { + e.id = nodes[n].first_out; + while ((e.id & 1) != 1) { + e.id = arcs[e.id].next_out; + } + if (e.id != -1) { + e.id /= 2; + return; + } + n = nodes[n].next; + } + e.id = -1; + } + + void firstOut(Arc &e, const Node& v) const { + e.id = nodes[v.id].first_out; + } + void nextOut(Arc &e) const { + e.id = arcs[e.id].next_out; + } + + void firstIn(Arc &e, const Node& v) const { + e.id = ((nodes[v.id].first_out) ^ 1); + if (e.id == -2) e.id = -1; + } + void nextIn(Arc &e) const { + e.id = ((arcs[e.id ^ 1].next_out) ^ 1); + if (e.id == -2) e.id = -1; + } + + void firstInc(Edge &e, bool& d, const Node& v) const { + int a = nodes[v.id].first_out; + if (a != -1 ) { + e.id = a / 2; + d = ((a & 1) == 1); + } else { + e.id = -1; + d = true; + } + } + void nextInc(Edge &e, bool& d) const { + int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out); + if (a != -1 ) { + e.id = a / 2; + d = ((a & 1) == 1); + } else { + e.id = -1; + d = true; + } + } + + static int id(Node v) { return v.id; } + static int id(Arc e) { return e.id; } + static int id(Edge e) { return e.id; } + + static Node nodeFromId(int id) { return Node(id);} + static Arc arcFromId(int id) { return Arc(id);} + static Edge edgeFromId(int id) { return Edge(id);} + + bool valid(Node n) const { + return n.id >= 0 && n.id < static_cast(nodes.size()) && + nodes[n.id].prev != -2; + } + + bool valid(Arc a) const { + return a.id >= 0 && a.id < static_cast(arcs.size()) && + arcs[a.id].prev_out != -2; + } + + bool valid(Edge e) const { + return e.id >= 0 && 2 * e.id < static_cast(arcs.size()) && + arcs[2 * e.id].prev_out != -2; + } + + Node addNode() { + int n; + + if(first_free_node==-1) { + n = nodes.size(); + nodes.push_back(NodeT()); + } else { + n = first_free_node; + first_free_node = nodes[n].next; + } + + nodes[n].next = first_node; + if (first_node != -1) nodes[first_node].prev = n; + first_node = n; + nodes[n].prev = -1; + + nodes[n].first_out = -1; + + return Node(n); + } + + Edge addEdge(Node u, Node v) { + int n; + + if (first_free_arc == -1) { + n = arcs.size(); + arcs.push_back(ArcT()); + arcs.push_back(ArcT()); + } else { + n = first_free_arc; + first_free_arc = arcs[n].next_out; + } + + arcs[n].target = u.id; + arcs[n | 1].target = v.id; + + arcs[n].next_out = nodes[v.id].first_out; + if (nodes[v.id].first_out != -1) { + arcs[nodes[v.id].first_out].prev_out = n; + } + arcs[n].prev_out = -1; + nodes[v.id].first_out = n; + + arcs[n | 1].next_out = nodes[u.id].first_out; + if (nodes[u.id].first_out != -1) { + arcs[nodes[u.id].first_out].prev_out = (n | 1); + } + arcs[n | 1].prev_out = -1; + nodes[u.id].first_out = (n | 1); + + return Edge(n / 2); + } + + void erase(const Node& node) { + int n = node.id; + + if(nodes[n].next != -1) { + nodes[nodes[n].next].prev = nodes[n].prev; + } + + if(nodes[n].prev != -1) { + nodes[nodes[n].prev].next = nodes[n].next; + } else { + first_node = nodes[n].next; + } + + nodes[n].next = first_free_node; + first_free_node = n; + nodes[n].prev = -2; + } + + void erase(const Edge& edge) { + int n = edge.id * 2; + + if (arcs[n].next_out != -1) { + arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; + } + + if (arcs[n].prev_out != -1) { + arcs[arcs[n].prev_out].next_out = arcs[n].next_out; + } else { + nodes[arcs[n | 1].target].first_out = arcs[n].next_out; + } + + if (arcs[n | 1].next_out != -1) { + arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; + } + + if (arcs[n | 1].prev_out != -1) { + arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; + } else { + nodes[arcs[n].target].first_out = arcs[n | 1].next_out; + } + + arcs[n].next_out = first_free_arc; + first_free_arc = n; + arcs[n].prev_out = -2; + arcs[n | 1].prev_out = -2; + + } + + void clear() { + arcs.clear(); + nodes.clear(); + first_node = first_free_node = first_free_arc = -1; + } + + protected: + + void changeV(Edge e, Node n) { + if(arcs[2 * e.id].next_out != -1) { + arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out; + } + if(arcs[2 * e.id].prev_out != -1) { + arcs[arcs[2 * e.id].prev_out].next_out = + arcs[2 * e.id].next_out; + } else { + nodes[arcs[(2 * e.id) | 1].target].first_out = + arcs[2 * e.id].next_out; + } + + if (nodes[n.id].first_out != -1) { + arcs[nodes[n.id].first_out].prev_out = 2 * e.id; + } + arcs[(2 * e.id) | 1].target = n.id; + arcs[2 * e.id].prev_out = -1; + arcs[2 * e.id].next_out = nodes[n.id].first_out; + nodes[n.id].first_out = 2 * e.id; + } + + void changeU(Edge e, Node n) { + if(arcs[(2 * e.id) | 1].next_out != -1) { + arcs[arcs[(2 * e.id) | 1].next_out].prev_out = + arcs[(2 * e.id) | 1].prev_out; + } + if(arcs[(2 * e.id) | 1].prev_out != -1) { + arcs[arcs[(2 * e.id) | 1].prev_out].next_out = + arcs[(2 * e.id) | 1].next_out; + } else { + nodes[arcs[2 * e.id].target].first_out = + arcs[(2 * e.id) | 1].next_out; + } + + if (nodes[n.id].first_out != -1) { + arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1); + } + arcs[2 * e.id].target = n.id; + arcs[(2 * e.id) | 1].prev_out = -1; + arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out; + nodes[n.id].first_out = ((2 * e.id) | 1); + } + + }; + + typedef GraphExtender ExtendedListGraphBase; + + + /// \addtogroup graphs + /// @{ + + ///A general undirected graph structure. + + ///\ref ListGraph is a versatile and fast undirected graph + ///implementation based on linked lists that are stored in + ///\c std::vector structures. + /// + ///This type fully conforms to the \ref concepts::Graph "Graph concept" + ///and it also provides several useful additional functionalities. + ///Most of its member functions and nested classes are documented + ///only in the concept class. + /// + ///This class provides only linear time counting for nodes, edges and arcs. + /// + ///\sa concepts::Graph + ///\sa ListDigraph + class ListGraph : public ExtendedListGraphBase { + typedef ExtendedListGraphBase Parent; + + private: + /// Graphs are \e not copy constructible. Use GraphCopy instead. + ListGraph(const ListGraph &) :ExtendedListGraphBase() {}; + /// \brief Assignment of a graph to another one is \e not allowed. + /// Use GraphCopy instead. + void operator=(const ListGraph &) {} + public: + /// Constructor + + /// Constructor. + /// + ListGraph() {} + + typedef Parent::OutArcIt IncEdgeIt; + + /// \brief Add a new node to the graph. + /// + /// This function adds a new node to the graph. + /// \return The new node. + Node addNode() { return Parent::addNode(); } + + /// \brief Add a new edge to the graph. + /// + /// This function adds a new edge to the graph between nodes + /// \c u and \c v with inherent orientation from node \c u to + /// node \c v. + /// \return The new edge. + Edge addEdge(Node u, Node v) { + return Parent::addEdge(u, v); + } + + ///\brief Erase a node from the graph. + /// + /// This function erases the given node along with its incident arcs + /// from the graph. + /// + /// \note All iterators referencing the removed node or the incident + /// edges are invalidated, of course. + void erase(Node n) { Parent::erase(n); } + + ///\brief Erase an edge from the graph. + /// + /// This function erases the given edge from the graph. + /// + /// \note All iterators referencing the removed edge are invalidated, + /// of course. + void erase(Edge e) { Parent::erase(e); } + /// Node validity check + + /// This function gives back \c true if the given node is valid, + /// i.e. it is a real node of the graph. + /// + /// \warning A removed node could become valid again if new nodes are + /// added to the graph. + bool valid(Node n) const { return Parent::valid(n); } + /// Edge validity check + + /// This function gives back \c true if the given edge is valid, + /// i.e. it is a real edge of the graph. + /// + /// \warning A removed edge could become valid again if new edges are + /// added to the graph. + bool valid(Edge e) const { return Parent::valid(e); } + /// Arc validity check + + /// This function gives back \c true if the given arc is valid, + /// i.e. it is a real arc of the graph. + /// + /// \warning A removed arc could become valid again if new edges are + /// added to the graph. + bool valid(Arc a) const { return Parent::valid(a); } + + /// \brief Change the first node of an edge. + /// + /// This function changes the first node of the given edge \c e to \c n. + /// + ///\note \c EdgeIt and \c ArcIt iterators referencing the + ///changed edge are invalidated and all other iterators whose + ///base node is the changed node are also invalidated. + /// + ///\warning This functionality cannot be used together with the + ///Snapshot feature. + void changeU(Edge e, Node n) { + Parent::changeU(e,n); + } + /// \brief Change the second node of an edge. + /// + /// This function changes the second node of the given edge \c e to \c n. + /// + ///\note \c EdgeIt iterators referencing the changed edge remain + ///valid, but \c ArcIt iterators referencing the changed edge and + ///all other iterators whose base node is the changed node are also + ///invalidated. + /// + ///\warning This functionality cannot be used together with the + ///Snapshot feature. + void changeV(Edge e, Node n) { + Parent::changeV(e,n); + } + + /// \brief Contract two nodes. + /// + /// This function contracts the given two nodes. + /// Node \c b is removed, but instead of deleting + /// its incident edges, they are joined to node \c a. + /// If the last parameter \c r is \c true (this is the default value), + /// then the newly created loops are removed. + /// + /// \note The moved edges are joined to node \c a using changeU() + /// or changeV(), thus all edge and arc iterators whose base node is + /// \c b are invalidated. + /// Moreover all iterators referencing node \c b or the removed + /// loops are also invalidated. Other iterators remain valid. + /// + ///\warning This functionality cannot be used together with the + ///Snapshot feature. + void contract(Node a, Node b, bool r = true) { + for(IncEdgeIt e(*this, b); e!=INVALID;) { + IncEdgeIt f = e; ++f; + if (r && runningNode(e) == a) { + erase(e); + } else if (u(e) == b) { + changeU(e, a); + } else { + changeV(e, a); + } + e = f; + } + erase(b); + } + + ///Clear the graph. + + ///This function erases all nodes and arcs from the graph. + /// + ///\note All iterators of the graph are invalidated, of course. + void clear() { + Parent::clear(); + } + + /// Reserve memory for nodes. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the graph you want to build will + /// be large (e.g. it will contain millions of nodes and/or edges), + /// then it is worth reserving space for this amount before starting + /// to build the graph. + /// \sa reserveEdge() + void reserveNode(int n) { nodes.reserve(n); }; + + /// Reserve memory for edges. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the graph you want to build will + /// be large (e.g. it will contain millions of nodes and/or edges), + /// then it is worth reserving space for this amount before starting + /// to build the graph. + /// \sa reserveNode() + void reserveEdge(int m) { arcs.reserve(2 * m); }; + + /// \brief Class to make a snapshot of the graph and restore + /// it later. + /// + /// Class to make a snapshot of the graph and restore it later. + /// + /// The newly added nodes and edges can be removed + /// using the restore() function. + /// + /// \note After a state is restored, you cannot restore a later state, + /// i.e. you cannot add the removed nodes and edges again using + /// another Snapshot instance. + /// + /// \warning Node and edge deletions and other modifications + /// (e.g. changing the end-nodes of edges or contracting nodes) + /// cannot be restored. These events invalidate the snapshot. + /// However, the edges and nodes that were added to the graph after + /// making the current snapshot can be removed without invalidating it. + class Snapshot { + protected: + + typedef Parent::NodeNotifier NodeNotifier; + + class NodeObserverProxy : public NodeNotifier::ObserverBase { + public: + + NodeObserverProxy(Snapshot& _snapshot) + : snapshot(_snapshot) {} + + using NodeNotifier::ObserverBase::attach; + using NodeNotifier::ObserverBase::detach; + using NodeNotifier::ObserverBase::attached; + + protected: + + virtual void add(const Node& node) { + snapshot.addNode(node); + } + virtual void add(const std::vector& nodes) { + for (int i = nodes.size() - 1; i >= 0; ++i) { + snapshot.addNode(nodes[i]); + } + } + virtual void erase(const Node& node) { + snapshot.eraseNode(node); + } + virtual void erase(const std::vector& nodes) { + for (int i = 0; i < int(nodes.size()); ++i) { + snapshot.eraseNode(nodes[i]); + } + } + virtual void build() { + Node node; + std::vector nodes; + for (notifier()->first(node); node != INVALID; + notifier()->next(node)) { + nodes.push_back(node); + } + for (int i = nodes.size() - 1; i >= 0; --i) { + snapshot.addNode(nodes[i]); + } + } + virtual void clear() { + Node node; + for (notifier()->first(node); node != INVALID; + notifier()->next(node)) { + snapshot.eraseNode(node); + } + } + + Snapshot& snapshot; + }; + + class EdgeObserverProxy : public EdgeNotifier::ObserverBase { + public: + + EdgeObserverProxy(Snapshot& _snapshot) + : snapshot(_snapshot) {} + + using EdgeNotifier::ObserverBase::attach; + using EdgeNotifier::ObserverBase::detach; + using EdgeNotifier::ObserverBase::attached; + + protected: + + virtual void add(const Edge& edge) { + snapshot.addEdge(edge); + } + virtual void add(const std::vector& edges) { + for (int i = edges.size() - 1; i >= 0; ++i) { + snapshot.addEdge(edges[i]); + } + } + virtual void erase(const Edge& edge) { + snapshot.eraseEdge(edge); + } + virtual void erase(const std::vector& edges) { + for (int i = 0; i < int(edges.size()); ++i) { + snapshot.eraseEdge(edges[i]); + } + } + virtual void build() { + Edge edge; + std::vector edges; + for (notifier()->first(edge); edge != INVALID; + notifier()->next(edge)) { + edges.push_back(edge); + } + for (int i = edges.size() - 1; i >= 0; --i) { + snapshot.addEdge(edges[i]); + } + } + virtual void clear() { + Edge edge; + for (notifier()->first(edge); edge != INVALID; + notifier()->next(edge)) { + snapshot.eraseEdge(edge); + } + } + + Snapshot& snapshot; + }; + + ListGraph *graph; + + NodeObserverProxy node_observer_proxy; + EdgeObserverProxy edge_observer_proxy; + + std::list added_nodes; + std::list added_edges; + + + void addNode(const Node& node) { + added_nodes.push_front(node); + } + void eraseNode(const Node& node) { + std::list::iterator it = + std::find(added_nodes.begin(), added_nodes.end(), node); + if (it == added_nodes.end()) { + clear(); + edge_observer_proxy.detach(); + throw NodeNotifier::ImmediateDetach(); + } else { + added_nodes.erase(it); + } + } + + void addEdge(const Edge& edge) { + added_edges.push_front(edge); + } + void eraseEdge(const Edge& edge) { + std::list::iterator it = + std::find(added_edges.begin(), added_edges.end(), edge); + if (it == added_edges.end()) { + clear(); + node_observer_proxy.detach(); + throw EdgeNotifier::ImmediateDetach(); + } else { + added_edges.erase(it); + } + } + + void attach(ListGraph &_graph) { + graph = &_graph; + node_observer_proxy.attach(graph->notifier(Node())); + edge_observer_proxy.attach(graph->notifier(Edge())); + } + + void detach() { + node_observer_proxy.detach(); + edge_observer_proxy.detach(); + } + + bool attached() const { + return node_observer_proxy.attached(); + } + + void clear() { + added_nodes.clear(); + added_edges.clear(); + } + + public: + + /// \brief Default constructor. + /// + /// Default constructor. + /// You have to call save() to actually make a snapshot. + Snapshot() + : graph(0), node_observer_proxy(*this), + edge_observer_proxy(*this) {} + + /// \brief Constructor that immediately makes a snapshot. + /// + /// This constructor immediately makes a snapshot of the given graph. + Snapshot(ListGraph &gr) + : node_observer_proxy(*this), + edge_observer_proxy(*this) { + attach(gr); + } + + /// \brief Make a snapshot. + /// + /// This function makes a snapshot of the given graph. + /// It can be called more than once. In case of a repeated + /// call, the previous snapshot gets lost. + void save(ListGraph &gr) { + if (attached()) { + detach(); + clear(); + } + attach(gr); + } + + /// \brief Undo the changes until the last snapshot. + /// + /// This function undos the changes until the last snapshot + /// created by save() or Snapshot(ListGraph&). + /// + /// \warning This method invalidates the snapshot, i.e. repeated + /// restoring is not supported unless you call save() again. + void restore() { + detach(); + for(std::list::iterator it = added_edges.begin(); + it != added_edges.end(); ++it) { + graph->erase(*it); + } + for(std::list::iterator it = added_nodes.begin(); + it != added_nodes.end(); ++it) { + graph->erase(*it); + } + clear(); + } + + /// \brief Returns \c true if the snapshot is valid. + /// + /// This function returns \c true if the snapshot is valid. + bool valid() const { + return attached(); + } + }; + }; + + /// @} +} //namespace lemon + + +#endif diff --git a/lemon/lemon/lp.h b/lemon/lemon/lp.h new file mode 100644 index 0000000..86aaa62 --- /dev/null +++ b/lemon/lemon/lp.h @@ -0,0 +1,93 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_LP_H +#define LEMON_LP_H + +#include + + +#ifdef LEMON_HAVE_GLPK +#include +#elif LEMON_HAVE_CPLEX +#include +#elif LEMON_HAVE_SOPLEX +#include +#elif LEMON_HAVE_CLP +#include +#endif + +///\file +///\brief Defines a default LP solver +///\ingroup lp_group +namespace lemon { + +#ifdef DOXYGEN + ///The default LP solver identifier + + ///The default LP solver identifier. + ///\ingroup lp_group + /// + ///Currently, the possible values are \c GLPK, \c CPLEX, + ///\c SOPLEX or \c CLP +#define LEMON_DEFAULT_LP SOLVER + ///The default LP solver + + ///The default LP solver. + ///\ingroup lp_group + /// + ///Currently, it is either \c GlpkLp, \c CplexLp, \c SoplexLp or \c ClpLp + typedef GlpkLp Lp; + + ///The default MIP solver identifier + + ///The default MIP solver identifier. + ///\ingroup lp_group + /// + ///Currently, the possible values are \c GLPK or \c CPLEX +#define LEMON_DEFAULT_MIP SOLVER + ///The default MIP solver. + + ///The default MIP solver. + ///\ingroup lp_group + /// + ///Currently, it is either \c GlpkMip or \c CplexMip + typedef GlpkMip Mip; +#else +#ifdef LEMON_HAVE_GLPK +# define LEMON_DEFAULT_LP GLPK + typedef GlpkLp Lp; +# define LEMON_DEFAULT_MIP GLPK + typedef GlpkMip Mip; +#elif LEMON_HAVE_CPLEX +# define LEMON_DEFAULT_LP CPLEX + typedef CplexLp Lp; +# define LEMON_DEFAULT_MIP CPLEX + typedef CplexMip Mip; +#elif LEMON_HAVE_SOPLEX +# define DEFAULT_LP SOPLEX + typedef SoplexLp Lp; +#elif LEMON_HAVE_CLP +# define DEFAULT_LP CLP + typedef ClpLp Lp; +#endif +#endif + +} //namespace lemon + +#endif //LEMON_LP_H diff --git a/lemon/lemon/lp_base.cc b/lemon/lemon/lp_base.cc new file mode 100644 index 0000000..f767c99 --- /dev/null +++ b/lemon/lemon/lp_base.cc @@ -0,0 +1,30 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief The implementation of the LP solver interface. + +#include +namespace lemon { + + const LpBase::Value LpBase::INF = + std::numeric_limits::infinity(); + const LpBase::Value LpBase::NaN = + std::numeric_limits::quiet_NaN(); + +} //namespace lemon diff --git a/lemon/lemon/lp_base.h b/lemon/lemon/lp_base.h new file mode 100644 index 0000000..8a7f726 --- /dev/null +++ b/lemon/lemon/lp_base.h @@ -0,0 +1,2102 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_LP_BASE_H +#define LEMON_LP_BASE_H + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +///\file +///\brief The interface of the LP solver interface. +///\ingroup lp_group +namespace lemon { + + ///Common base class for LP and MIP solvers + + ///Usually this class is not used directly, please use one of the concrete + ///implementations of the solver interface. + ///\ingroup lp_group + class LpBase { + + protected: + + _solver_bits::VarIndex rows; + _solver_bits::VarIndex cols; + + public: + + ///Possible outcomes of an LP solving procedure + enum SolveExitStatus { + /// = 0. It means that the problem has been successfully solved: either + ///an optimal solution has been found or infeasibility/unboundedness + ///has been proved. + SOLVED = 0, + /// = 1. Any other case (including the case when some user specified + ///limit has been exceeded). + UNSOLVED = 1 + }; + + ///Direction of the optimization + enum Sense { + /// Minimization + MIN, + /// Maximization + MAX + }; + + ///Enum for \c messageLevel() parameter + enum MessageLevel { + /// No output (default value). + MESSAGE_NOTHING, + /// Error messages only. + MESSAGE_ERROR, + /// Warnings. + MESSAGE_WARNING, + /// Normal output. + MESSAGE_NORMAL, + /// Verbose output. + MESSAGE_VERBOSE + }; + + + ///The floating point type used by the solver + typedef double Value; + ///The infinity constant + static const Value INF; + ///The not a number constant + static const Value NaN; + + friend class Col; + friend class ColIt; + friend class Row; + friend class RowIt; + + ///Refer to a column of the LP. + + ///This type is used to refer to a column of the LP. + /// + ///Its value remains valid and correct even after the addition or erase of + ///other columns. + /// + ///\note This class is similar to other Item types in LEMON, like + ///Node and Arc types in digraph. + class Col { + friend class LpBase; + protected: + int _id; + explicit Col(int id) : _id(id) {} + public: + typedef Value ExprValue; + typedef True LpCol; + /// Default constructor + + /// \warning The default constructor sets the Col to an + /// undefined value. + Col() {} + /// Invalid constructor \& conversion. + + /// This constructor initializes the Col to be invalid. + /// \sa Invalid for more details. + Col(const Invalid&) : _id(-1) {} + /// Equality operator + + /// Two \ref Col "Col"s are equal if and only if they point to + /// the same LP column or both are invalid. + bool operator==(Col c) const {return _id == c._id;} + /// Inequality operator + + /// \sa operator==(Col c) + /// + bool operator!=(Col c) const {return _id != c._id;} + /// Artificial ordering operator. + + /// To allow the use of this object in std::map or similar + /// associative container we require this. + /// + /// \note This operator only have to define some strict ordering of + /// the items; this order has nothing to do with the iteration + /// ordering of the items. + bool operator<(Col c) const {return _id < c._id;} + }; + + ///Iterator for iterate over the columns of an LP problem + + /// Its usage is quite simple, for example, you can count the number + /// of columns in an LP \c lp: + ///\code + /// int count=0; + /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count; + ///\endcode + class ColIt : public Col { + const LpBase *_solver; + public: + /// Default constructor + + /// \warning The default constructor sets the iterator + /// to an undefined value. + ColIt() {} + /// Sets the iterator to the first Col + + /// Sets the iterator to the first Col. + /// + ColIt(const LpBase &solver) : _solver(&solver) + { + _solver->cols.firstItem(_id); + } + /// Invalid constructor \& conversion + + /// Initialize the iterator to be invalid. + /// \sa Invalid for more details. + ColIt(const Invalid&) : Col(INVALID) {} + /// Next column + + /// Assign the iterator to the next column. + /// + ColIt &operator++() + { + _solver->cols.nextItem(_id); + return *this; + } + }; + + /// \brief Returns the ID of the column. + static int id(const Col& col) { return col._id; } + /// \brief Returns the column with the given ID. + /// + /// \pre The argument should be a valid column ID in the LP problem. + static Col colFromId(int id) { return Col(id); } + + ///Refer to a row of the LP. + + ///This type is used to refer to a row of the LP. + /// + ///Its value remains valid and correct even after the addition or erase of + ///other rows. + /// + ///\note This class is similar to other Item types in LEMON, like + ///Node and Arc types in digraph. + class Row { + friend class LpBase; + protected: + int _id; + explicit Row(int id) : _id(id) {} + public: + typedef Value ExprValue; + typedef True LpRow; + /// Default constructor + + /// \warning The default constructor sets the Row to an + /// undefined value. + Row() {} + /// Invalid constructor \& conversion. + + /// This constructor initializes the Row to be invalid. + /// \sa Invalid for more details. + Row(const Invalid&) : _id(-1) {} + /// Equality operator + + /// Two \ref Row "Row"s are equal if and only if they point to + /// the same LP row or both are invalid. + bool operator==(Row r) const {return _id == r._id;} + /// Inequality operator + + /// \sa operator==(Row r) + /// + bool operator!=(Row r) const {return _id != r._id;} + /// Artificial ordering operator. + + /// To allow the use of this object in std::map or similar + /// associative container we require this. + /// + /// \note This operator only have to define some strict ordering of + /// the items; this order has nothing to do with the iteration + /// ordering of the items. + bool operator<(Row r) const {return _id < r._id;} + }; + + ///Iterator for iterate over the rows of an LP problem + + /// Its usage is quite simple, for example, you can count the number + /// of rows in an LP \c lp: + ///\code + /// int count=0; + /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count; + ///\endcode + class RowIt : public Row { + const LpBase *_solver; + public: + /// Default constructor + + /// \warning The default constructor sets the iterator + /// to an undefined value. + RowIt() {} + /// Sets the iterator to the first Row + + /// Sets the iterator to the first Row. + /// + RowIt(const LpBase &solver) : _solver(&solver) + { + _solver->rows.firstItem(_id); + } + /// Invalid constructor \& conversion + + /// Initialize the iterator to be invalid. + /// \sa Invalid for more details. + RowIt(const Invalid&) : Row(INVALID) {} + /// Next row + + /// Assign the iterator to the next row. + /// + RowIt &operator++() + { + _solver->rows.nextItem(_id); + return *this; + } + }; + + /// \brief Returns the ID of the row. + static int id(const Row& row) { return row._id; } + /// \brief Returns the row with the given ID. + /// + /// \pre The argument should be a valid row ID in the LP problem. + static Row rowFromId(int id) { return Row(id); } + + public: + + ///Linear expression of variables and a constant component + + ///This data structure stores a linear expression of the variables + ///(\ref Col "Col"s) and also has a constant component. + /// + ///There are several ways to access and modify the contents of this + ///container. + ///\code + ///e[v]=5; + ///e[v]+=12; + ///e.erase(v); + ///\endcode + ///or you can also iterate through its elements. + ///\code + ///double s=0; + ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i) + /// s+=*i * primal(i); + ///\endcode + ///(This code computes the primal value of the expression). + ///- Numbers (double's) + ///and variables (\ref Col "Col"s) directly convert to an + ///\ref Expr and the usual linear operations are defined, so + ///\code + ///v+w + ///2*v-3.12*(v-w/2)+2 + ///v*2.1+(3*v+(v*12+w+6)*3)/2 + ///\endcode + ///are valid expressions. + ///The usual assignment operations are also defined. + ///\code + ///e=v+w; + ///e+=2*v-3.12*(v-w/2)+2; + ///e*=3.4; + ///e/=5; + ///\endcode + ///- The constant member can be set and read by dereference + /// operator (unary *) + /// + ///\code + ///*e=12; + ///double c=*e; + ///\endcode + /// + ///\sa Constr + class Expr { + friend class LpBase; + public: + /// The key type of the expression + typedef LpBase::Col Key; + /// The value type of the expression + typedef LpBase::Value Value; + + protected: + Value const_comp; + std::map comps; + + public: + typedef True SolverExpr; + /// Default constructor + + /// Construct an empty expression, the coefficients and + /// the constant component are initialized to zero. + Expr() : const_comp(0) {} + /// Construct an expression from a column + + /// Construct an expression, which has a term with \c c variable + /// and 1.0 coefficient. + Expr(const Col &c) : const_comp(0) { + typedef std::map::value_type pair_type; + comps.insert(pair_type(id(c), 1)); + } + /// Construct an expression from a constant + + /// Construct an expression, which's constant component is \c v. + /// + Expr(const Value &v) : const_comp(v) {} + /// Returns the coefficient of the column + Value operator[](const Col& c) const { + std::map::const_iterator it=comps.find(id(c)); + if (it != comps.end()) { + return it->second; + } else { + return 0; + } + } + /// Returns the coefficient of the column + Value& operator[](const Col& c) { + return comps[id(c)]; + } + /// Sets the coefficient of the column + void set(const Col &c, const Value &v) { + if (v != 0.0) { + typedef std::map::value_type pair_type; + comps.insert(pair_type(id(c), v)); + } else { + comps.erase(id(c)); + } + } + /// Returns the constant component of the expression + Value& operator*() { return const_comp; } + /// Returns the constant component of the expression + const Value& operator*() const { return const_comp; } + /// \brief Removes the coefficients which's absolute value does + /// not exceed \c epsilon. It also sets to zero the constant + /// component, if it does not exceed epsilon in absolute value. + void simplify(Value epsilon = 0.0) { + std::map::iterator it=comps.begin(); + while (it != comps.end()) { + std::map::iterator jt=it; + ++jt; + if (std::fabs((*it).second) <= epsilon) comps.erase(it); + it=jt; + } + if (std::fabs(const_comp) <= epsilon) const_comp = 0; + } + + void simplify(Value epsilon = 0.0) const { + const_cast(this)->simplify(epsilon); + } + + ///Sets all coefficients and the constant component to 0. + void clear() { + comps.clear(); + const_comp=0; + } + + ///Compound assignment + Expr &operator+=(const Expr &e) { + for (std::map::const_iterator it=e.comps.begin(); + it!=e.comps.end(); ++it) + comps[it->first]+=it->second; + const_comp+=e.const_comp; + return *this; + } + ///Compound assignment + Expr &operator-=(const Expr &e) { + for (std::map::const_iterator it=e.comps.begin(); + it!=e.comps.end(); ++it) + comps[it->first]-=it->second; + const_comp-=e.const_comp; + return *this; + } + ///Multiply with a constant + Expr &operator*=(const Value &v) { + for (std::map::iterator it=comps.begin(); + it!=comps.end(); ++it) + it->second*=v; + const_comp*=v; + return *this; + } + ///Division with a constant + Expr &operator/=(const Value &c) { + for (std::map::iterator it=comps.begin(); + it!=comps.end(); ++it) + it->second/=c; + const_comp/=c; + return *this; + } + + ///Iterator over the expression + + ///The iterator iterates over the terms of the expression. + /// + ///\code + ///double s=0; + ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i) + /// s+= *i * primal(i); + ///\endcode + class CoeffIt { + private: + + std::map::iterator _it, _end; + + public: + + /// Sets the iterator to the first term + + /// Sets the iterator to the first term of the expression. + /// + CoeffIt(Expr& e) + : _it(e.comps.begin()), _end(e.comps.end()){} + + /// Convert the iterator to the column of the term + operator Col() const { + return colFromId(_it->first); + } + + /// Returns the coefficient of the term + Value& operator*() { return _it->second; } + + /// Returns the coefficient of the term + const Value& operator*() const { return _it->second; } + /// Next term + + /// Assign the iterator to the next term. + /// + CoeffIt& operator++() { ++_it; return *this; } + + /// Equality operator + bool operator==(Invalid) const { return _it == _end; } + /// Inequality operator + bool operator!=(Invalid) const { return _it != _end; } + }; + + /// Const iterator over the expression + + ///The iterator iterates over the terms of the expression. + /// + ///\code + ///double s=0; + ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i) + /// s+=*i * primal(i); + ///\endcode + class ConstCoeffIt { + private: + + std::map::const_iterator _it, _end; + + public: + + /// Sets the iterator to the first term + + /// Sets the iterator to the first term of the expression. + /// + ConstCoeffIt(const Expr& e) + : _it(e.comps.begin()), _end(e.comps.end()){} + + /// Convert the iterator to the column of the term + operator Col() const { + return colFromId(_it->first); + } + + /// Returns the coefficient of the term + const Value& operator*() const { return _it->second; } + + /// Next term + + /// Assign the iterator to the next term. + /// + ConstCoeffIt& operator++() { ++_it; return *this; } + + /// Equality operator + bool operator==(Invalid) const { return _it == _end; } + /// Inequality operator + bool operator!=(Invalid) const { return _it != _end; } + }; + + }; + + ///Linear constraint + + ///This data stucture represents a linear constraint in the LP. + ///Basically it is a linear expression with a lower or an upper bound + ///(or both). These parts of the constraint can be obtained by the member + ///functions \ref expr(), \ref lowerBound() and \ref upperBound(), + ///respectively. + ///There are two ways to construct a constraint. + ///- You can set the linear expression and the bounds directly + /// by the functions above. + ///- The operators \<=, == and \>= + /// are defined between expressions, or even between constraints whenever + /// it makes sense. Therefore if \c e and \c f are linear expressions and + /// \c s and \c t are numbers, then the followings are valid expressions + /// and thus they can be used directly e.g. in \ref addRow() whenever + /// it makes sense. + ///\code + /// e<=s + /// e<=f + /// e==f + /// s<=e<=t + /// e>=t + ///\endcode + ///\warning The validity of a constraint is checked only at run + ///time, so e.g. \ref addRow(x[1]\<=x[2]<=5) will + ///compile, but will fail an assertion. + class Constr + { + public: + typedef LpBase::Expr Expr; + typedef Expr::Key Key; + typedef Expr::Value Value; + + protected: + Expr _expr; + Value _lb,_ub; + public: + ///\e + Constr() : _expr(), _lb(NaN), _ub(NaN) {} + ///\e + Constr(Value lb, const Expr &e, Value ub) : + _expr(e), _lb(lb), _ub(ub) {} + Constr(const Expr &e) : + _expr(e), _lb(NaN), _ub(NaN) {} + ///\e + void clear() + { + _expr.clear(); + _lb=_ub=NaN; + } + + ///Reference to the linear expression + Expr &expr() { return _expr; } + ///Cont reference to the linear expression + const Expr &expr() const { return _expr; } + ///Reference to the lower bound. + + ///\return + ///- \ref INF "INF": the constraint is lower unbounded. + ///- \ref NaN "NaN": lower bound has not been set. + ///- finite number: the lower bound + Value &lowerBound() { return _lb; } + ///The const version of \ref lowerBound() + const Value &lowerBound() const { return _lb; } + ///Reference to the upper bound. + + ///\return + ///- \ref INF "INF": the constraint is upper unbounded. + ///- \ref NaN "NaN": upper bound has not been set. + ///- finite number: the upper bound + Value &upperBound() { return _ub; } + ///The const version of \ref upperBound() + const Value &upperBound() const { return _ub; } + ///Is the constraint lower bounded? + bool lowerBounded() const { + return _lb != -INF && !isNaN(_lb); + } + ///Is the constraint upper bounded? + bool upperBounded() const { + return _ub != INF && !isNaN(_ub); + } + + }; + + ///Linear expression of rows + + ///This data structure represents a column of the matrix, + ///thas is it strores a linear expression of the dual variables + ///(\ref Row "Row"s). + /// + ///There are several ways to access and modify the contents of this + ///container. + ///\code + ///e[v]=5; + ///e[v]+=12; + ///e.erase(v); + ///\endcode + ///or you can also iterate through its elements. + ///\code + ///double s=0; + ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i) + /// s+=*i; + ///\endcode + ///(This code computes the sum of all coefficients). + ///- Numbers (double's) + ///and variables (\ref Row "Row"s) directly convert to an + ///\ref DualExpr and the usual linear operations are defined, so + ///\code + ///v+w + ///2*v-3.12*(v-w/2) + ///v*2.1+(3*v+(v*12+w)*3)/2 + ///\endcode + ///are valid \ref DualExpr dual expressions. + ///The usual assignment operations are also defined. + ///\code + ///e=v+w; + ///e+=2*v-3.12*(v-w/2); + ///e*=3.4; + ///e/=5; + ///\endcode + /// + ///\sa Expr + class DualExpr { + friend class LpBase; + public: + /// The key type of the expression + typedef LpBase::Row Key; + /// The value type of the expression + typedef LpBase::Value Value; + + protected: + std::map comps; + + public: + typedef True SolverExpr; + /// Default constructor + + /// Construct an empty expression, the coefficients are + /// initialized to zero. + DualExpr() {} + /// Construct an expression from a row + + /// Construct an expression, which has a term with \c r dual + /// variable and 1.0 coefficient. + DualExpr(const Row &r) { + typedef std::map::value_type pair_type; + comps.insert(pair_type(id(r), 1)); + } + /// Returns the coefficient of the row + Value operator[](const Row& r) const { + std::map::const_iterator it = comps.find(id(r)); + if (it != comps.end()) { + return it->second; + } else { + return 0; + } + } + /// Returns the coefficient of the row + Value& operator[](const Row& r) { + return comps[id(r)]; + } + /// Sets the coefficient of the row + void set(const Row &r, const Value &v) { + if (v != 0.0) { + typedef std::map::value_type pair_type; + comps.insert(pair_type(id(r), v)); + } else { + comps.erase(id(r)); + } + } + /// \brief Removes the coefficients which's absolute value does + /// not exceed \c epsilon. + void simplify(Value epsilon = 0.0) { + std::map::iterator it=comps.begin(); + while (it != comps.end()) { + std::map::iterator jt=it; + ++jt; + if (std::fabs((*it).second) <= epsilon) comps.erase(it); + it=jt; + } + } + + void simplify(Value epsilon = 0.0) const { + const_cast(this)->simplify(epsilon); + } + + ///Sets all coefficients to 0. + void clear() { + comps.clear(); + } + ///Compound assignment + DualExpr &operator+=(const DualExpr &e) { + for (std::map::const_iterator it=e.comps.begin(); + it!=e.comps.end(); ++it) + comps[it->first]+=it->second; + return *this; + } + ///Compound assignment + DualExpr &operator-=(const DualExpr &e) { + for (std::map::const_iterator it=e.comps.begin(); + it!=e.comps.end(); ++it) + comps[it->first]-=it->second; + return *this; + } + ///Multiply with a constant + DualExpr &operator*=(const Value &v) { + for (std::map::iterator it=comps.begin(); + it!=comps.end(); ++it) + it->second*=v; + return *this; + } + ///Division with a constant + DualExpr &operator/=(const Value &v) { + for (std::map::iterator it=comps.begin(); + it!=comps.end(); ++it) + it->second/=v; + return *this; + } + + ///Iterator over the expression + + ///The iterator iterates over the terms of the expression. + /// + ///\code + ///double s=0; + ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i) + /// s+= *i * dual(i); + ///\endcode + class CoeffIt { + private: + + std::map::iterator _it, _end; + + public: + + /// Sets the iterator to the first term + + /// Sets the iterator to the first term of the expression. + /// + CoeffIt(DualExpr& e) + : _it(e.comps.begin()), _end(e.comps.end()){} + + /// Convert the iterator to the row of the term + operator Row() const { + return rowFromId(_it->first); + } + + /// Returns the coefficient of the term + Value& operator*() { return _it->second; } + + /// Returns the coefficient of the term + const Value& operator*() const { return _it->second; } + + /// Next term + + /// Assign the iterator to the next term. + /// + CoeffIt& operator++() { ++_it; return *this; } + + /// Equality operator + bool operator==(Invalid) const { return _it == _end; } + /// Inequality operator + bool operator!=(Invalid) const { return _it != _end; } + }; + + ///Iterator over the expression + + ///The iterator iterates over the terms of the expression. + /// + ///\code + ///double s=0; + ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i) + /// s+= *i * dual(i); + ///\endcode + class ConstCoeffIt { + private: + + std::map::const_iterator _it, _end; + + public: + + /// Sets the iterator to the first term + + /// Sets the iterator to the first term of the expression. + /// + ConstCoeffIt(const DualExpr& e) + : _it(e.comps.begin()), _end(e.comps.end()){} + + /// Convert the iterator to the row of the term + operator Row() const { + return rowFromId(_it->first); + } + + /// Returns the coefficient of the term + const Value& operator*() const { return _it->second; } + + /// Next term + + /// Assign the iterator to the next term. + /// + ConstCoeffIt& operator++() { ++_it; return *this; } + + /// Equality operator + bool operator==(Invalid) const { return _it == _end; } + /// Inequality operator + bool operator!=(Invalid) const { return _it != _end; } + }; + }; + + + protected: + + class InsertIterator { + private: + + std::map& _host; + const _solver_bits::VarIndex& _index; + + public: + + typedef std::output_iterator_tag iterator_category; + typedef void difference_type; + typedef void value_type; + typedef void reference; + typedef void pointer; + + InsertIterator(std::map& host, + const _solver_bits::VarIndex& index) + : _host(host), _index(index) {} + + InsertIterator& operator=(const std::pair& value) { + typedef std::map::value_type pair_type; + _host.insert(pair_type(_index[value.first], value.second)); + return *this; + } + + InsertIterator& operator*() { return *this; } + InsertIterator& operator++() { return *this; } + InsertIterator operator++(int) { return *this; } + + }; + + class ExprIterator { + private: + std::map::const_iterator _host_it; + const _solver_bits::VarIndex& _index; + public: + + typedef std::bidirectional_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + typedef const std::pair value_type; + typedef value_type reference; + + class pointer { + public: + pointer(value_type& _value) : value(_value) {} + value_type* operator->() { return &value; } + private: + value_type value; + }; + + ExprIterator(const std::map::const_iterator& host_it, + const _solver_bits::VarIndex& index) + : _host_it(host_it), _index(index) {} + + reference operator*() { + return std::make_pair(_index(_host_it->first), _host_it->second); + } + + pointer operator->() { + return pointer(operator*()); + } + + ExprIterator& operator++() { ++_host_it; return *this; } + ExprIterator operator++(int) { + ExprIterator tmp(*this); ++_host_it; return tmp; + } + + ExprIterator& operator--() { --_host_it; return *this; } + ExprIterator operator--(int) { + ExprIterator tmp(*this); --_host_it; return tmp; + } + + bool operator==(const ExprIterator& it) const { + return _host_it == it._host_it; + } + + bool operator!=(const ExprIterator& it) const { + return _host_it != it._host_it; + } + + }; + + protected: + + //Abstract virtual functions + + virtual int _addColId(int col) { return cols.addIndex(col); } + virtual int _addRowId(int row) { return rows.addIndex(row); } + + virtual void _eraseColId(int col) { cols.eraseIndex(col); } + virtual void _eraseRowId(int row) { rows.eraseIndex(row); } + + virtual int _addCol() = 0; + virtual int _addRow() = 0; + + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) { + int row = _addRow(); + _setRowCoeffs(row, b, e); + _setRowLowerBound(row, l); + _setRowUpperBound(row, u); + return row; + } + + virtual void _eraseCol(int col) = 0; + virtual void _eraseRow(int row) = 0; + + virtual void _getColName(int col, std::string& name) const = 0; + virtual void _setColName(int col, const std::string& name) = 0; + virtual int _colByName(const std::string& name) const = 0; + + virtual void _getRowName(int row, std::string& name) const = 0; + virtual void _setRowName(int row, const std::string& name) = 0; + virtual int _rowByName(const std::string& name) const = 0; + + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0; + virtual void _getRowCoeffs(int i, InsertIterator b) const = 0; + + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0; + virtual void _getColCoeffs(int i, InsertIterator b) const = 0; + + virtual void _setCoeff(int row, int col, Value value) = 0; + virtual Value _getCoeff(int row, int col) const = 0; + + virtual void _setColLowerBound(int i, Value value) = 0; + virtual Value _getColLowerBound(int i) const = 0; + + virtual void _setColUpperBound(int i, Value value) = 0; + virtual Value _getColUpperBound(int i) const = 0; + + virtual void _setRowLowerBound(int i, Value value) = 0; + virtual Value _getRowLowerBound(int i) const = 0; + + virtual void _setRowUpperBound(int i, Value value) = 0; + virtual Value _getRowUpperBound(int i) const = 0; + + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0; + virtual void _getObjCoeffs(InsertIterator b) const = 0; + + virtual void _setObjCoeff(int i, Value obj_coef) = 0; + virtual Value _getObjCoeff(int i) const = 0; + + virtual void _setSense(Sense) = 0; + virtual Sense _getSense() const = 0; + + virtual void _clear() = 0; + + virtual const char* _solverName() const = 0; + + virtual void _messageLevel(MessageLevel level) = 0; + + //Own protected stuff + + //Constant component of the objective function + Value obj_const_comp; + + LpBase() : rows(), cols(), obj_const_comp(0) {} + + public: + + /// Virtual destructor + virtual ~LpBase() {} + + ///Gives back the name of the solver. + const char* solverName() const {return _solverName();} + + ///\name Build Up and Modify the LP + + ///@{ + + ///Add a new empty column (i.e a new variable) to the LP + Col addCol() { Col c; c._id = _addColId(_addCol()); return c;} + + ///\brief Adds several new columns (i.e variables) at once + /// + ///This magic function takes a container as its argument and fills + ///its elements with new columns (i.e. variables) + ///\param t can be + ///- a standard STL compatible iterable container with + ///\ref Col as its \c values_type like + ///\code + ///std::vector + ///std::list + ///\endcode + ///- a standard STL compatible iterable container with + ///\ref Col as its \c mapped_type like + ///\code + ///std::map + ///\endcode + ///- an iterable lemon \ref concepts::WriteMap "write map" like + ///\code + ///ListGraph::NodeMap + ///ListGraph::ArcMap + ///\endcode + ///\return The number of the created column. +#ifdef DOXYGEN + template + int addColSet(T &t) { return 0;} +#else + template + typename enable_if::type + addColSet(T &t,dummy<0> = 0) { + int s=0; + for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;} + return s; + } + template + typename enable_if::type + addColSet(T &t,dummy<1> = 1) { + int s=0; + for(typename T::iterator i=t.begin();i!=t.end();++i) { + i->second=addCol(); + s++; + } + return s; + } + template + typename enable_if::type + addColSet(T &t,dummy<2> = 2) { + int s=0; + for(typename T::MapIt i(t); i!=INVALID; ++i) + { + i.set(addCol()); + s++; + } + return s; + } +#endif + + ///Set a column (i.e a dual constraint) of the LP + + ///\param c is the column to be modified + ///\param e is a dual linear expression (see \ref DualExpr) + ///a better one. + void col(Col c, const DualExpr &e) { + e.simplify(); + _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows), + ExprIterator(e.comps.end(), rows)); + } + + ///Get a column (i.e a dual constraint) of the LP + + ///\param c is the column to get + ///\return the dual expression associated to the column + DualExpr col(Col c) const { + DualExpr e; + _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows)); + return e; + } + + ///Add a new column to the LP + + ///\param e is a dual linear expression (see \ref DualExpr) + ///\param o is the corresponding component of the objective + ///function. It is 0 by default. + ///\return The created column. + Col addCol(const DualExpr &e, Value o = 0) { + Col c=addCol(); + col(c,e); + objCoeff(c,o); + return c; + } + + ///Add a new empty row (i.e a new constraint) to the LP + + ///This function adds a new empty row (i.e a new constraint) to the LP. + ///\return The created row + Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;} + + ///\brief Add several new rows (i.e constraints) at once + /// + ///This magic function takes a container as its argument and fills + ///its elements with new row (i.e. variables) + ///\param t can be + ///- a standard STL compatible iterable container with + ///\ref Row as its \c values_type like + ///\code + ///std::vector + ///std::list + ///\endcode + ///- a standard STL compatible iterable container with + ///\ref Row as its \c mapped_type like + ///\code + ///std::map + ///\endcode + ///- an iterable lemon \ref concepts::WriteMap "write map" like + ///\code + ///ListGraph::NodeMap + ///ListGraph::ArcMap + ///\endcode + ///\return The number of rows created. +#ifdef DOXYGEN + template + int addRowSet(T &t) { return 0;} +#else + template + typename enable_if::type + addRowSet(T &t, dummy<0> = 0) { + int s=0; + for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;} + return s; + } + template + typename enable_if::type + addRowSet(T &t, dummy<1> = 1) { + int s=0; + for(typename T::iterator i=t.begin();i!=t.end();++i) { + i->second=addRow(); + s++; + } + return s; + } + template + typename enable_if::type + addRowSet(T &t, dummy<2> = 2) { + int s=0; + for(typename T::MapIt i(t); i!=INVALID; ++i) + { + i.set(addRow()); + s++; + } + return s; + } +#endif + + ///Set a row (i.e a constraint) of the LP + + ///\param r is the row to be modified + ///\param l is lower bound (-\ref INF means no bound) + ///\param e is a linear expression (see \ref Expr) + ///\param u is the upper bound (\ref INF means no bound) + void row(Row r, Value l, const Expr &e, Value u) { + e.simplify(); + _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols), + ExprIterator(e.comps.end(), cols)); + _setRowLowerBound(rows(id(r)),l - *e); + _setRowUpperBound(rows(id(r)),u - *e); + } + + ///Set a row (i.e a constraint) of the LP + + ///\param r is the row to be modified + ///\param c is a linear expression (see \ref Constr) + void row(Row r, const Constr &c) { + row(r, c.lowerBounded()?c.lowerBound():-INF, + c.expr(), c.upperBounded()?c.upperBound():INF); + } + + + ///Get a row (i.e a constraint) of the LP + + ///\param r is the row to get + ///\return the expression associated to the row + Expr row(Row r) const { + Expr e; + _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols)); + return e; + } + + ///Add a new row (i.e a new constraint) to the LP + + ///\param l is the lower bound (-\ref INF means no bound) + ///\param e is a linear expression (see \ref Expr) + ///\param u is the upper bound (\ref INF means no bound) + ///\return The created row. + Row addRow(Value l,const Expr &e, Value u) { + Row r; + e.simplify(); + r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols), + ExprIterator(e.comps.end(), cols), u - *e)); + return r; + } + + ///Add a new row (i.e a new constraint) to the LP + + ///\param c is a linear expression (see \ref Constr) + ///\return The created row. + Row addRow(const Constr &c) { + Row r; + c.expr().simplify(); + r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF, + ExprIterator(c.expr().comps.begin(), cols), + ExprIterator(c.expr().comps.end(), cols), + c.upperBounded()?c.upperBound()-*c.expr():INF)); + return r; + } + ///Erase a column (i.e a variable) from the LP + + ///\param c is the column to be deleted + void erase(Col c) { + _eraseCol(cols(id(c))); + _eraseColId(cols(id(c))); + } + ///Erase a row (i.e a constraint) from the LP + + ///\param r is the row to be deleted + void erase(Row r) { + _eraseRow(rows(id(r))); + _eraseRowId(rows(id(r))); + } + + /// Get the name of a column + + ///\param c is the coresponding column + ///\return The name of the colunm + std::string colName(Col c) const { + std::string name; + _getColName(cols(id(c)), name); + return name; + } + + /// Set the name of a column + + ///\param c is the coresponding column + ///\param name The name to be given + void colName(Col c, const std::string& name) { + _setColName(cols(id(c)), name); + } + + /// Get the column by its name + + ///\param name The name of the column + ///\return the proper column or \c INVALID + Col colByName(const std::string& name) const { + int k = _colByName(name); + return k != -1 ? Col(cols[k]) : Col(INVALID); + } + + /// Get the name of a row + + ///\param r is the coresponding row + ///\return The name of the row + std::string rowName(Row r) const { + std::string name; + _getRowName(rows(id(r)), name); + return name; + } + + /// Set the name of a row + + ///\param r is the coresponding row + ///\param name The name to be given + void rowName(Row r, const std::string& name) { + _setRowName(rows(id(r)), name); + } + + /// Get the row by its name + + ///\param name The name of the row + ///\return the proper row or \c INVALID + Row rowByName(const std::string& name) const { + int k = _rowByName(name); + return k != -1 ? Row(rows[k]) : Row(INVALID); + } + + /// Set an element of the coefficient matrix of the LP + + ///\param r is the row of the element to be modified + ///\param c is the column of the element to be modified + ///\param val is the new value of the coefficient + void coeff(Row r, Col c, Value val) { + _setCoeff(rows(id(r)),cols(id(c)), val); + } + + /// Get an element of the coefficient matrix of the LP + + ///\param r is the row of the element + ///\param c is the column of the element + ///\return the corresponding coefficient + Value coeff(Row r, Col c) const { + return _getCoeff(rows(id(r)),cols(id(c))); + } + + /// Set the lower bound of a column (i.e a variable) + + /// The lower bound of a variable (column) has to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or -\ref INF. + void colLowerBound(Col c, Value value) { + _setColLowerBound(cols(id(c)),value); + } + + /// Get the lower bound of a column (i.e a variable) + + /// This function returns the lower bound for column (variable) \c c + /// (this might be -\ref INF as well). + ///\return The lower bound for column \c c + Value colLowerBound(Col c) const { + return _getColLowerBound(cols(id(c))); + } + + ///\brief Set the lower bound of several columns + ///(i.e variables) at once + /// + ///This magic function takes a container as its argument + ///and applies the function on all of its elements. + ///The lower bound of a variable (column) has to be given by an + ///extended number of type Value, i.e. a finite number of type + ///Value or -\ref INF. +#ifdef DOXYGEN + template + void colLowerBound(T &t, Value value) { return 0;} +#else + template + typename enable_if::type + colLowerBound(T &t, Value value,dummy<0> = 0) { + for(typename T::iterator i=t.begin();i!=t.end();++i) { + colLowerBound(*i, value); + } + } + template + typename enable_if::type + colLowerBound(T &t, Value value,dummy<1> = 1) { + for(typename T::iterator i=t.begin();i!=t.end();++i) { + colLowerBound(i->second, value); + } + } + template + typename enable_if::type + colLowerBound(T &t, Value value,dummy<2> = 2) { + for(typename T::MapIt i(t); i!=INVALID; ++i){ + colLowerBound(*i, value); + } + } +#endif + + /// Set the upper bound of a column (i.e a variable) + + /// The upper bound of a variable (column) has to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or \ref INF. + void colUpperBound(Col c, Value value) { + _setColUpperBound(cols(id(c)),value); + }; + + /// Get the upper bound of a column (i.e a variable) + + /// This function returns the upper bound for column (variable) \c c + /// (this might be \ref INF as well). + /// \return The upper bound for column \c c + Value colUpperBound(Col c) const { + return _getColUpperBound(cols(id(c))); + } + + ///\brief Set the upper bound of several columns + ///(i.e variables) at once + /// + ///This magic function takes a container as its argument + ///and applies the function on all of its elements. + ///The upper bound of a variable (column) has to be given by an + ///extended number of type Value, i.e. a finite number of type + ///Value or \ref INF. +#ifdef DOXYGEN + template + void colUpperBound(T &t, Value value) { return 0;} +#else + template + typename enable_if::type + colUpperBound(T1 &t, Value value,dummy<0> = 0) { + for(typename T1::iterator i=t.begin();i!=t.end();++i) { + colUpperBound(*i, value); + } + } + template + typename enable_if::type + colUpperBound(T1 &t, Value value,dummy<1> = 1) { + for(typename T1::iterator i=t.begin();i!=t.end();++i) { + colUpperBound(i->second, value); + } + } + template + typename enable_if::type + colUpperBound(T1 &t, Value value,dummy<2> = 2) { + for(typename T1::MapIt i(t); i!=INVALID; ++i){ + colUpperBound(*i, value); + } + } +#endif + + /// Set the lower and the upper bounds of a column (i.e a variable) + + /// The lower and the upper bounds of + /// a variable (column) have to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value, -\ref INF or \ref INF. + void colBounds(Col c, Value lower, Value upper) { + _setColLowerBound(cols(id(c)),lower); + _setColUpperBound(cols(id(c)),upper); + } + + ///\brief Set the lower and the upper bound of several columns + ///(i.e variables) at once + /// + ///This magic function takes a container as its argument + ///and applies the function on all of its elements. + /// The lower and the upper bounds of + /// a variable (column) have to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value, -\ref INF or \ref INF. +#ifdef DOXYGEN + template + void colBounds(T &t, Value lower, Value upper) { return 0;} +#else + template + typename enable_if::type + colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) { + for(typename T2::iterator i=t.begin();i!=t.end();++i) { + colBounds(*i, lower, upper); + } + } + template + typename enable_if::type + colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) { + for(typename T2::iterator i=t.begin();i!=t.end();++i) { + colBounds(i->second, lower, upper); + } + } + template + typename enable_if::type + colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) { + for(typename T2::MapIt i(t); i!=INVALID; ++i){ + colBounds(*i, lower, upper); + } + } +#endif + + /// Set the lower bound of a row (i.e a constraint) + + /// The lower bound of a constraint (row) has to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or -\ref INF. + void rowLowerBound(Row r, Value value) { + _setRowLowerBound(rows(id(r)),value); + } + + /// Get the lower bound of a row (i.e a constraint) + + /// This function returns the lower bound for row (constraint) \c c + /// (this might be -\ref INF as well). + ///\return The lower bound for row \c r + Value rowLowerBound(Row r) const { + return _getRowLowerBound(rows(id(r))); + } + + /// Set the upper bound of a row (i.e a constraint) + + /// The upper bound of a constraint (row) has to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or -\ref INF. + void rowUpperBound(Row r, Value value) { + _setRowUpperBound(rows(id(r)),value); + } + + /// Get the upper bound of a row (i.e a constraint) + + /// This function returns the upper bound for row (constraint) \c c + /// (this might be -\ref INF as well). + ///\return The upper bound for row \c r + Value rowUpperBound(Row r) const { + return _getRowUpperBound(rows(id(r))); + } + + ///Set an element of the objective function + void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); }; + + ///Get an element of the objective function + Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); }; + + ///Set the objective function + + ///\param e is a linear expression of type \ref Expr. + /// + void obj(const Expr& e) { + _setObjCoeffs(ExprIterator(e.comps.begin(), cols), + ExprIterator(e.comps.end(), cols)); + obj_const_comp = *e; + } + + ///Get the objective function + + ///\return the objective function as a linear expression of type + ///Expr. + Expr obj() const { + Expr e; + _getObjCoeffs(InsertIterator(e.comps, cols)); + *e = obj_const_comp; + return e; + } + + + ///Set the direction of optimization + void sense(Sense sense) { _setSense(sense); } + + ///Query the direction of the optimization + Sense sense() const {return _getSense(); } + + ///Set the sense to maximization + void max() { _setSense(MAX); } + + ///Set the sense to maximization + void min() { _setSense(MIN); } + + ///Clears the problem + void clear() { _clear(); } + + /// Sets the message level of the solver + void messageLevel(MessageLevel level) { _messageLevel(level); } + + ///@} + + }; + + /// Addition + + ///\relates LpBase::Expr + /// + inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) { + LpBase::Expr tmp(a); + tmp+=b; + return tmp; + } + ///Substraction + + ///\relates LpBase::Expr + /// + inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) { + LpBase::Expr tmp(a); + tmp-=b; + return tmp; + } + ///Multiply with constant + + ///\relates LpBase::Expr + /// + inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) { + LpBase::Expr tmp(a); + tmp*=b; + return tmp; + } + + ///Multiply with constant + + ///\relates LpBase::Expr + /// + inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) { + LpBase::Expr tmp(b); + tmp*=a; + return tmp; + } + ///Divide with constant + + ///\relates LpBase::Expr + /// + inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) { + LpBase::Expr tmp(a); + tmp/=b; + return tmp; + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator<=(const LpBase::Expr &e, + const LpBase::Expr &f) { + return LpBase::Constr(0, f - e, LpBase::NaN); + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator<=(const LpBase::Value &e, + const LpBase::Expr &f) { + return LpBase::Constr(e, f, LpBase::NaN); + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator<=(const LpBase::Expr &e, + const LpBase::Value &f) { + return LpBase::Constr(LpBase::NaN, e, f); + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator>=(const LpBase::Expr &e, + const LpBase::Expr &f) { + return LpBase::Constr(0, e - f, LpBase::NaN); + } + + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator>=(const LpBase::Value &e, + const LpBase::Expr &f) { + return LpBase::Constr(LpBase::NaN, f, e); + } + + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator>=(const LpBase::Expr &e, + const LpBase::Value &f) { + return LpBase::Constr(f, e, LpBase::NaN); + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator==(const LpBase::Expr &e, + const LpBase::Value &f) { + return LpBase::Constr(f, e, f); + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator==(const LpBase::Expr &e, + const LpBase::Expr &f) { + return LpBase::Constr(0, f - e, 0); + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator<=(const LpBase::Value &n, + const LpBase::Constr &c) { + LpBase::Constr tmp(c); + LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint"); + tmp.lowerBound()=n; + return tmp; + } + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator<=(const LpBase::Constr &c, + const LpBase::Value &n) + { + LpBase::Constr tmp(c); + LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint"); + tmp.upperBound()=n; + return tmp; + } + + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator>=(const LpBase::Value &n, + const LpBase::Constr &c) { + LpBase::Constr tmp(c); + LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint"); + tmp.upperBound()=n; + return tmp; + } + ///Create constraint + + ///\relates LpBase::Constr + /// + inline LpBase::Constr operator>=(const LpBase::Constr &c, + const LpBase::Value &n) + { + LpBase::Constr tmp(c); + LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint"); + tmp.lowerBound()=n; + return tmp; + } + + ///Addition + + ///\relates LpBase::DualExpr + /// + inline LpBase::DualExpr operator+(const LpBase::DualExpr &a, + const LpBase::DualExpr &b) { + LpBase::DualExpr tmp(a); + tmp+=b; + return tmp; + } + ///Substraction + + ///\relates LpBase::DualExpr + /// + inline LpBase::DualExpr operator-(const LpBase::DualExpr &a, + const LpBase::DualExpr &b) { + LpBase::DualExpr tmp(a); + tmp-=b; + return tmp; + } + ///Multiply with constant + + ///\relates LpBase::DualExpr + /// + inline LpBase::DualExpr operator*(const LpBase::DualExpr &a, + const LpBase::Value &b) { + LpBase::DualExpr tmp(a); + tmp*=b; + return tmp; + } + + ///Multiply with constant + + ///\relates LpBase::DualExpr + /// + inline LpBase::DualExpr operator*(const LpBase::Value &a, + const LpBase::DualExpr &b) { + LpBase::DualExpr tmp(b); + tmp*=a; + return tmp; + } + ///Divide with constant + + ///\relates LpBase::DualExpr + /// + inline LpBase::DualExpr operator/(const LpBase::DualExpr &a, + const LpBase::Value &b) { + LpBase::DualExpr tmp(a); + tmp/=b; + return tmp; + } + + /// \ingroup lp_group + /// + /// \brief Common base class for LP solvers + /// + /// This class is an abstract base class for LP solvers. This class + /// provides a full interface for set and modify an LP problem, + /// solve it and retrieve the solution. You can use one of the + /// descendants as a concrete implementation, or the \c Lp + /// default LP solver. However, if you would like to handle LP + /// solvers as reference or pointer in a generic way, you can use + /// this class directly. + class LpSolver : virtual public LpBase { + public: + + /// The problem types for primal and dual problems + enum ProblemType { + /// = 0. Feasible solution hasn't been found (but may exist). + UNDEFINED = 0, + /// = 1. The problem has no feasible solution. + INFEASIBLE = 1, + /// = 2. Feasible solution found. + FEASIBLE = 2, + /// = 3. Optimal solution exists and found. + OPTIMAL = 3, + /// = 4. The cost function is unbounded. + UNBOUNDED = 4 + }; + + ///The basis status of variables + enum VarStatus { + /// The variable is in the basis + BASIC, + /// The variable is free, but not basic + FREE, + /// The variable has active lower bound + LOWER, + /// The variable has active upper bound + UPPER, + /// The variable is non-basic and fixed + FIXED + }; + + protected: + + virtual SolveExitStatus _solve() = 0; + + virtual Value _getPrimal(int i) const = 0; + virtual Value _getDual(int i) const = 0; + + virtual Value _getPrimalRay(int i) const = 0; + virtual Value _getDualRay(int i) const = 0; + + virtual Value _getPrimalValue() const = 0; + + virtual VarStatus _getColStatus(int i) const = 0; + virtual VarStatus _getRowStatus(int i) const = 0; + + virtual ProblemType _getPrimalType() const = 0; + virtual ProblemType _getDualType() const = 0; + + public: + + ///Allocate a new LP problem instance + virtual LpSolver* newSolver() const = 0; + ///Make a copy of the LP problem + virtual LpSolver* cloneSolver() const = 0; + + ///\name Solve the LP + + ///@{ + + ///\e Solve the LP problem at hand + /// + ///\return The result of the optimization procedure. Possible + ///values and their meanings can be found in the documentation of + ///\ref SolveExitStatus. + SolveExitStatus solve() { return _solve(); } + + ///@} + + ///\name Obtain the Solution + + ///@{ + + /// The type of the primal problem + ProblemType primalType() const { + return _getPrimalType(); + } + + /// The type of the dual problem + ProblemType dualType() const { + return _getDualType(); + } + + /// Return the primal value of the column + + /// Return the primal value of the column. + /// \pre The problem is solved. + Value primal(Col c) const { return _getPrimal(cols(id(c))); } + + /// Return the primal value of the expression + + /// Return the primal value of the expression, i.e. the dot + /// product of the primal solution and the expression. + /// \pre The problem is solved. + Value primal(const Expr& e) const { + double res = *e; + for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) { + res += *c * primal(c); + } + return res; + } + /// Returns a component of the primal ray + + /// The primal ray is solution of the modified primal problem, + /// where we change each finite bound to 0, and we looking for a + /// negative objective value in case of minimization, and positive + /// objective value for maximization. If there is such solution, + /// that proofs the unsolvability of the dual problem, and if a + /// feasible primal solution exists, then the unboundness of + /// primal problem. + /// + /// \pre The problem is solved and the dual problem is infeasible. + /// \note Some solvers does not provide primal ray calculation + /// functions. + Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); } + + /// Return the dual value of the row + + /// Return the dual value of the row. + /// \pre The problem is solved. + Value dual(Row r) const { return _getDual(rows(id(r))); } + + /// Return the dual value of the dual expression + + /// Return the dual value of the dual expression, i.e. the dot + /// product of the dual solution and the dual expression. + /// \pre The problem is solved. + Value dual(const DualExpr& e) const { + double res = 0.0; + for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) { + res += *r * dual(r); + } + return res; + } + + /// Returns a component of the dual ray + + /// The dual ray is solution of the modified primal problem, where + /// we change each finite bound to 0 (i.e. the objective function + /// coefficients in the primal problem), and we looking for a + /// ositive objective value. If there is such solution, that + /// proofs the unsolvability of the primal problem, and if a + /// feasible dual solution exists, then the unboundness of + /// dual problem. + /// + /// \pre The problem is solved and the primal problem is infeasible. + /// \note Some solvers does not provide dual ray calculation + /// functions. + Value dualRay(Row r) const { return _getDualRay(rows(id(r))); } + + /// Return the basis status of the column + + /// \see VarStatus + VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); } + + /// Return the basis status of the row + + /// \see VarStatus + VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); } + + ///The value of the objective function + + ///\return + ///- \ref INF or -\ref INF means either infeasibility or unboundedness + /// of the primal problem, depending on whether we minimize or maximize. + ///- \ref NaN if no primal solution is found. + ///- The (finite) objective value if an optimal solution is found. + Value primal() const { return _getPrimalValue()+obj_const_comp;} + ///@} + + protected: + + }; + + + /// \ingroup lp_group + /// + /// \brief Common base class for MIP solvers + /// + /// This class is an abstract base class for MIP solvers. This class + /// provides a full interface for set and modify an MIP problem, + /// solve it and retrieve the solution. You can use one of the + /// descendants as a concrete implementation, or the \c Lp + /// default MIP solver. However, if you would like to handle MIP + /// solvers as reference or pointer in a generic way, you can use + /// this class directly. + class MipSolver : virtual public LpBase { + public: + + /// The problem types for MIP problems + enum ProblemType { + /// = 0. Feasible solution hasn't been found (but may exist). + UNDEFINED = 0, + /// = 1. The problem has no feasible solution. + INFEASIBLE = 1, + /// = 2. Feasible solution found. + FEASIBLE = 2, + /// = 3. Optimal solution exists and found. + OPTIMAL = 3, + /// = 4. The cost function is unbounded. + ///The Mip or at least the relaxed problem is unbounded. + UNBOUNDED = 4 + }; + + ///Allocate a new MIP problem instance + virtual MipSolver* newSolver() const = 0; + ///Make a copy of the MIP problem + virtual MipSolver* cloneSolver() const = 0; + + ///\name Solve the MIP + + ///@{ + + /// Solve the MIP problem at hand + /// + ///\return The result of the optimization procedure. Possible + ///values and their meanings can be found in the documentation of + ///\ref SolveExitStatus. + SolveExitStatus solve() { return _solve(); } + + ///@} + + ///\name Set Column Type + ///@{ + + ///Possible variable (column) types (e.g. real, integer, binary etc.) + enum ColTypes { + /// = 0. Continuous variable (default). + REAL = 0, + /// = 1. Integer variable. + INTEGER = 1 + }; + + ///Sets the type of the given column to the given type + + ///Sets the type of the given column to the given type. + /// + void colType(Col c, ColTypes col_type) { + _setColType(cols(id(c)),col_type); + } + + ///Gives back the type of the column. + + ///Gives back the type of the column. + /// + ColTypes colType(Col c) const { + return _getColType(cols(id(c))); + } + ///@} + + ///\name Obtain the Solution + + ///@{ + + /// The type of the MIP problem + ProblemType type() const { + return _getType(); + } + + /// Return the value of the row in the solution + + /// Return the value of the row in the solution. + /// \pre The problem is solved. + Value sol(Col c) const { return _getSol(cols(id(c))); } + + /// Return the value of the expression in the solution + + /// Return the value of the expression in the solution, i.e. the + /// dot product of the solution and the expression. + /// \pre The problem is solved. + Value sol(const Expr& e) const { + double res = *e; + for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) { + res += *c * sol(c); + } + return res; + } + ///The value of the objective function + + ///\return + ///- \ref INF or -\ref INF means either infeasibility or unboundedness + /// of the problem, depending on whether we minimize or maximize. + ///- \ref NaN if no primal solution is found. + ///- The (finite) objective value if an optimal solution is found. + Value solValue() const { return _getSolValue()+obj_const_comp;} + ///@} + + protected: + + virtual SolveExitStatus _solve() = 0; + virtual ColTypes _getColType(int col) const = 0; + virtual void _setColType(int col, ColTypes col_type) = 0; + virtual ProblemType _getType() const = 0; + virtual Value _getSol(int i) const = 0; + virtual Value _getSolValue() const = 0; + + }; + + + +} //namespace lemon + +#endif //LEMON_LP_BASE_H diff --git a/lemon/lemon/lp_skeleton.cc b/lemon/lemon/lp_skeleton.cc new file mode 100644 index 0000000..d2adf54 --- /dev/null +++ b/lemon/lemon/lp_skeleton.cc @@ -0,0 +1,141 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +///\file +///\brief A skeleton file to implement LP solver interfaces +namespace lemon { + + int SkeletonSolverBase::_addCol() + { + return ++col_num; + } + + int SkeletonSolverBase::_addRow() + { + return ++row_num; + } + + int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value) + { + return ++row_num; + } + + void SkeletonSolverBase::_eraseCol(int) {} + void SkeletonSolverBase::_eraseRow(int) {} + + void SkeletonSolverBase::_getColName(int, std::string &) const {} + void SkeletonSolverBase::_setColName(int, const std::string &) {} + int SkeletonSolverBase::_colByName(const std::string&) const { return -1; } + + void SkeletonSolverBase::_getRowName(int, std::string &) const {} + void SkeletonSolverBase::_setRowName(int, const std::string &) {} + int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; } + + void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {} + void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {} + + void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {} + void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {} + + void SkeletonSolverBase::_setCoeff(int, int, Value) {} + SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const + { return 0; } + + void SkeletonSolverBase::_setColLowerBound(int, Value) {} + SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const + { return 0; } + + void SkeletonSolverBase::_setColUpperBound(int, Value) {} + SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const + { return 0; } + + void SkeletonSolverBase::_setRowLowerBound(int, Value) {} + SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const + { return 0; } + + void SkeletonSolverBase::_setRowUpperBound(int, Value) {} + SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const + { return 0; } + + void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {} + void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {}; + + void SkeletonSolverBase::_setObjCoeff(int, Value) {} + SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const + { return 0; } + + void SkeletonSolverBase::_setSense(Sense) {} + SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const + { return MIN; } + + void SkeletonSolverBase::_clear() { + row_num = col_num = 0; + } + + void SkeletonSolverBase::_messageLevel(MessageLevel) {} + + LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; } + + LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; } + LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; } + LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; } + + LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; } + LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; } + + LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const + { return UNDEFINED; } + + LpSkeleton::ProblemType LpSkeleton::_getDualType() const + { return UNDEFINED; } + + LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const + { return BASIC; } + + LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const + { return BASIC; } + + LpSkeleton* LpSkeleton::newSolver() const + { return static_cast(0); } + + LpSkeleton* LpSkeleton::cloneSolver() const + { return static_cast(0); } + + const char* LpSkeleton::_solverName() const { return "LpSkeleton"; } + + MipSkeleton::SolveExitStatus MipSkeleton::_solve() + { return SOLVED; } + + MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; } + MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; } + + MipSkeleton::ProblemType MipSkeleton::_getType() const + { return UNDEFINED; } + + MipSkeleton* MipSkeleton::newSolver() const + { return static_cast(0); } + + MipSkeleton* MipSkeleton::cloneSolver() const + { return static_cast(0); } + + const char* MipSkeleton::_solverName() const { return "MipSkeleton"; } + +} //namespace lemon + diff --git a/lemon/lemon/lp_skeleton.h b/lemon/lemon/lp_skeleton.h new file mode 100644 index 0000000..80c121a --- /dev/null +++ b/lemon/lemon/lp_skeleton.h @@ -0,0 +1,229 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_LP_SKELETON_H +#define LEMON_LP_SKELETON_H + +#include + +///\file +///\brief Skeleton file to implement LP/MIP solver interfaces +/// +///The classes in this file do nothing, but they can serve as skeletons when +///implementing an interface to new solvers. +namespace lemon { + + ///A skeleton class to implement LP/MIP solver base interface + + ///This class does nothing, but it can serve as a skeleton when + ///implementing an interface to new solvers. + class SkeletonSolverBase : public virtual LpBase { + int col_num,row_num; + + protected: + + SkeletonSolverBase() + : col_num(-1), row_num(-1) {} + + /// \e + virtual int _addCol(); + /// \e + virtual int _addRow(); + /// \e + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u); + /// \e + virtual void _eraseCol(int i); + /// \e + virtual void _eraseRow(int i); + + /// \e + virtual void _getColName(int col, std::string& name) const; + /// \e + virtual void _setColName(int col, const std::string& name); + /// \e + virtual int _colByName(const std::string& name) const; + + /// \e + virtual void _getRowName(int row, std::string& name) const; + /// \e + virtual void _setRowName(int row, const std::string& name); + /// \e + virtual int _rowByName(const std::string& name) const; + + /// \e + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e); + /// \e + virtual void _getRowCoeffs(int i, InsertIterator b) const; + /// \e + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e); + /// \e + virtual void _getColCoeffs(int i, InsertIterator b) const; + + /// Set one element of the coefficient matrix + virtual void _setCoeff(int row, int col, Value value); + + /// Get one element of the coefficient matrix + virtual Value _getCoeff(int row, int col) const; + + /// The lower bound of a variable (column) have to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or -\ref INF. + virtual void _setColLowerBound(int i, Value value); + /// \e + + /// The lower bound of a variable (column) is an + /// extended number of type Value, i.e. a finite number of type + /// Value or -\ref INF. + virtual Value _getColLowerBound(int i) const; + + /// The upper bound of a variable (column) have to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or \ref INF. + virtual void _setColUpperBound(int i, Value value); + /// \e + + /// The upper bound of a variable (column) is an + /// extended number of type Value, i.e. a finite number of type + /// Value or \ref INF. + virtual Value _getColUpperBound(int i) const; + + /// The lower bound of a constraint (row) have to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or -\ref INF. + virtual void _setRowLowerBound(int i, Value value); + /// \e + + /// The lower bound of a constraint (row) is an + /// extended number of type Value, i.e. a finite number of type + /// Value or -\ref INF. + virtual Value _getRowLowerBound(int i) const; + + /// The upper bound of a constraint (row) have to be given by an + /// extended number of type Value, i.e. a finite number of type + /// Value or \ref INF. + virtual void _setRowUpperBound(int i, Value value); + /// \e + + /// The upper bound of a constraint (row) is an + /// extended number of type Value, i.e. a finite number of type + /// Value or \ref INF. + virtual Value _getRowUpperBound(int i) const; + + /// \e + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e); + /// \e + virtual void _getObjCoeffs(InsertIterator b) const; + + /// \e + virtual void _setObjCoeff(int i, Value obj_coef); + /// \e + virtual Value _getObjCoeff(int i) const; + + ///\e + virtual void _setSense(Sense); + ///\e + virtual Sense _getSense() const; + + ///\e + virtual void _clear(); + + ///\e + virtual void _messageLevel(MessageLevel); + }; + + /// \brief Skeleton class for an LP solver interface + /// + ///This class does nothing, but it can serve as a skeleton when + ///implementing an interface to new solvers. + + ///\ingroup lp_group + class LpSkeleton : public LpSolver, public SkeletonSolverBase { + public: + ///\e + LpSkeleton() : LpSolver(), SkeletonSolverBase() {} + ///\e + virtual LpSkeleton* newSolver() const; + ///\e + virtual LpSkeleton* cloneSolver() const; + protected: + + ///\e + virtual SolveExitStatus _solve(); + + ///\e + virtual Value _getPrimal(int i) const; + ///\e + virtual Value _getDual(int i) const; + + ///\e + virtual Value _getPrimalValue() const; + + ///\e + virtual Value _getPrimalRay(int i) const; + ///\e + virtual Value _getDualRay(int i) const; + + ///\e + virtual ProblemType _getPrimalType() const; + ///\e + virtual ProblemType _getDualType() const; + + ///\e + virtual VarStatus _getColStatus(int i) const; + ///\e + virtual VarStatus _getRowStatus(int i) const; + + ///\e + virtual const char* _solverName() const; + + }; + + /// \brief Skeleton class for a MIP solver interface + /// + ///This class does nothing, but it can serve as a skeleton when + ///implementing an interface to new solvers. + ///\ingroup lp_group + class MipSkeleton : public MipSolver, public SkeletonSolverBase { + public: + ///\e + MipSkeleton() : MipSolver(), SkeletonSolverBase() {} + ///\e + virtual MipSkeleton* newSolver() const; + ///\e + virtual MipSkeleton* cloneSolver() const; + + protected: + ///\e + virtual SolveExitStatus _solve(); + + ///\e + virtual Value _getSol(int i) const; + + ///\e + virtual Value _getSolValue() const; + + ///\e + virtual ProblemType _getType() const; + + ///\e + virtual const char* _solverName() const; + }; + +} //namespace lemon + +#endif diff --git a/lemon/lemon/maps.h b/lemon/lemon/maps.h new file mode 100644 index 0000000..830a7ef --- /dev/null +++ b/lemon/lemon/maps.h @@ -0,0 +1,4057 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_MAPS_H +#define LEMON_MAPS_H + +#include +#include +#include +#include + +#include + +///\file +///\ingroup maps +///\brief Miscellaneous property maps + +namespace lemon { + + /// \addtogroup maps + /// @{ + + /// Base class of maps. + + /// Base class of maps. It provides the necessary type definitions + /// required by the map %concepts. + template + class MapBase { + public: + /// \brief The key type of the map. + typedef K Key; + /// \brief The value type of the map. + /// (The type of objects associated with the keys). + typedef V Value; + }; + + + /// Null map. (a.k.a. DoNothingMap) + + /// This map can be used if you have to provide a map only for + /// its type definitions, or if you have to provide a writable map, + /// but data written to it is not required (i.e. it will be sent to + /// /dev/null). + /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept. + /// + /// \sa ConstMap + template + class NullMap : public MapBase { + public: + ///\e + typedef K Key; + ///\e + typedef V Value; + + /// Gives back a default constructed element. + Value operator[](const Key&) const { return Value(); } + /// Absorbs the value. + void set(const Key&, const Value&) {} + }; + + /// Returns a \c NullMap class + + /// This function just returns a \c NullMap class. + /// \relates NullMap + template + NullMap nullMap() { + return NullMap(); + } + + + /// Constant map. + + /// This \ref concepts::ReadMap "readable map" assigns a specified + /// value to each key. + /// + /// In other aspects it is equivalent to \c NullMap. + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" + /// concept, but it absorbs the data written to it. + /// + /// The simplest way of using this map is through the constMap() + /// function. + /// + /// \sa NullMap + /// \sa IdentityMap + template + class ConstMap : public MapBase { + private: + V _value; + public: + ///\e + typedef K Key; + ///\e + typedef V Value; + + /// Default constructor + + /// Default constructor. + /// The value of the map will be default constructed. + ConstMap() {} + + /// Constructor with specified initial value + + /// Constructor with specified initial value. + /// \param v The initial value of the map. + ConstMap(const Value &v) : _value(v) {} + + /// Gives back the specified value. + Value operator[](const Key&) const { return _value; } + + /// Absorbs the value. + void set(const Key&, const Value&) {} + + /// Sets the value that is assigned to each key. + void setAll(const Value &v) { + _value = v; + } + + template + ConstMap(const ConstMap &, const Value &v) : _value(v) {} + }; + + /// Returns a \c ConstMap class + + /// This function just returns a \c ConstMap class. + /// \relates ConstMap + template + inline ConstMap constMap(const V &v) { + return ConstMap(v); + } + + template + inline ConstMap constMap() { + return ConstMap(); + } + + + template + struct Const {}; + + /// Constant map with inlined constant value. + + /// This \ref concepts::ReadMap "readable map" assigns a specified + /// value to each key. + /// + /// In other aspects it is equivalent to \c NullMap. + /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" + /// concept, but it absorbs the data written to it. + /// + /// The simplest way of using this map is through the constMap() + /// function. + /// + /// \sa NullMap + /// \sa IdentityMap + template + class ConstMap > : public MapBase { + public: + ///\e + typedef K Key; + ///\e + typedef V Value; + + /// Constructor. + ConstMap() {} + + /// Gives back the specified value. + Value operator[](const Key&) const { return v; } + + /// Absorbs the value. + void set(const Key&, const Value&) {} + }; + + /// Returns a \c ConstMap class with inlined constant value + + /// This function just returns a \c ConstMap class with inlined + /// constant value. + /// \relates ConstMap + template + inline ConstMap > constMap() { + return ConstMap >(); + } + + + /// Identity map. + + /// This \ref concepts::ReadMap "read-only map" gives back the given + /// key as value without any modification. + /// + /// \sa ConstMap + template + class IdentityMap : public MapBase { + public: + ///\e + typedef T Key; + ///\e + typedef T Value; + + /// Gives back the given value without any modification. + Value operator[](const Key &k) const { + return k; + } + }; + + /// Returns an \c IdentityMap class + + /// This function just returns an \c IdentityMap class. + /// \relates IdentityMap + template + inline IdentityMap identityMap() { + return IdentityMap(); + } + + + /// \brief Map for storing values for integer keys from the range + /// [0..size-1]. + /// + /// This map is essentially a wrapper for \c std::vector. It assigns + /// values to integer keys from the range [0..size-1]. + /// It can be used together with some data structures, e.g. + /// heap types and \c UnionFind, when the used items are small + /// integers. This map conforms to the \ref concepts::ReferenceMap + /// "ReferenceMap" concept. + /// + /// The simplest way of using this map is through the rangeMap() + /// function. + template + class RangeMap : public MapBase { + template + friend class RangeMap; + private: + + typedef std::vector Vector; + Vector _vector; + + public: + + /// Key type + typedef int Key; + /// Value type + typedef V Value; + /// Reference type + typedef typename Vector::reference Reference; + /// Const reference type + typedef typename Vector::const_reference ConstReference; + + typedef True ReferenceMapTag; + + public: + + /// Constructor with specified default value. + RangeMap(int size = 0, const Value &value = Value()) + : _vector(size, value) {} + + /// Constructs the map from an appropriate \c std::vector. + template + RangeMap(const std::vector& vector) + : _vector(vector.begin(), vector.end()) {} + + /// Constructs the map from another \c RangeMap. + template + RangeMap(const RangeMap &c) + : _vector(c._vector.begin(), c._vector.end()) {} + + /// Returns the size of the map. + int size() { + return _vector.size(); + } + + /// Resizes the map. + + /// Resizes the underlying \c std::vector container, so changes the + /// keyset of the map. + /// \param size The new size of the map. The new keyset will be the + /// range [0..size-1]. + /// \param value The default value to assign to the new keys. + void resize(int size, const Value &value = Value()) { + _vector.resize(size, value); + } + + private: + + RangeMap& operator=(const RangeMap&); + + public: + + ///\e + Reference operator[](const Key &k) { + return _vector[k]; + } + + ///\e + ConstReference operator[](const Key &k) const { + return _vector[k]; + } + + ///\e + void set(const Key &k, const Value &v) { + _vector[k] = v; + } + }; + + /// Returns a \c RangeMap class + + /// This function just returns a \c RangeMap class. + /// \relates RangeMap + template + inline RangeMap rangeMap(int size = 0, const V &value = V()) { + return RangeMap(size, value); + } + + /// \brief Returns a \c RangeMap class created from an appropriate + /// \c std::vector + + /// This function just returns a \c RangeMap class created from an + /// appropriate \c std::vector. + /// \relates RangeMap + template + inline RangeMap rangeMap(const std::vector &vector) { + return RangeMap(vector); + } + + + /// Map type based on \c std::map + + /// This map is essentially a wrapper for \c std::map with addition + /// that you can specify a default value for the keys that are not + /// stored actually. This value can be different from the default + /// contructed value (i.e. \c %Value()). + /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap" + /// concept. + /// + /// This map is useful if a default value should be assigned to most of + /// the keys and different values should be assigned only to a few + /// keys (i.e. the map is "sparse"). + /// The name of this type also refers to this important usage. + /// + /// Apart form that, this map can be used in many other cases since it + /// is based on \c std::map, which is a general associative container. + /// However, keep in mind that it is usually not as efficient as other + /// maps. + /// + /// The simplest way of using this map is through the sparseMap() + /// function. + template > + class SparseMap : public MapBase { + template + friend class SparseMap; + public: + + /// Key type + typedef K Key; + /// Value type + typedef V Value; + /// Reference type + typedef Value& Reference; + /// Const reference type + typedef const Value& ConstReference; + + typedef True ReferenceMapTag; + + private: + + typedef std::map Map; + Map _map; + Value _value; + + public: + + /// \brief Constructor with specified default value. + SparseMap(const Value &value = Value()) : _value(value) {} + /// \brief Constructs the map from an appropriate \c std::map, and + /// explicitly specifies a default value. + template + SparseMap(const std::map &map, + const Value &value = Value()) + : _map(map.begin(), map.end()), _value(value) {} + + /// \brief Constructs the map from another \c SparseMap. + template + SparseMap(const SparseMap &c) + : _map(c._map.begin(), c._map.end()), _value(c._value) {} + + private: + + SparseMap& operator=(const SparseMap&); + + public: + + ///\e + Reference operator[](const Key &k) { + typename Map::iterator it = _map.lower_bound(k); + if (it != _map.end() && !_map.key_comp()(k, it->first)) + return it->second; + else + return _map.insert(it, std::make_pair(k, _value))->second; + } + + ///\e + ConstReference operator[](const Key &k) const { + typename Map::const_iterator it = _map.find(k); + if (it != _map.end()) + return it->second; + else + return _value; + } + + ///\e + void set(const Key &k, const Value &v) { + typename Map::iterator it = _map.lower_bound(k); + if (it != _map.end() && !_map.key_comp()(k, it->first)) + it->second = v; + else + _map.insert(it, std::make_pair(k, v)); + } + + ///\e + void setAll(const Value &v) { + _value = v; + _map.clear(); + } + }; + + /// Returns a \c SparseMap class + + /// This function just returns a \c SparseMap class with specified + /// default value. + /// \relates SparseMap + template + inline SparseMap sparseMap(const V& value = V()) { + return SparseMap(value); + } + + template + inline SparseMap > sparseMap(const V& value = V()) { + return SparseMap >(value); + } + + /// \brief Returns a \c SparseMap class created from an appropriate + /// \c std::map + + /// This function just returns a \c SparseMap class created from an + /// appropriate \c std::map. + /// \relates SparseMap + template + inline SparseMap + sparseMap(const std::map &map, const V& value = V()) + { + return SparseMap(map, value); + } + + /// @} + + /// \addtogroup map_adaptors + /// @{ + + /// Composition of two maps + + /// This \ref concepts::ReadMap "read-only map" returns the + /// composition of two given maps. That is to say, if \c m1 is of + /// type \c M1 and \c m2 is of \c M2, then for + /// \code + /// ComposeMap cm(m1,m2); + /// \endcode + /// cm[x] will be equal to m1[m2[x]]. + /// + /// The \c Key type of the map is inherited from \c M2 and the + /// \c Value type is from \c M1. + /// \c M2::Value must be convertible to \c M1::Key. + /// + /// The simplest way of using this map is through the composeMap() + /// function. + /// + /// \sa CombineMap + template + class ComposeMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M2::Key Key; + ///\e + typedef typename M1::Value Value; + + /// Constructor + ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {} + + ///\e + typename MapTraits::ConstReturnValue + operator[](const Key &k) const { return _m1[_m2[k]]; } + }; + + /// Returns a \c ComposeMap class + + /// This function just returns a \c ComposeMap class. + /// + /// If \c m1 and \c m2 are maps and the \c Value type of \c m2 is + /// convertible to the \c Key of \c m1, then composeMap(m1,m2)[x] + /// will be equal to m1[m2[x]]. + /// + /// \relates ComposeMap + template + inline ComposeMap composeMap(const M1 &m1, const M2 &m2) { + return ComposeMap(m1, m2); + } + + + /// Combination of two maps using an STL (binary) functor. + + /// This \ref concepts::ReadMap "read-only map" takes two maps and a + /// binary functor and returns the combination of the two given maps + /// using the functor. + /// That is to say, if \c m1 is of type \c M1 and \c m2 is of \c M2 + /// and \c f is of \c F, then for + /// \code + /// CombineMap cm(m1,m2,f); + /// \endcode + /// cm[x] will be equal to f(m1[x],m2[x]). + /// + /// The \c Key type of the map is inherited from \c M1 (\c M1::Key + /// must be convertible to \c M2::Key) and the \c Value type is \c V. + /// \c M2::Value and \c M1::Value must be convertible to the + /// corresponding input parameter of \c F and the return type of \c F + /// must be convertible to \c V. + /// + /// The simplest way of using this map is through the combineMap() + /// function. + /// + /// \sa ComposeMap + template + class CombineMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + F _f; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef V Value; + + /// Constructor + CombineMap(const M1 &m1, const M2 &m2, const F &f = F()) + : _m1(m1), _m2(m2), _f(f) {} + ///\e + Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); } + }; + + /// Returns a \c CombineMap class + + /// This function just returns a \c CombineMap class. + /// + /// For example, if \c m1 and \c m2 are both maps with \c double + /// values, then + /// \code + /// combineMap(m1,m2,std::plus()) + /// \endcode + /// is equivalent to + /// \code + /// addMap(m1,m2) + /// \endcode + /// + /// This function is specialized for adaptable binary function + /// classes and C++ functions. + /// + /// \relates CombineMap + template + inline CombineMap + combineMap(const M1 &m1, const M2 &m2, const F &f) { + return CombineMap(m1,m2,f); + } + + template + inline CombineMap + combineMap(const M1 &m1, const M2 &m2, const F &f) { + return combineMap(m1,m2,f); + } + + template + inline CombineMap + combineMap(const M1 &m1, const M2 &m2, V (*f)(K1, K2)) { + return combineMap(m1,m2,f); + } + + + /// Converts an STL style (unary) functor to a map + + /// This \ref concepts::ReadMap "read-only map" returns the value + /// of a given functor. Actually, it just wraps the functor and + /// provides the \c Key and \c Value typedefs. + /// + /// Template parameters \c K and \c V will become its \c Key and + /// \c Value. In most cases they have to be given explicitly because + /// a functor typically does not provide \c argument_type and + /// \c result_type typedefs. + /// Parameter \c F is the type of the used functor. + /// + /// The simplest way of using this map is through the functorToMap() + /// function. + /// + /// \sa MapToFunctor + template + class FunctorToMap : public MapBase { + F _f; + public: + ///\e + typedef K Key; + ///\e + typedef V Value; + + /// Constructor + FunctorToMap(const F &f = F()) : _f(f) {} + ///\e + Value operator[](const Key &k) const { return _f(k); } + }; + + /// Returns a \c FunctorToMap class + + /// This function just returns a \c FunctorToMap class. + /// + /// This function is specialized for adaptable binary function + /// classes and C++ functions. + /// + /// \relates FunctorToMap + template + inline FunctorToMap functorToMap(const F &f) { + return FunctorToMap(f); + } + + template + inline FunctorToMap + functorToMap(const F &f) + { + return FunctorToMap(f); + } + + template + inline FunctorToMap functorToMap(V (*f)(K)) { + return FunctorToMap(f); + } + + + /// Converts a map to an STL style (unary) functor + + /// This class converts a map to an STL style (unary) functor. + /// That is it provides an operator() to read its values. + /// + /// For the sake of convenience it also works as a usual + /// \ref concepts::ReadMap "readable map", i.e. operator[] + /// and the \c Key and \c Value typedefs also exist. + /// + /// The simplest way of using this map is through the mapToFunctor() + /// function. + /// + ///\sa FunctorToMap + template + class MapToFunctor : public MapBase { + const M &_m; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + typedef typename M::Key argument_type; + typedef typename M::Value result_type; + + /// Constructor + MapToFunctor(const M &m) : _m(m) {} + ///\e + Value operator()(const Key &k) const { return _m[k]; } + ///\e + Value operator[](const Key &k) const { return _m[k]; } + }; + + /// Returns a \c MapToFunctor class + + /// This function just returns a \c MapToFunctor class. + /// \relates MapToFunctor + template + inline MapToFunctor mapToFunctor(const M &m) { + return MapToFunctor(m); + } + + + /// \brief Map adaptor to convert the \c Value type of a map to + /// another type using the default conversion. + + /// Map adaptor to convert the \c Value type of a \ref concepts::ReadMap + /// "readable map" to another type using the default conversion. + /// The \c Key type of it is inherited from \c M and the \c Value + /// type is \c V. + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept. + /// + /// The simplest way of using this map is through the convertMap() + /// function. + template + class ConvertMap : public MapBase { + const M &_m; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef V Value; + + /// Constructor + + /// Constructor. + /// \param m The underlying map. + ConvertMap(const M &m) : _m(m) {} + + ///\e + Value operator[](const Key &k) const { return _m[k]; } + }; + + /// Returns a \c ConvertMap class + + /// This function just returns a \c ConvertMap class. + /// \relates ConvertMap + template + inline ConvertMap convertMap(const M &map) { + return ConvertMap(map); + } + + + /// Applies all map setting operations to two maps + + /// This map has two \ref concepts::WriteMap "writable map" parameters + /// and each write request will be passed to both of them. + /// If \c M1 is also \ref concepts::ReadMap "readable", then the read + /// operations will return the corresponding values of \c M1. + /// + /// The \c Key and \c Value types are inherited from \c M1. + /// The \c Key and \c Value of \c M2 must be convertible from those + /// of \c M1. + /// + /// The simplest way of using this map is through the forkMap() + /// function. + template + class ForkMap : public MapBase { + M1 &_m1; + M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef typename M1::Value Value; + + /// Constructor + ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {} + /// Returns the value associated with the given key in the first map. + Value operator[](const Key &k) const { return _m1[k]; } + /// Sets the value associated with the given key in both maps. + void set(const Key &k, const Value &v) { _m1.set(k,v); _m2.set(k,v); } + }; + + /// Returns a \c ForkMap class + + /// This function just returns a \c ForkMap class. + /// \relates ForkMap + template + inline ForkMap forkMap(M1 &m1, M2 &m2) { + return ForkMap(m1,m2); + } + + + /// Sum of two maps + + /// This \ref concepts::ReadMap "read-only map" returns the sum + /// of the values of the two given maps. + /// Its \c Key and \c Value types are inherited from \c M1. + /// The \c Key and \c Value of \c M2 must be convertible to those of + /// \c M1. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// AddMap am(m1,m2); + /// \endcode + /// am[x] will be equal to m1[x]+m2[x]. + /// + /// The simplest way of using this map is through the addMap() + /// function. + /// + /// \sa SubMap, MulMap, DivMap + /// \sa ShiftMap, ShiftWriteMap + template + class AddMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef typename M1::Value Value; + + /// Constructor + AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]+_m2[k]; } + }; + + /// Returns an \c AddMap class + + /// This function just returns an \c AddMap class. + /// + /// For example, if \c m1 and \c m2 are both maps with \c double + /// values, then addMap(m1,m2)[x] will be equal to + /// m1[x]+m2[x]. + /// + /// \relates AddMap + template + inline AddMap addMap(const M1 &m1, const M2 &m2) { + return AddMap(m1,m2); + } + + + /// Difference of two maps + + /// This \ref concepts::ReadMap "read-only map" returns the difference + /// of the values of the two given maps. + /// Its \c Key and \c Value types are inherited from \c M1. + /// The \c Key and \c Value of \c M2 must be convertible to those of + /// \c M1. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// SubMap sm(m1,m2); + /// \endcode + /// sm[x] will be equal to m1[x]-m2[x]. + /// + /// The simplest way of using this map is through the subMap() + /// function. + /// + /// \sa AddMap, MulMap, DivMap + template + class SubMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef typename M1::Value Value; + + /// Constructor + SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]-_m2[k]; } + }; + + /// Returns a \c SubMap class + + /// This function just returns a \c SubMap class. + /// + /// For example, if \c m1 and \c m2 are both maps with \c double + /// values, then subMap(m1,m2)[x] will be equal to + /// m1[x]-m2[x]. + /// + /// \relates SubMap + template + inline SubMap subMap(const M1 &m1, const M2 &m2) { + return SubMap(m1,m2); + } + + + /// Product of two maps + + /// This \ref concepts::ReadMap "read-only map" returns the product + /// of the values of the two given maps. + /// Its \c Key and \c Value types are inherited from \c M1. + /// The \c Key and \c Value of \c M2 must be convertible to those of + /// \c M1. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// MulMap mm(m1,m2); + /// \endcode + /// mm[x] will be equal to m1[x]*m2[x]. + /// + /// The simplest way of using this map is through the mulMap() + /// function. + /// + /// \sa AddMap, SubMap, DivMap + /// \sa ScaleMap, ScaleWriteMap + template + class MulMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef typename M1::Value Value; + + /// Constructor + MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]*_m2[k]; } + }; + + /// Returns a \c MulMap class + + /// This function just returns a \c MulMap class. + /// + /// For example, if \c m1 and \c m2 are both maps with \c double + /// values, then mulMap(m1,m2)[x] will be equal to + /// m1[x]*m2[x]. + /// + /// \relates MulMap + template + inline MulMap mulMap(const M1 &m1,const M2 &m2) { + return MulMap(m1,m2); + } + + + /// Quotient of two maps + + /// This \ref concepts::ReadMap "read-only map" returns the quotient + /// of the values of the two given maps. + /// Its \c Key and \c Value types are inherited from \c M1. + /// The \c Key and \c Value of \c M2 must be convertible to those of + /// \c M1. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// DivMap dm(m1,m2); + /// \endcode + /// dm[x] will be equal to m1[x]/m2[x]. + /// + /// The simplest way of using this map is through the divMap() + /// function. + /// + /// \sa AddMap, SubMap, MulMap + template + class DivMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef typename M1::Value Value; + + /// Constructor + DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]/_m2[k]; } + }; + + /// Returns a \c DivMap class + + /// This function just returns a \c DivMap class. + /// + /// For example, if \c m1 and \c m2 are both maps with \c double + /// values, then divMap(m1,m2)[x] will be equal to + /// m1[x]/m2[x]. + /// + /// \relates DivMap + template + inline DivMap divMap(const M1 &m1,const M2 &m2) { + return DivMap(m1,m2); + } + + + /// Shifts a map with a constant. + + /// This \ref concepts::ReadMap "read-only map" returns the sum of + /// the given map and a constant value (i.e. it shifts the map with + /// the constant). Its \c Key and \c Value are inherited from \c M. + /// + /// Actually, + /// \code + /// ShiftMap sh(m,v); + /// \endcode + /// is equivalent to + /// \code + /// ConstMap cm(v); + /// AddMap > sh(m,cm); + /// \endcode + /// + /// The simplest way of using this map is through the shiftMap() + /// function. + /// + /// \sa ShiftWriteMap + template + class ShiftMap : public MapBase { + const M &_m; + C _v; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + /// Constructor + + /// Constructor. + /// \param m The undelying map. + /// \param v The constant value. + ShiftMap(const M &m, const C &v) : _m(m), _v(v) {} + ///\e + Value operator[](const Key &k) const { return _m[k]+_v; } + }; + + /// Shifts a map with a constant (read-write version). + + /// This \ref concepts::ReadWriteMap "read-write map" returns the sum + /// of the given map and a constant value (i.e. it shifts the map with + /// the constant). Its \c Key and \c Value are inherited from \c M. + /// It makes also possible to write the map. + /// + /// The simplest way of using this map is through the shiftWriteMap() + /// function. + /// + /// \sa ShiftMap + template + class ShiftWriteMap : public MapBase { + M &_m; + C _v; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + /// Constructor + + /// Constructor. + /// \param m The undelying map. + /// \param v The constant value. + ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {} + ///\e + Value operator[](const Key &k) const { return _m[k]+_v; } + ///\e + void set(const Key &k, const Value &v) { _m.set(k, v-_v); } + }; + + /// Returns a \c ShiftMap class + + /// This function just returns a \c ShiftMap class. + /// + /// For example, if \c m is a map with \c double values and \c v is + /// \c double, then shiftMap(m,v)[x] will be equal to + /// m[x]+v. + /// + /// \relates ShiftMap + template + inline ShiftMap shiftMap(const M &m, const C &v) { + return ShiftMap(m,v); + } + + /// Returns a \c ShiftWriteMap class + + /// This function just returns a \c ShiftWriteMap class. + /// + /// For example, if \c m is a map with \c double values and \c v is + /// \c double, then shiftWriteMap(m,v)[x] will be equal to + /// m[x]+v. + /// Moreover it makes also possible to write the map. + /// + /// \relates ShiftWriteMap + template + inline ShiftWriteMap shiftWriteMap(M &m, const C &v) { + return ShiftWriteMap(m,v); + } + + + /// Scales a map with a constant. + + /// This \ref concepts::ReadMap "read-only map" returns the value of + /// the given map multiplied from the left side with a constant value. + /// Its \c Key and \c Value are inherited from \c M. + /// + /// Actually, + /// \code + /// ScaleMap sc(m,v); + /// \endcode + /// is equivalent to + /// \code + /// ConstMap cm(v); + /// MulMap, M> sc(cm,m); + /// \endcode + /// + /// The simplest way of using this map is through the scaleMap() + /// function. + /// + /// \sa ScaleWriteMap + template + class ScaleMap : public MapBase { + const M &_m; + C _v; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + /// Constructor + + /// Constructor. + /// \param m The undelying map. + /// \param v The constant value. + ScaleMap(const M &m, const C &v) : _m(m), _v(v) {} + ///\e + Value operator[](const Key &k) const { return _v*_m[k]; } + }; + + /// Scales a map with a constant (read-write version). + + /// This \ref concepts::ReadWriteMap "read-write map" returns the value of + /// the given map multiplied from the left side with a constant value. + /// Its \c Key and \c Value are inherited from \c M. + /// It can also be used as write map if the \c / operator is defined + /// between \c Value and \c C and the given multiplier is not zero. + /// + /// The simplest way of using this map is through the scaleWriteMap() + /// function. + /// + /// \sa ScaleMap + template + class ScaleWriteMap : public MapBase { + M &_m; + C _v; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + /// Constructor + + /// Constructor. + /// \param m The undelying map. + /// \param v The constant value. + ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {} + ///\e + Value operator[](const Key &k) const { return _v*_m[k]; } + ///\e + void set(const Key &k, const Value &v) { _m.set(k, v/_v); } + }; + + /// Returns a \c ScaleMap class + + /// This function just returns a \c ScaleMap class. + /// + /// For example, if \c m is a map with \c double values and \c v is + /// \c double, then scaleMap(m,v)[x] will be equal to + /// v*m[x]. + /// + /// \relates ScaleMap + template + inline ScaleMap scaleMap(const M &m, const C &v) { + return ScaleMap(m,v); + } + + /// Returns a \c ScaleWriteMap class + + /// This function just returns a \c ScaleWriteMap class. + /// + /// For example, if \c m is a map with \c double values and \c v is + /// \c double, then scaleWriteMap(m,v)[x] will be equal to + /// v*m[x]. + /// Moreover it makes also possible to write the map. + /// + /// \relates ScaleWriteMap + template + inline ScaleWriteMap scaleWriteMap(M &m, const C &v) { + return ScaleWriteMap(m,v); + } + + + /// Negative of a map + + /// This \ref concepts::ReadMap "read-only map" returns the negative + /// of the values of the given map (using the unary \c - operator). + /// Its \c Key and \c Value are inherited from \c M. + /// + /// If M::Value is \c int, \c double etc., then + /// \code + /// NegMap neg(m); + /// \endcode + /// is equivalent to + /// \code + /// ScaleMap neg(m,-1); + /// \endcode + /// + /// The simplest way of using this map is through the negMap() + /// function. + /// + /// \sa NegWriteMap + template + class NegMap : public MapBase { + const M& _m; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + /// Constructor + NegMap(const M &m) : _m(m) {} + ///\e + Value operator[](const Key &k) const { return -_m[k]; } + }; + + /// Negative of a map (read-write version) + + /// This \ref concepts::ReadWriteMap "read-write map" returns the + /// negative of the values of the given map (using the unary \c - + /// operator). + /// Its \c Key and \c Value are inherited from \c M. + /// It makes also possible to write the map. + /// + /// If M::Value is \c int, \c double etc., then + /// \code + /// NegWriteMap neg(m); + /// \endcode + /// is equivalent to + /// \code + /// ScaleWriteMap neg(m,-1); + /// \endcode + /// + /// The simplest way of using this map is through the negWriteMap() + /// function. + /// + /// \sa NegMap + template + class NegWriteMap : public MapBase { + M &_m; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + /// Constructor + NegWriteMap(M &m) : _m(m) {} + ///\e + Value operator[](const Key &k) const { return -_m[k]; } + ///\e + void set(const Key &k, const Value &v) { _m.set(k, -v); } + }; + + /// Returns a \c NegMap class + + /// This function just returns a \c NegMap class. + /// + /// For example, if \c m is a map with \c double values, then + /// negMap(m)[x] will be equal to -m[x]. + /// + /// \relates NegMap + template + inline NegMap negMap(const M &m) { + return NegMap(m); + } + + /// Returns a \c NegWriteMap class + + /// This function just returns a \c NegWriteMap class. + /// + /// For example, if \c m is a map with \c double values, then + /// negWriteMap(m)[x] will be equal to -m[x]. + /// Moreover it makes also possible to write the map. + /// + /// \relates NegWriteMap + template + inline NegWriteMap negWriteMap(M &m) { + return NegWriteMap(m); + } + + + /// Absolute value of a map + + /// This \ref concepts::ReadMap "read-only map" returns the absolute + /// value of the values of the given map. + /// Its \c Key and \c Value are inherited from \c M. + /// \c Value must be comparable to \c 0 and the unary \c - + /// operator must be defined for it, of course. + /// + /// The simplest way of using this map is through the absMap() + /// function. + template + class AbsMap : public MapBase { + const M &_m; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef typename M::Value Value; + + /// Constructor + AbsMap(const M &m) : _m(m) {} + ///\e + Value operator[](const Key &k) const { + Value tmp = _m[k]; + return tmp >= 0 ? tmp : -tmp; + } + + }; + + /// Returns an \c AbsMap class + + /// This function just returns an \c AbsMap class. + /// + /// For example, if \c m is a map with \c double values, then + /// absMap(m)[x] will be equal to m[x] if + /// it is positive or zero and -m[x] if m[x] is + /// negative. + /// + /// \relates AbsMap + template + inline AbsMap absMap(const M &m) { + return AbsMap(m); + } + + /// @} + + // Logical maps and map adaptors: + + /// \addtogroup maps + /// @{ + + /// Constant \c true map. + + /// This \ref concepts::ReadMap "read-only map" assigns \c true to + /// each key. + /// + /// Note that + /// \code + /// TrueMap tm; + /// \endcode + /// is equivalent to + /// \code + /// ConstMap tm(true); + /// \endcode + /// + /// \sa FalseMap + /// \sa ConstMap + template + class TrueMap : public MapBase { + public: + ///\e + typedef K Key; + ///\e + typedef bool Value; + + /// Gives back \c true. + Value operator[](const Key&) const { return true; } + }; + + /// Returns a \c TrueMap class + + /// This function just returns a \c TrueMap class. + /// \relates TrueMap + template + inline TrueMap trueMap() { + return TrueMap(); + } + + + /// Constant \c false map. + + /// This \ref concepts::ReadMap "read-only map" assigns \c false to + /// each key. + /// + /// Note that + /// \code + /// FalseMap fm; + /// \endcode + /// is equivalent to + /// \code + /// ConstMap fm(false); + /// \endcode + /// + /// \sa TrueMap + /// \sa ConstMap + template + class FalseMap : public MapBase { + public: + ///\e + typedef K Key; + ///\e + typedef bool Value; + + /// Gives back \c false. + Value operator[](const Key&) const { return false; } + }; + + /// Returns a \c FalseMap class + + /// This function just returns a \c FalseMap class. + /// \relates FalseMap + template + inline FalseMap falseMap() { + return FalseMap(); + } + + /// @} + + /// \addtogroup map_adaptors + /// @{ + + /// Logical 'and' of two maps + + /// This \ref concepts::ReadMap "read-only map" returns the logical + /// 'and' of the values of the two given maps. + /// Its \c Key type is inherited from \c M1 and its \c Value type is + /// \c bool. \c M2::Key must be convertible to \c M1::Key. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// AndMap am(m1,m2); + /// \endcode + /// am[x] will be equal to m1[x]&&m2[x]. + /// + /// The simplest way of using this map is through the andMap() + /// function. + /// + /// \sa OrMap + /// \sa NotMap, NotWriteMap + template + class AndMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef bool Value; + + /// Constructor + AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; } + }; + + /// Returns an \c AndMap class + + /// This function just returns an \c AndMap class. + /// + /// For example, if \c m1 and \c m2 are both maps with \c bool values, + /// then andMap(m1,m2)[x] will be equal to + /// m1[x]&&m2[x]. + /// + /// \relates AndMap + template + inline AndMap andMap(const M1 &m1, const M2 &m2) { + return AndMap(m1,m2); + } + + + /// Logical 'or' of two maps + + /// This \ref concepts::ReadMap "read-only map" returns the logical + /// 'or' of the values of the two given maps. + /// Its \c Key type is inherited from \c M1 and its \c Value type is + /// \c bool. \c M2::Key must be convertible to \c M1::Key. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// OrMap om(m1,m2); + /// \endcode + /// om[x] will be equal to m1[x]||m2[x]. + /// + /// The simplest way of using this map is through the orMap() + /// function. + /// + /// \sa AndMap + /// \sa NotMap, NotWriteMap + template + class OrMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef bool Value; + + /// Constructor + OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]||_m2[k]; } + }; + + /// Returns an \c OrMap class + + /// This function just returns an \c OrMap class. + /// + /// For example, if \c m1 and \c m2 are both maps with \c bool values, + /// then orMap(m1,m2)[x] will be equal to + /// m1[x]||m2[x]. + /// + /// \relates OrMap + template + inline OrMap orMap(const M1 &m1, const M2 &m2) { + return OrMap(m1,m2); + } + + + /// Logical 'not' of a map + + /// This \ref concepts::ReadMap "read-only map" returns the logical + /// negation of the values of the given map. + /// Its \c Key is inherited from \c M and its \c Value is \c bool. + /// + /// The simplest way of using this map is through the notMap() + /// function. + /// + /// \sa NotWriteMap + template + class NotMap : public MapBase { + const M &_m; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef bool Value; + + /// Constructor + NotMap(const M &m) : _m(m) {} + ///\e + Value operator[](const Key &k) const { return !_m[k]; } + }; + + /// Logical 'not' of a map (read-write version) + + /// This \ref concepts::ReadWriteMap "read-write map" returns the + /// logical negation of the values of the given map. + /// Its \c Key is inherited from \c M and its \c Value is \c bool. + /// It makes also possible to write the map. When a value is set, + /// the opposite value is set to the original map. + /// + /// The simplest way of using this map is through the notWriteMap() + /// function. + /// + /// \sa NotMap + template + class NotWriteMap : public MapBase { + M &_m; + public: + ///\e + typedef typename M::Key Key; + ///\e + typedef bool Value; + + /// Constructor + NotWriteMap(M &m) : _m(m) {} + ///\e + Value operator[](const Key &k) const { return !_m[k]; } + ///\e + void set(const Key &k, bool v) { _m.set(k, !v); } + }; + + /// Returns a \c NotMap class + + /// This function just returns a \c NotMap class. + /// + /// For example, if \c m is a map with \c bool values, then + /// notMap(m)[x] will be equal to !m[x]. + /// + /// \relates NotMap + template + inline NotMap notMap(const M &m) { + return NotMap(m); + } + + /// Returns a \c NotWriteMap class + + /// This function just returns a \c NotWriteMap class. + /// + /// For example, if \c m is a map with \c bool values, then + /// notWriteMap(m)[x] will be equal to !m[x]. + /// Moreover it makes also possible to write the map. + /// + /// \relates NotWriteMap + template + inline NotWriteMap notWriteMap(M &m) { + return NotWriteMap(m); + } + + + /// Combination of two maps using the \c == operator + + /// This \ref concepts::ReadMap "read-only map" assigns \c true to + /// the keys for which the corresponding values of the two maps are + /// equal. + /// Its \c Key type is inherited from \c M1 and its \c Value type is + /// \c bool. \c M2::Key must be convertible to \c M1::Key. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// EqualMap em(m1,m2); + /// \endcode + /// em[x] will be equal to m1[x]==m2[x]. + /// + /// The simplest way of using this map is through the equalMap() + /// function. + /// + /// \sa LessMap + template + class EqualMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef bool Value; + + /// Constructor + EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]==_m2[k]; } + }; + + /// Returns an \c EqualMap class + + /// This function just returns an \c EqualMap class. + /// + /// For example, if \c m1 and \c m2 are maps with keys and values of + /// the same type, then equalMap(m1,m2)[x] will be equal to + /// m1[x]==m2[x]. + /// + /// \relates EqualMap + template + inline EqualMap equalMap(const M1 &m1, const M2 &m2) { + return EqualMap(m1,m2); + } + + + /// Combination of two maps using the \c < operator + + /// This \ref concepts::ReadMap "read-only map" assigns \c true to + /// the keys for which the corresponding value of the first map is + /// less then the value of the second map. + /// Its \c Key type is inherited from \c M1 and its \c Value type is + /// \c bool. \c M2::Key must be convertible to \c M1::Key. + /// + /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for + /// \code + /// LessMap lm(m1,m2); + /// \endcode + /// lm[x] will be equal to m1[x]. + /// + /// The simplest way of using this map is through the lessMap() + /// function. + /// + /// \sa EqualMap + template + class LessMap : public MapBase { + const M1 &_m1; + const M2 &_m2; + public: + ///\e + typedef typename M1::Key Key; + ///\e + typedef bool Value; + + /// Constructor + LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {} + ///\e + Value operator[](const Key &k) const { return _m1[k]<_m2[k]; } + }; + + /// Returns an \c LessMap class + + /// This function just returns an \c LessMap class. + /// + /// For example, if \c m1 and \c m2 are maps with keys and values of + /// the same type, then lessMap(m1,m2)[x] will be equal to + /// m1[x]. + /// + /// \relates LessMap + template + inline LessMap lessMap(const M1 &m1, const M2 &m2) { + return LessMap(m1,m2); + } + + namespace _maps_bits { + + template + struct IteratorTraits { + typedef typename std::iterator_traits<_Iterator>::value_type Value; + }; + + template + struct IteratorTraits<_Iterator, + typename exists::type> + { + typedef typename _Iterator::container_type::value_type Value; + }; + + } + + /// @} + + /// \addtogroup maps + /// @{ + + /// \brief Writable bool map for logging each \c true assigned element + /// + /// A \ref concepts::WriteMap "writable" bool map for logging + /// each \c true assigned element, i.e it copies subsequently each + /// keys set to \c true to the given iterator. + /// The most important usage of it is storing certain nodes or arcs + /// that were marked \c true by an algorithm. + /// + /// There are several algorithms that provide solutions through bool + /// maps and most of them assign \c true at most once for each key. + /// In these cases it is a natural request to store each \c true + /// assigned elements (in order of the assignment), which can be + /// easily done with LoggerBoolMap. + /// + /// The simplest way of using this map is through the loggerBoolMap() + /// function. + /// + /// \tparam IT The type of the iterator. + /// \tparam KEY The key type of the map. The default value set + /// according to the iterator type should work in most cases. + /// + /// \note The container of the iterator must contain enough space + /// for the elements or the iterator should be an inserter iterator. +#ifdef DOXYGEN + template +#else + template ::Value> +#endif + class LoggerBoolMap : public MapBase { + public: + + ///\e + typedef KEY Key; + ///\e + typedef bool Value; + ///\e + typedef IT Iterator; + + /// Constructor + LoggerBoolMap(Iterator it) + : _begin(it), _end(it) {} + + /// Gives back the given iterator set for the first key + Iterator begin() const { + return _begin; + } + + /// Gives back the the 'after the last' iterator + Iterator end() const { + return _end; + } + + /// The set function of the map + void set(const Key& key, Value value) { + if (value) { + *_end++ = key; + } + } + + private: + Iterator _begin; + Iterator _end; + }; + + /// Returns a \c LoggerBoolMap class + + /// This function just returns a \c LoggerBoolMap class. + /// + /// The most important usage of it is storing certain nodes or arcs + /// that were marked \c true by an algorithm. + /// For example, it makes easier to store the nodes in the processing + /// order of Dfs algorithm, as the following examples show. + /// \code + /// std::vector v; + /// dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s); + /// \endcode + /// \code + /// std::vector v(countNodes(g)); + /// dfs(g).processedMap(loggerBoolMap(v.begin())).run(s); + /// \endcode + /// + /// \note The container of the iterator must contain enough space + /// for the elements or the iterator should be an inserter iterator. + /// + /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so + /// it cannot be used when a readable map is needed, for example, as + /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms. + /// + /// \relates LoggerBoolMap + template + inline LoggerBoolMap loggerBoolMap(Iterator it) { + return LoggerBoolMap(it); + } + + /// @} + + /// \addtogroup graph_maps + /// @{ + + /// \brief Provides an immutable and unique id for each item in a graph. + /// + /// IdMap provides a unique and immutable id for each item of the + /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is + /// - \b unique: different items get different ids, + /// - \b immutable: the id of an item does not change (even if you + /// delete other nodes). + /// + /// Using this map you get access (i.e. can read) the inner id values of + /// the items stored in the graph, which is returned by the \c id() + /// function of the graph. This map can be inverted with its member + /// class \c InverseMap or with the \c operator()() member. + /// + /// \tparam GR The graph type. + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or + /// \c GR::Edge). + /// + /// \see RangeIdMap + template + class IdMap : public MapBase { + public: + /// The graph type of IdMap. + typedef GR Graph; + typedef GR Digraph; + /// The key type of IdMap (\c Node, \c Arc or \c Edge). + typedef K Item; + /// The key type of IdMap (\c Node, \c Arc or \c Edge). + typedef K Key; + /// The value type of IdMap. + typedef int Value; + + /// \brief Constructor. + /// + /// Constructor of the map. + explicit IdMap(const Graph& graph) : _graph(&graph) {} + + /// \brief Gives back the \e id of the item. + /// + /// Gives back the immutable and unique \e id of the item. + int operator[](const Item& item) const { return _graph->id(item);} + + /// \brief Gives back the \e item by its id. + /// + /// Gives back the \e item by its id. + Item operator()(int id) { return _graph->fromId(id, Item()); } + + private: + const Graph* _graph; + + public: + + /// \brief The inverse map type of IdMap. + /// + /// The inverse map type of IdMap. The subscript operator gives back + /// an item by its id. + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept. + /// \see inverse() + class InverseMap { + public: + + /// \brief Constructor. + /// + /// Constructor for creating an id-to-item map. + explicit InverseMap(const Graph& graph) : _graph(&graph) {} + + /// \brief Constructor. + /// + /// Constructor for creating an id-to-item map. + explicit InverseMap(const IdMap& map) : _graph(map._graph) {} + + /// \brief Gives back an item by its id. + /// + /// Gives back an item by its id. + Item operator[](int id) const { return _graph->fromId(id, Item());} + + private: + const Graph* _graph; + }; + + /// \brief Gives back the inverse of the map. + /// + /// Gives back the inverse of the IdMap. + InverseMap inverse() const { return InverseMap(*_graph);} + }; + + /// \brief Returns an \c IdMap class. + /// + /// This function just returns an \c IdMap class. + /// \relates IdMap + template + inline IdMap idMap(const GR& graph) { + return IdMap(graph); + } + + /// \brief General cross reference graph map type. + + /// This class provides simple invertable graph maps. + /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap) + /// and if a key is set to a new value, then stores it in the inverse map. + /// The graph items can be accessed by their values either using + /// \c InverseMap or \c operator()(), and the values of the map can be + /// accessed with an STL compatible forward iterator (\c ValueIt). + /// + /// This map is intended to be used when all associated values are + /// different (the map is actually invertable) or there are only a few + /// items with the same value. + /// Otherwise consider to use \c IterableValueMap, which is more + /// suitable and more efficient for such cases. It provides iterators + /// to traverse the items with the same associated value, but + /// it does not have \c InverseMap. + /// + /// This type is not reference map, so it cannot be modified with + /// the subscript operator. + /// + /// \tparam GR The graph type. + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or + /// \c GR::Edge). + /// \tparam V The value type of the map. + /// + /// \see IterableValueMap + template + class CrossRefMap + : protected ItemSetTraits::template Map::Type { + private: + + typedef typename ItemSetTraits:: + template Map::Type Map; + + typedef std::multimap Container; + Container _inv_map; + + public: + + /// The graph type of CrossRefMap. + typedef GR Graph; + typedef GR Digraph; + /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge). + typedef K Item; + /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge). + typedef K Key; + /// The value type of CrossRefMap. + typedef V Value; + + /// \brief Constructor. + /// + /// Construct a new CrossRefMap for the given graph. + explicit CrossRefMap(const Graph& graph) : Map(graph) {} + + /// \brief Forward iterator for values. + /// + /// This iterator is an STL compatible forward + /// iterator on the values of the map. The values can + /// be accessed in the [beginValue, endValue) range. + /// They are considered with multiplicity, so each value is + /// traversed for each item it is assigned to. + class ValueIt + : public std::iterator { + friend class CrossRefMap; + private: + ValueIt(typename Container::const_iterator _it) + : it(_it) {} + public: + + /// Constructor + ValueIt() {} + + /// \e + ValueIt& operator++() { ++it; return *this; } + /// \e + ValueIt operator++(int) { + ValueIt tmp(*this); + operator++(); + return tmp; + } + + /// \e + const Value& operator*() const { return it->first; } + /// \e + const Value* operator->() const { return &(it->first); } + + /// \e + bool operator==(ValueIt jt) const { return it == jt.it; } + /// \e + bool operator!=(ValueIt jt) const { return it != jt.it; } + + private: + typename Container::const_iterator it; + }; + + /// Alias for \c ValueIt + typedef ValueIt ValueIterator; + + /// \brief Returns an iterator to the first value. + /// + /// Returns an STL compatible iterator to the + /// first value of the map. The values of the + /// map can be accessed in the [beginValue, endValue) + /// range. + ValueIt beginValue() const { + return ValueIt(_inv_map.begin()); + } + + /// \brief Returns an iterator after the last value. + /// + /// Returns an STL compatible iterator after the + /// last value of the map. The values of the + /// map can be accessed in the [beginValue, endValue) + /// range. + ValueIt endValue() const { + return ValueIt(_inv_map.end()); + } + + /// \brief Sets the value associated with the given key. + /// + /// Sets the value associated with the given key. + void set(const Key& key, const Value& val) { + Value oldval = Map::operator[](key); + typename Container::iterator it; + for (it = _inv_map.equal_range(oldval).first; + it != _inv_map.equal_range(oldval).second; ++it) { + if (it->second == key) { + _inv_map.erase(it); + break; + } + } + _inv_map.insert(std::make_pair(val, key)); + Map::set(key, val); + } + + /// \brief Returns the value associated with the given key. + /// + /// Returns the value associated with the given key. + typename MapTraits::ConstReturnValue + operator[](const Key& key) const { + return Map::operator[](key); + } + + /// \brief Gives back an item by its value. + /// + /// This function gives back an item that is assigned to + /// the given value or \c INVALID if no such item exists. + /// If there are more items with the same associated value, + /// only one of them is returned. + Key operator()(const Value& val) const { + typename Container::const_iterator it = _inv_map.find(val); + return it != _inv_map.end() ? it->second : INVALID; + } + + /// \brief Returns the number of items with the given value. + /// + /// This function returns the number of items with the given value + /// associated with it. + int count(const Value &val) const { + return _inv_map.count(val); + } + + protected: + + /// \brief Erase the key from the map and the inverse map. + /// + /// Erase the key from the map and the inverse map. It is called by the + /// \c AlterationNotifier. + virtual void erase(const Key& key) { + Value val = Map::operator[](key); + typename Container::iterator it; + for (it = _inv_map.equal_range(val).first; + it != _inv_map.equal_range(val).second; ++it) { + if (it->second == key) { + _inv_map.erase(it); + break; + } + } + Map::erase(key); + } + + /// \brief Erase more keys from the map and the inverse map. + /// + /// Erase more keys from the map and the inverse map. It is called by the + /// \c AlterationNotifier. + virtual void erase(const std::vector& keys) { + for (int i = 0; i < int(keys.size()); ++i) { + Value val = Map::operator[](keys[i]); + typename Container::iterator it; + for (it = _inv_map.equal_range(val).first; + it != _inv_map.equal_range(val).second; ++it) { + if (it->second == keys[i]) { + _inv_map.erase(it); + break; + } + } + } + Map::erase(keys); + } + + /// \brief Clear the keys from the map and the inverse map. + /// + /// Clear the keys from the map and the inverse map. It is called by the + /// \c AlterationNotifier. + virtual void clear() { + _inv_map.clear(); + Map::clear(); + } + + public: + + /// \brief The inverse map type of CrossRefMap. + /// + /// The inverse map type of CrossRefMap. The subscript operator gives + /// back an item by its value. + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept. + /// \see inverse() + class InverseMap { + public: + /// \brief Constructor + /// + /// Constructor of the InverseMap. + explicit InverseMap(const CrossRefMap& inverted) + : _inverted(inverted) {} + + /// The value type of the InverseMap. + typedef typename CrossRefMap::Key Value; + /// The key type of the InverseMap. + typedef typename CrossRefMap::Value Key; + + /// \brief Subscript operator. + /// + /// Subscript operator. It gives back an item + /// that is assigned to the given value or \c INVALID + /// if no such item exists. + Value operator[](const Key& key) const { + return _inverted(key); + } + + private: + const CrossRefMap& _inverted; + }; + + /// \brief Gives back the inverse of the map. + /// + /// Gives back the inverse of the CrossRefMap. + InverseMap inverse() const { + return InverseMap(*this); + } + + }; + + /// \brief Provides continuous and unique id for the + /// items of a graph. + /// + /// RangeIdMap provides a unique and continuous + /// id for each item of a given type (\c Node, \c Arc or + /// \c Edge) in a graph. This id is + /// - \b unique: different items get different ids, + /// - \b continuous: the range of the ids is the set of integers + /// between 0 and \c n-1, where \c n is the number of the items of + /// this type (\c Node, \c Arc or \c Edge). + /// - So, the ids can change when deleting an item of the same type. + /// + /// Thus this id is not (necessarily) the same as what can get using + /// the \c id() function of the graph or \ref IdMap. + /// This map can be inverted with its member class \c InverseMap, + /// or with the \c operator()() member. + /// + /// \tparam GR The graph type. + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or + /// \c GR::Edge). + /// + /// \see IdMap + template + class RangeIdMap + : protected ItemSetTraits::template Map::Type { + + typedef typename ItemSetTraits::template Map::Type Map; + + public: + /// The graph type of RangeIdMap. + typedef GR Graph; + typedef GR Digraph; + /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge). + typedef K Item; + /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge). + typedef K Key; + /// The value type of RangeIdMap. + typedef int Value; + + /// \brief Constructor. + /// + /// Constructor. + explicit RangeIdMap(const Graph& gr) : Map(gr) { + Item it; + const typename Map::Notifier* nf = Map::notifier(); + for (nf->first(it); it != INVALID; nf->next(it)) { + Map::set(it, _inv_map.size()); + _inv_map.push_back(it); + } + } + + protected: + + /// \brief Adds a new key to the map. + /// + /// Add a new key to the map. It is called by the + /// \c AlterationNotifier. + virtual void add(const Item& item) { + Map::add(item); + Map::set(item, _inv_map.size()); + _inv_map.push_back(item); + } + + /// \brief Add more new keys to the map. + /// + /// Add more new keys to the map. It is called by the + /// \c AlterationNotifier. + virtual void add(const std::vector& items) { + Map::add(items); + for (int i = 0; i < int(items.size()); ++i) { + Map::set(items[i], _inv_map.size()); + _inv_map.push_back(items[i]); + } + } + + /// \brief Erase the key from the map. + /// + /// Erase the key from the map. It is called by the + /// \c AlterationNotifier. + virtual void erase(const Item& item) { + Map::set(_inv_map.back(), Map::operator[](item)); + _inv_map[Map::operator[](item)] = _inv_map.back(); + _inv_map.pop_back(); + Map::erase(item); + } + + /// \brief Erase more keys from the map. + /// + /// Erase more keys from the map. It is called by the + /// \c AlterationNotifier. + virtual void erase(const std::vector& items) { + for (int i = 0; i < int(items.size()); ++i) { + Map::set(_inv_map.back(), Map::operator[](items[i])); + _inv_map[Map::operator[](items[i])] = _inv_map.back(); + _inv_map.pop_back(); + } + Map::erase(items); + } + + /// \brief Build the unique map. + /// + /// Build the unique map. It is called by the + /// \c AlterationNotifier. + virtual void build() { + Map::build(); + Item it; + const typename Map::Notifier* nf = Map::notifier(); + for (nf->first(it); it != INVALID; nf->next(it)) { + Map::set(it, _inv_map.size()); + _inv_map.push_back(it); + } + } + + /// \brief Clear the keys from the map. + /// + /// Clear the keys from the map. It is called by the + /// \c AlterationNotifier. + virtual void clear() { + _inv_map.clear(); + Map::clear(); + } + + public: + + /// \brief Returns the maximal value plus one. + /// + /// Returns the maximal value plus one in the map. + unsigned int size() const { + return _inv_map.size(); + } + + /// \brief Swaps the position of the two items in the map. + /// + /// Swaps the position of the two items in the map. + void swap(const Item& p, const Item& q) { + int pi = Map::operator[](p); + int qi = Map::operator[](q); + Map::set(p, qi); + _inv_map[qi] = p; + Map::set(q, pi); + _inv_map[pi] = q; + } + + /// \brief Gives back the \e range \e id of the item + /// + /// Gives back the \e range \e id of the item. + int operator[](const Item& item) const { + return Map::operator[](item); + } + + /// \brief Gives back the item belonging to a \e range \e id + /// + /// Gives back the item belonging to the given \e range \e id. + Item operator()(int id) const { + return _inv_map[id]; + } + + private: + + typedef std::vector Container; + Container _inv_map; + + public: + + /// \brief The inverse map type of RangeIdMap. + /// + /// The inverse map type of RangeIdMap. The subscript operator gives + /// back an item by its \e range \e id. + /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept. + class InverseMap { + public: + /// \brief Constructor + /// + /// Constructor of the InverseMap. + explicit InverseMap(const RangeIdMap& inverted) + : _inverted(inverted) {} + + + /// The value type of the InverseMap. + typedef typename RangeIdMap::Key Value; + /// The key type of the InverseMap. + typedef typename RangeIdMap::Value Key; + + /// \brief Subscript operator. + /// + /// Subscript operator. It gives back the item + /// that the given \e range \e id currently belongs to. + Value operator[](const Key& key) const { + return _inverted(key); + } + + /// \brief Size of the map. + /// + /// Returns the size of the map. + unsigned int size() const { + return _inverted.size(); + } + + private: + const RangeIdMap& _inverted; + }; + + /// \brief Gives back the inverse of the map. + /// + /// Gives back the inverse of the RangeIdMap. + const InverseMap inverse() const { + return InverseMap(*this); + } + }; + + /// \brief Returns a \c RangeIdMap class. + /// + /// This function just returns an \c RangeIdMap class. + /// \relates RangeIdMap + template + inline RangeIdMap rangeIdMap(const GR& graph) { + return RangeIdMap(graph); + } + + /// \brief Dynamic iterable \c bool map. + /// + /// This class provides a special graph map type which can store a + /// \c bool value for graph items (\c Node, \c Arc or \c Edge). + /// For both \c true and \c false values it is possible to iterate on + /// the keys mapped to the value. + /// + /// This type is a reference map, so it can be modified with the + /// subscript operator. + /// + /// \tparam GR The graph type. + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or + /// \c GR::Edge). + /// + /// \see IterableIntMap, IterableValueMap + /// \see CrossRefMap + template + class IterableBoolMap + : protected ItemSetTraits::template Map::Type { + private: + typedef GR Graph; + + typedef typename ItemSetTraits::ItemIt KeyIt; + typedef typename ItemSetTraits::template Map::Type Parent; + + std::vector _array; + int _sep; + + public: + + /// Indicates that the map is reference map. + typedef True ReferenceMapTag; + + /// The key type + typedef K Key; + /// The value type + typedef bool Value; + /// The const reference type. + typedef const Value& ConstReference; + + private: + + int position(const Key& key) const { + return Parent::operator[](key); + } + + public: + + /// \brief Reference to the value of the map. + /// + /// This class is similar to the \c bool type. It can be converted to + /// \c bool and it provides the same operators. + class Reference { + friend class IterableBoolMap; + private: + Reference(IterableBoolMap& map, const Key& key) + : _key(key), _map(map) {} + public: + + Reference& operator=(const Reference& value) { + _map.set(_key, static_cast(value)); + return *this; + } + + operator bool() const { + return static_cast(_map)[_key]; + } + + Reference& operator=(bool value) { + _map.set(_key, value); + return *this; + } + Reference& operator&=(bool value) { + _map.set(_key, _map[_key] & value); + return *this; + } + Reference& operator|=(bool value) { + _map.set(_key, _map[_key] | value); + return *this; + } + Reference& operator^=(bool value) { + _map.set(_key, _map[_key] ^ value); + return *this; + } + private: + Key _key; + IterableBoolMap& _map; + }; + + /// \brief Constructor of the map with a default value. + /// + /// Constructor of the map with a default value. + explicit IterableBoolMap(const Graph& graph, bool def = false) + : Parent(graph) { + typename Parent::Notifier* nf = Parent::notifier(); + Key it; + for (nf->first(it); it != INVALID; nf->next(it)) { + Parent::set(it, _array.size()); + _array.push_back(it); + } + _sep = (def ? _array.size() : 0); + } + + /// \brief Const subscript operator of the map. + /// + /// Const subscript operator of the map. + bool operator[](const Key& key) const { + return position(key) < _sep; + } + + /// \brief Subscript operator of the map. + /// + /// Subscript operator of the map. + Reference operator[](const Key& key) { + return Reference(*this, key); + } + + /// \brief Set operation of the map. + /// + /// Set operation of the map. + void set(const Key& key, bool value) { + int pos = position(key); + if (value) { + if (pos < _sep) return; + Key tmp = _array[_sep]; + _array[_sep] = key; + Parent::set(key, _sep); + _array[pos] = tmp; + Parent::set(tmp, pos); + ++_sep; + } else { + if (pos >= _sep) return; + --_sep; + Key tmp = _array[_sep]; + _array[_sep] = key; + Parent::set(key, _sep); + _array[pos] = tmp; + Parent::set(tmp, pos); + } + } + + /// \brief Set all items. + /// + /// Set all items in the map. + /// \note Constant time operation. + void setAll(bool value) { + _sep = (value ? _array.size() : 0); + } + + /// \brief Returns the number of the keys mapped to \c true. + /// + /// Returns the number of the keys mapped to \c true. + int trueNum() const { + return _sep; + } + + /// \brief Returns the number of the keys mapped to \c false. + /// + /// Returns the number of the keys mapped to \c false. + int falseNum() const { + return _array.size() - _sep; + } + + /// \brief Iterator for the keys mapped to \c true. + /// + /// Iterator for the keys mapped to \c true. It works + /// like a graph item iterator, it can be converted to + /// the key type of the map, incremented with \c ++ operator, and + /// if the iterator leaves the last valid key, it will be equal to + /// \c INVALID. + class TrueIt : public Key { + public: + typedef Key Parent; + + /// \brief Creates an iterator. + /// + /// Creates an iterator. It iterates on the + /// keys mapped to \c true. + /// \param map The IterableBoolMap. + explicit TrueIt(const IterableBoolMap& map) + : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID), + _map(&map) {} + + /// \brief Invalid constructor \& conversion. + /// + /// This constructor initializes the iterator to be invalid. + /// \sa Invalid for more details. + TrueIt(Invalid) : Parent(INVALID), _map(0) {} + + /// \brief Increment operator. + /// + /// Increment operator. + TrueIt& operator++() { + int pos = _map->position(*this); + Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID); + return *this; + } + + private: + const IterableBoolMap* _map; + }; + + /// \brief Iterator for the keys mapped to \c false. + /// + /// Iterator for the keys mapped to \c false. It works + /// like a graph item iterator, it can be converted to + /// the key type of the map, incremented with \c ++ operator, and + /// if the iterator leaves the last valid key, it will be equal to + /// \c INVALID. + class FalseIt : public Key { + public: + typedef Key Parent; + + /// \brief Creates an iterator. + /// + /// Creates an iterator. It iterates on the + /// keys mapped to \c false. + /// \param map The IterableBoolMap. + explicit FalseIt(const IterableBoolMap& map) + : Parent(map._sep < int(map._array.size()) ? + map._array.back() : INVALID), _map(&map) {} + + /// \brief Invalid constructor \& conversion. + /// + /// This constructor initializes the iterator to be invalid. + /// \sa Invalid for more details. + FalseIt(Invalid) : Parent(INVALID), _map(0) {} + + /// \brief Increment operator. + /// + /// Increment operator. + FalseIt& operator++() { + int pos = _map->position(*this); + Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID); + return *this; + } + + private: + const IterableBoolMap* _map; + }; + + /// \brief Iterator for the keys mapped to a given value. + /// + /// Iterator for the keys mapped to a given value. It works + /// like a graph item iterator, it can be converted to + /// the key type of the map, incremented with \c ++ operator, and + /// if the iterator leaves the last valid key, it will be equal to + /// \c INVALID. + class ItemIt : public Key { + public: + typedef Key Parent; + + /// \brief Creates an iterator with a value. + /// + /// Creates an iterator with a value. It iterates on the + /// keys mapped to the given value. + /// \param map The IterableBoolMap. + /// \param value The value. + ItemIt(const IterableBoolMap& map, bool value) + : Parent(value ? + (map._sep > 0 ? + map._array[map._sep - 1] : INVALID) : + (map._sep < int(map._array.size()) ? + map._array.back() : INVALID)), _map(&map) {} + + /// \brief Invalid constructor \& conversion. + /// + /// This constructor initializes the iterator to be invalid. + /// \sa Invalid for more details. + ItemIt(Invalid) : Parent(INVALID), _map(0) {} + + /// \brief Increment operator. + /// + /// Increment operator. + ItemIt& operator++() { + int pos = _map->position(*this); + int _sep = pos >= _map->_sep ? _map->_sep : 0; + Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID); + return *this; + } + + private: + const IterableBoolMap* _map; + }; + + protected: + + virtual void add(const Key& key) { + Parent::add(key); + Parent::set(key, _array.size()); + _array.push_back(key); + } + + virtual void add(const std::vector& keys) { + Parent::add(keys); + for (int i = 0; i < int(keys.size()); ++i) { + Parent::set(keys[i], _array.size()); + _array.push_back(keys[i]); + } + } + + virtual void erase(const Key& key) { + int pos = position(key); + if (pos < _sep) { + --_sep; + Parent::set(_array[_sep], pos); + _array[pos] = _array[_sep]; + Parent::set(_array.back(), _sep); + _array[_sep] = _array.back(); + _array.pop_back(); + } else { + Parent::set(_array.back(), pos); + _array[pos] = _array.back(); + _array.pop_back(); + } + Parent::erase(key); + } + + virtual void erase(const std::vector& keys) { + for (int i = 0; i < int(keys.size()); ++i) { + int pos = position(keys[i]); + if (pos < _sep) { + --_sep; + Parent::set(_array[_sep], pos); + _array[pos] = _array[_sep]; + Parent::set(_array.back(), _sep); + _array[_sep] = _array.back(); + _array.pop_back(); + } else { + Parent::set(_array.back(), pos); + _array[pos] = _array.back(); + _array.pop_back(); + } + } + Parent::erase(keys); + } + + virtual void build() { + Parent::build(); + typename Parent::Notifier* nf = Parent::notifier(); + Key it; + for (nf->first(it); it != INVALID; nf->next(it)) { + Parent::set(it, _array.size()); + _array.push_back(it); + } + _sep = 0; + } + + virtual void clear() { + _array.clear(); + _sep = 0; + Parent::clear(); + } + + }; + + + namespace _maps_bits { + template + struct IterableIntMapNode { + IterableIntMapNode() : value(-1) {} + IterableIntMapNode(int _value) : value(_value) {} + Item prev, next; + int value; + }; + } + + /// \brief Dynamic iterable integer map. + /// + /// This class provides a special graph map type which can store an + /// integer value for graph items (\c Node, \c Arc or \c Edge). + /// For each non-negative value it is possible to iterate on the keys + /// mapped to the value. + /// + /// This map is intended to be used with small integer values, for which + /// it is efficient, and supports iteration only for non-negative values. + /// If you need large values and/or iteration for negative integers, + /// consider to use \ref IterableValueMap instead. + /// + /// This type is a reference map, so it can be modified with the + /// subscript operator. + /// + /// \note The size of the data structure depends on the largest + /// value in the map. + /// + /// \tparam GR The graph type. + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or + /// \c GR::Edge). + /// + /// \see IterableBoolMap, IterableValueMap + /// \see CrossRefMap + template + class IterableIntMap + : protected ItemSetTraits:: + template Map<_maps_bits::IterableIntMapNode >::Type { + public: + typedef typename ItemSetTraits:: + template Map<_maps_bits::IterableIntMapNode >::Type Parent; + + /// The key type + typedef K Key; + /// The value type + typedef int Value; + /// The graph type + typedef GR Graph; + + /// \brief Constructor of the map. + /// + /// Constructor of the map. It sets all values to -1. + explicit IterableIntMap(const Graph& graph) + : Parent(graph) {} + + /// \brief Constructor of the map with a given value. + /// + /// Constructor of the map with a given value. + explicit IterableIntMap(const Graph& graph, int value) + : Parent(graph, _maps_bits::IterableIntMapNode(value)) { + if (value >= 0) { + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) { + lace(it); + } + } + } + + private: + + void unlace(const Key& key) { + typename Parent::Value& node = Parent::operator[](key); + if (node.value < 0) return; + if (node.prev != INVALID) { + Parent::operator[](node.prev).next = node.next; + } else { + _first[node.value] = node.next; + } + if (node.next != INVALID) { + Parent::operator[](node.next).prev = node.prev; + } + while (!_first.empty() && _first.back() == INVALID) { + _first.pop_back(); + } + } + + void lace(const Key& key) { + typename Parent::Value& node = Parent::operator[](key); + if (node.value < 0) return; + if (node.value >= int(_first.size())) { + _first.resize(node.value + 1, INVALID); + } + node.prev = INVALID; + node.next = _first[node.value]; + if (node.next != INVALID) { + Parent::operator[](node.next).prev = key; + } + _first[node.value] = key; + } + + public: + + /// Indicates that the map is reference map. + typedef True ReferenceMapTag; + + /// \brief Reference to the value of the map. + /// + /// This class is similar to the \c int type. It can + /// be converted to \c int and it has the same operators. + class Reference { + friend class IterableIntMap; + private: + Reference(IterableIntMap& map, const Key& key) + : _key(key), _map(map) {} + public: + + Reference& operator=(const Reference& value) { + _map.set(_key, static_cast(value)); + return *this; + } + + operator const int&() const { + return static_cast(_map)[_key]; + } + + Reference& operator=(int value) { + _map.set(_key, value); + return *this; + } + Reference& operator++() { + _map.set(_key, _map[_key] + 1); + return *this; + } + int operator++(int) { + int value = _map[_key]; + _map.set(_key, value + 1); + return value; + } + Reference& operator--() { + _map.set(_key, _map[_key] - 1); + return *this; + } + int operator--(int) { + int value = _map[_key]; + _map.set(_key, value - 1); + return value; + } + Reference& operator+=(int value) { + _map.set(_key, _map[_key] + value); + return *this; + } + Reference& operator-=(int value) { + _map.set(_key, _map[_key] - value); + return *this; + } + Reference& operator*=(int value) { + _map.set(_key, _map[_key] * value); + return *this; + } + Reference& operator/=(int value) { + _map.set(_key, _map[_key] / value); + return *this; + } + Reference& operator%=(int value) { + _map.set(_key, _map[_key] % value); + return *this; + } + Reference& operator&=(int value) { + _map.set(_key, _map[_key] & value); + return *this; + } + Reference& operator|=(int value) { + _map.set(_key, _map[_key] | value); + return *this; + } + Reference& operator^=(int value) { + _map.set(_key, _map[_key] ^ value); + return *this; + } + Reference& operator<<=(int value) { + _map.set(_key, _map[_key] << value); + return *this; + } + Reference& operator>>=(int value) { + _map.set(_key, _map[_key] >> value); + return *this; + } + + private: + Key _key; + IterableIntMap& _map; + }; + + /// The const reference type. + typedef const Value& ConstReference; + + /// \brief Gives back the maximal value plus one. + /// + /// Gives back the maximal value plus one. + int size() const { + return _first.size(); + } + + /// \brief Set operation of the map. + /// + /// Set operation of the map. + void set(const Key& key, const Value& value) { + unlace(key); + Parent::operator[](key).value = value; + lace(key); + } + + /// \brief Const subscript operator of the map. + /// + /// Const subscript operator of the map. + const Value& operator[](const Key& key) const { + return Parent::operator[](key).value; + } + + /// \brief Subscript operator of the map. + /// + /// Subscript operator of the map. + Reference operator[](const Key& key) { + return Reference(*this, key); + } + + /// \brief Iterator for the keys with the same value. + /// + /// Iterator for the keys with the same value. It works + /// like a graph item iterator, it can be converted to + /// the item type of the map, incremented with \c ++ operator, and + /// if the iterator leaves the last valid item, it will be equal to + /// \c INVALID. + class ItemIt : public Key { + public: + typedef Key Parent; + + /// \brief Invalid constructor \& conversion. + /// + /// This constructor initializes the iterator to be invalid. + /// \sa Invalid for more details. + ItemIt(Invalid) : Parent(INVALID), _map(0) {} + + /// \brief Creates an iterator with a value. + /// + /// Creates an iterator with a value. It iterates on the + /// keys mapped to the given value. + /// \param map The IterableIntMap. + /// \param value The value. + ItemIt(const IterableIntMap& map, int value) : _map(&map) { + if (value < 0 || value >= int(_map->_first.size())) { + Parent::operator=(INVALID); + } else { + Parent::operator=(_map->_first[value]); + } + } + + /// \brief Increment operator. + /// + /// Increment operator. + ItemIt& operator++() { + Parent::operator=(_map->IterableIntMap::Parent:: + operator[](static_cast(*this)).next); + return *this; + } + + private: + const IterableIntMap* _map; + }; + + protected: + + virtual void erase(const Key& key) { + unlace(key); + Parent::erase(key); + } + + virtual void erase(const std::vector& keys) { + for (int i = 0; i < int(keys.size()); ++i) { + unlace(keys[i]); + } + Parent::erase(keys); + } + + virtual void clear() { + _first.clear(); + Parent::clear(); + } + + private: + std::vector _first; + }; + + namespace _maps_bits { + template + struct IterableValueMapNode { + IterableValueMapNode(Value _value = Value()) : value(_value) {} + Item prev, next; + Value value; + }; + } + + /// \brief Dynamic iterable map for comparable values. + /// + /// This class provides a special graph map type which can store a + /// comparable value for graph items (\c Node, \c Arc or \c Edge). + /// For each value it is possible to iterate on the keys mapped to + /// the value (\c ItemIt), and the values of the map can be accessed + /// with an STL compatible forward iterator (\c ValueIt). + /// The map stores a linked list for each value, which contains + /// the items mapped to the value, and the used values are stored + /// in balanced binary tree (\c std::map). + /// + /// \ref IterableBoolMap and \ref IterableIntMap are similar classes + /// specialized for \c bool and \c int values, respectively. + /// + /// This type is not reference map, so it cannot be modified with + /// the subscript operator. + /// + /// \tparam GR The graph type. + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or + /// \c GR::Edge). + /// \tparam V The value type of the map. It can be any comparable + /// value type. + /// + /// \see IterableBoolMap, IterableIntMap + /// \see CrossRefMap + template + class IterableValueMap + : protected ItemSetTraits:: + template Map<_maps_bits::IterableValueMapNode >::Type { + public: + typedef typename ItemSetTraits:: + template Map<_maps_bits::IterableValueMapNode >::Type Parent; + + /// The key type + typedef K Key; + /// The value type + typedef V Value; + /// The graph type + typedef GR Graph; + + public: + + /// \brief Constructor of the map with a given value. + /// + /// Constructor of the map with a given value. + explicit IterableValueMap(const Graph& graph, + const Value& value = Value()) + : Parent(graph, _maps_bits::IterableValueMapNode(value)) { + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) { + lace(it); + } + } + + protected: + + void unlace(const Key& key) { + typename Parent::Value& node = Parent::operator[](key); + if (node.prev != INVALID) { + Parent::operator[](node.prev).next = node.next; + } else { + if (node.next != INVALID) { + _first[node.value] = node.next; + } else { + _first.erase(node.value); + } + } + if (node.next != INVALID) { + Parent::operator[](node.next).prev = node.prev; + } + } + + void lace(const Key& key) { + typename Parent::Value& node = Parent::operator[](key); + typename std::map::iterator it = _first.find(node.value); + if (it == _first.end()) { + node.prev = node.next = INVALID; + _first.insert(std::make_pair(node.value, key)); + } else { + node.prev = INVALID; + node.next = it->second; + if (node.next != INVALID) { + Parent::operator[](node.next).prev = key; + } + it->second = key; + } + } + + public: + + /// \brief Forward iterator for values. + /// + /// This iterator is an STL compatible forward + /// iterator on the values of the map. The values can + /// be accessed in the [beginValue, endValue) range. + class ValueIt + : public std::iterator { + friend class IterableValueMap; + private: + ValueIt(typename std::map::const_iterator _it) + : it(_it) {} + public: + + /// Constructor + ValueIt() {} + + /// \e + ValueIt& operator++() { ++it; return *this; } + /// \e + ValueIt operator++(int) { + ValueIt tmp(*this); + operator++(); + return tmp; + } + + /// \e + const Value& operator*() const { return it->first; } + /// \e + const Value* operator->() const { return &(it->first); } + + /// \e + bool operator==(ValueIt jt) const { return it == jt.it; } + /// \e + bool operator!=(ValueIt jt) const { return it != jt.it; } + + private: + typename std::map::const_iterator it; + }; + + /// \brief Returns an iterator to the first value. + /// + /// Returns an STL compatible iterator to the + /// first value of the map. The values of the + /// map can be accessed in the [beginValue, endValue) + /// range. + ValueIt beginValue() const { + return ValueIt(_first.begin()); + } + + /// \brief Returns an iterator after the last value. + /// + /// Returns an STL compatible iterator after the + /// last value of the map. The values of the + /// map can be accessed in the [beginValue, endValue) + /// range. + ValueIt endValue() const { + return ValueIt(_first.end()); + } + + /// \brief Set operation of the map. + /// + /// Set operation of the map. + void set(const Key& key, const Value& value) { + unlace(key); + Parent::operator[](key).value = value; + lace(key); + } + + /// \brief Const subscript operator of the map. + /// + /// Const subscript operator of the map. + const Value& operator[](const Key& key) const { + return Parent::operator[](key).value; + } + + /// \brief Iterator for the keys with the same value. + /// + /// Iterator for the keys with the same value. It works + /// like a graph item iterator, it can be converted to + /// the item type of the map, incremented with \c ++ operator, and + /// if the iterator leaves the last valid item, it will be equal to + /// \c INVALID. + class ItemIt : public Key { + public: + typedef Key Parent; + + /// \brief Invalid constructor \& conversion. + /// + /// This constructor initializes the iterator to be invalid. + /// \sa Invalid for more details. + ItemIt(Invalid) : Parent(INVALID), _map(0) {} + + /// \brief Creates an iterator with a value. + /// + /// Creates an iterator with a value. It iterates on the + /// keys which have the given value. + /// \param map The IterableValueMap + /// \param value The value + ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) { + typename std::map::const_iterator it = + map._first.find(value); + if (it == map._first.end()) { + Parent::operator=(INVALID); + } else { + Parent::operator=(it->second); + } + } + + /// \brief Increment operator. + /// + /// Increment Operator. + ItemIt& operator++() { + Parent::operator=(_map->IterableValueMap::Parent:: + operator[](static_cast(*this)).next); + return *this; + } + + + private: + const IterableValueMap* _map; + }; + + protected: + + virtual void add(const Key& key) { + Parent::add(key); + lace(key); + } + + virtual void add(const std::vector& keys) { + Parent::add(keys); + for (int i = 0; i < int(keys.size()); ++i) { + lace(keys[i]); + } + } + + virtual void erase(const Key& key) { + unlace(key); + Parent::erase(key); + } + + virtual void erase(const std::vector& keys) { + for (int i = 0; i < int(keys.size()); ++i) { + unlace(keys[i]); + } + Parent::erase(keys); + } + + virtual void build() { + Parent::build(); + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) { + lace(it); + } + } + + virtual void clear() { + _first.clear(); + Parent::clear(); + } + + private: + std::map _first; + }; + + /// \brief Map of the source nodes of arcs in a digraph. + /// + /// SourceMap provides access for the source node of each arc in a digraph, + /// which is returned by the \c source() function of the digraph. + /// \tparam GR The digraph type. + /// \see TargetMap + template + class SourceMap { + public: + + /// The key type (the \c Arc type of the digraph). + typedef typename GR::Arc Key; + /// The value type (the \c Node type of the digraph). + typedef typename GR::Node Value; + + /// \brief Constructor + /// + /// Constructor. + /// \param digraph The digraph that the map belongs to. + explicit SourceMap(const GR& digraph) : _graph(digraph) {} + + /// \brief Returns the source node of the given arc. + /// + /// Returns the source node of the given arc. + Value operator[](const Key& arc) const { + return _graph.source(arc); + } + + private: + const GR& _graph; + }; + + /// \brief Returns a \c SourceMap class. + /// + /// This function just returns an \c SourceMap class. + /// \relates SourceMap + template + inline SourceMap sourceMap(const GR& graph) { + return SourceMap(graph); + } + + /// \brief Map of the target nodes of arcs in a digraph. + /// + /// TargetMap provides access for the target node of each arc in a digraph, + /// which is returned by the \c target() function of the digraph. + /// \tparam GR The digraph type. + /// \see SourceMap + template + class TargetMap { + public: + + /// The key type (the \c Arc type of the digraph). + typedef typename GR::Arc Key; + /// The value type (the \c Node type of the digraph). + typedef typename GR::Node Value; + + /// \brief Constructor + /// + /// Constructor. + /// \param digraph The digraph that the map belongs to. + explicit TargetMap(const GR& digraph) : _graph(digraph) {} + + /// \brief Returns the target node of the given arc. + /// + /// Returns the target node of the given arc. + Value operator[](const Key& e) const { + return _graph.target(e); + } + + private: + const GR& _graph; + }; + + /// \brief Returns a \c TargetMap class. + /// + /// This function just returns a \c TargetMap class. + /// \relates TargetMap + template + inline TargetMap targetMap(const GR& graph) { + return TargetMap(graph); + } + + /// \brief Map of the "forward" directed arc view of edges in a graph. + /// + /// ForwardMap provides access for the "forward" directed arc view of + /// each edge in a graph, which is returned by the \c direct() function + /// of the graph with \c true parameter. + /// \tparam GR The graph type. + /// \see BackwardMap + template + class ForwardMap { + public: + + /// The key type (the \c Edge type of the digraph). + typedef typename GR::Edge Key; + /// The value type (the \c Arc type of the digraph). + typedef typename GR::Arc Value; + + /// \brief Constructor + /// + /// Constructor. + /// \param graph The graph that the map belongs to. + explicit ForwardMap(const GR& graph) : _graph(graph) {} + + /// \brief Returns the "forward" directed arc view of the given edge. + /// + /// Returns the "forward" directed arc view of the given edge. + Value operator[](const Key& key) const { + return _graph.direct(key, true); + } + + private: + const GR& _graph; + }; + + /// \brief Returns a \c ForwardMap class. + /// + /// This function just returns an \c ForwardMap class. + /// \relates ForwardMap + template + inline ForwardMap forwardMap(const GR& graph) { + return ForwardMap(graph); + } + + /// \brief Map of the "backward" directed arc view of edges in a graph. + /// + /// BackwardMap provides access for the "backward" directed arc view of + /// each edge in a graph, which is returned by the \c direct() function + /// of the graph with \c false parameter. + /// \tparam GR The graph type. + /// \see ForwardMap + template + class BackwardMap { + public: + + /// The key type (the \c Edge type of the digraph). + typedef typename GR::Edge Key; + /// The value type (the \c Arc type of the digraph). + typedef typename GR::Arc Value; + + /// \brief Constructor + /// + /// Constructor. + /// \param graph The graph that the map belongs to. + explicit BackwardMap(const GR& graph) : _graph(graph) {} + + /// \brief Returns the "backward" directed arc view of the given edge. + /// + /// Returns the "backward" directed arc view of the given edge. + Value operator[](const Key& key) const { + return _graph.direct(key, false); + } + + private: + const GR& _graph; + }; + + /// \brief Returns a \c BackwardMap class + + /// This function just returns a \c BackwardMap class. + /// \relates BackwardMap + template + inline BackwardMap backwardMap(const GR& graph) { + return BackwardMap(graph); + } + + /// \brief Map of the in-degrees of nodes in a digraph. + /// + /// This map returns the in-degree of a node. Once it is constructed, + /// the degrees are stored in a standard \c NodeMap, so each query is done + /// in constant time. On the other hand, the values are updated automatically + /// whenever the digraph changes. + /// + /// \warning Besides \c addNode() and \c addArc(), a digraph structure + /// may provide alternative ways to modify the digraph. + /// The correct behavior of InDegMap is not guarantied if these additional + /// features are used. For example, the functions + /// \ref ListDigraph::changeSource() "changeSource()", + /// \ref ListDigraph::changeTarget() "changeTarget()" and + /// \ref ListDigraph::reverseArc() "reverseArc()" + /// of \ref ListDigraph will \e not update the degree values correctly. + /// + /// \sa OutDegMap + template + class InDegMap + : protected ItemSetTraits + ::ItemNotifier::ObserverBase { + + public: + + /// The graph type of InDegMap + typedef GR Graph; + typedef GR Digraph; + /// The key type + typedef typename Digraph::Node Key; + /// The value type + typedef int Value; + + typedef typename ItemSetTraits + ::ItemNotifier::ObserverBase Parent; + + private: + + class AutoNodeMap + : public ItemSetTraits::template Map::Type { + public: + + typedef typename ItemSetTraits:: + template Map::Type Parent; + + AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {} + + virtual void add(const Key& key) { + Parent::add(key); + Parent::set(key, 0); + } + + virtual void add(const std::vector& keys) { + Parent::add(keys); + for (int i = 0; i < int(keys.size()); ++i) { + Parent::set(keys[i], 0); + } + } + + virtual void build() { + Parent::build(); + Key it; + typename Parent::Notifier* nf = Parent::notifier(); + for (nf->first(it); it != INVALID; nf->next(it)) { + Parent::set(it, 0); + } + } + }; + + public: + + /// \brief Constructor. + /// + /// Constructor for creating an in-degree map. + explicit InDegMap(const Digraph& graph) + : _digraph(graph), _deg(graph) { + Parent::attach(_digraph.notifier(typename Digraph::Arc())); + + for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) { + _deg[it] = countInArcs(_digraph, it); + } + } + + /// \brief Gives back the in-degree of a Node. + /// + /// Gives back the in-degree of a Node. + int operator[](const Key& key) const { + return _deg[key]; + } + + protected: + + typedef typename Digraph::Arc Arc; + + virtual void add(const Arc& arc) { + ++_deg[_digraph.target(arc)]; + } + + virtual void add(const std::vector& arcs) { + for (int i = 0; i < int(arcs.size()); ++i) { + ++_deg[_digraph.target(arcs[i])]; + } + } + + virtual void erase(const Arc& arc) { + --_deg[_digraph.target(arc)]; + } + + virtual void erase(const std::vector& arcs) { + for (int i = 0; i < int(arcs.size()); ++i) { + --_deg[_digraph.target(arcs[i])]; + } + } + + virtual void build() { + for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) { + _deg[it] = countInArcs(_digraph, it); + } + } + + virtual void clear() { + for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) { + _deg[it] = 0; + } + } + private: + + const Digraph& _digraph; + AutoNodeMap _deg; + }; + + /// \brief Map of the out-degrees of nodes in a digraph. + /// + /// This map returns the out-degree of a node. Once it is constructed, + /// the degrees are stored in a standard \c NodeMap, so each query is done + /// in constant time. On the other hand, the values are updated automatically + /// whenever the digraph changes. + /// + /// \warning Besides \c addNode() and \c addArc(), a digraph structure + /// may provide alternative ways to modify the digraph. + /// The correct behavior of OutDegMap is not guarantied if these additional + /// features are used. For example, the functions + /// \ref ListDigraph::changeSource() "changeSource()", + /// \ref ListDigraph::changeTarget() "changeTarget()" and + /// \ref ListDigraph::reverseArc() "reverseArc()" + /// of \ref ListDigraph will \e not update the degree values correctly. + /// + /// \sa InDegMap + template + class OutDegMap + : protected ItemSetTraits + ::ItemNotifier::ObserverBase { + + public: + + /// The graph type of OutDegMap + typedef GR Graph; + typedef GR Digraph; + /// The key type + typedef typename Digraph::Node Key; + /// The value type + typedef int Value; + + typedef typename ItemSetTraits + ::ItemNotifier::ObserverBase Parent; + + private: + + class AutoNodeMap + : public ItemSetTraits::template Map::Type { + public: + + typedef typename ItemSetTraits:: + template Map::Type Parent; + + AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {} + + virtual void add(const Key& key) { + Parent::add(key); + Parent::set(key, 0); + } + virtual void add(const std::vector& keys) { + Parent::add(keys); + for (int i = 0; i < int(keys.size()); ++i) { + Parent::set(keys[i], 0); + } + } + virtual void build() { + Parent::build(); + Key it; + typename Parent::Notifier* nf = Parent::notifier(); + for (nf->first(it); it != INVALID; nf->next(it)) { + Parent::set(it, 0); + } + } + }; + + public: + + /// \brief Constructor. + /// + /// Constructor for creating an out-degree map. + explicit OutDegMap(const Digraph& graph) + : _digraph(graph), _deg(graph) { + Parent::attach(_digraph.notifier(typename Digraph::Arc())); + + for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) { + _deg[it] = countOutArcs(_digraph, it); + } + } + + /// \brief Gives back the out-degree of a Node. + /// + /// Gives back the out-degree of a Node. + int operator[](const Key& key) const { + return _deg[key]; + } + + protected: + + typedef typename Digraph::Arc Arc; + + virtual void add(const Arc& arc) { + ++_deg[_digraph.source(arc)]; + } + + virtual void add(const std::vector& arcs) { + for (int i = 0; i < int(arcs.size()); ++i) { + ++_deg[_digraph.source(arcs[i])]; + } + } + + virtual void erase(const Arc& arc) { + --_deg[_digraph.source(arc)]; + } + + virtual void erase(const std::vector& arcs) { + for (int i = 0; i < int(arcs.size()); ++i) { + --_deg[_digraph.source(arcs[i])]; + } + } + + virtual void build() { + for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) { + _deg[it] = countOutArcs(_digraph, it); + } + } + + virtual void clear() { + for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) { + _deg[it] = 0; + } + } + private: + + const Digraph& _digraph; + AutoNodeMap _deg; + }; + + /// \brief Potential difference map + /// + /// PotentialDifferenceMap returns the difference between the potentials of + /// the source and target nodes of each arc in a digraph, i.e. it returns + /// \code + /// potential[gr.target(arc)] - potential[gr.source(arc)]. + /// \endcode + /// \tparam GR The digraph type. + /// \tparam POT A node map storing the potentials. + template + class PotentialDifferenceMap { + public: + /// Key type + typedef typename GR::Arc Key; + /// Value type + typedef typename POT::Value Value; + + /// \brief Constructor + /// + /// Contructor of the map. + explicit PotentialDifferenceMap(const GR& gr, + const POT& potential) + : _digraph(gr), _potential(potential) {} + + /// \brief Returns the potential difference for the given arc. + /// + /// Returns the potential difference for the given arc, i.e. + /// \code + /// potential[gr.target(arc)] - potential[gr.source(arc)]. + /// \endcode + Value operator[](const Key& arc) const { + return _potential[_digraph.target(arc)] - + _potential[_digraph.source(arc)]; + } + + private: + const GR& _digraph; + const POT& _potential; + }; + + /// \brief Returns a PotentialDifferenceMap. + /// + /// This function just returns a PotentialDifferenceMap. + /// \relates PotentialDifferenceMap + template + PotentialDifferenceMap + potentialDifferenceMap(const GR& gr, const POT& potential) { + return PotentialDifferenceMap(gr, potential); + } + + + /// \brief Copy the values of a graph map to another map. + /// + /// This function copies the values of a graph map to another graph map. + /// \c To::Key must be equal or convertible to \c From::Key and + /// \c From::Value must be equal or convertible to \c To::Value. + /// + /// For example, an edge map of \c int value type can be copied to + /// an arc map of \c double value type in an undirected graph, but + /// an arc map cannot be copied to an edge map. + /// Note that even a \ref ConstMap can be copied to a standard graph map, + /// but \ref mapFill() can also be used for this purpose. + /// + /// \param gr The graph for which the maps are defined. + /// \param from The map from which the values have to be copied. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. + /// \param to The map to which the values have to be copied. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + template + void mapCopy(const GR& gr, const From& from, To& to) { + typedef typename To::Key Item; + typedef typename ItemSetTraits::ItemIt ItemIt; + + for (ItemIt it(gr); it != INVALID; ++it) { + to.set(it, from[it]); + } + } + + /// \brief Compare two graph maps. + /// + /// This function compares the values of two graph maps. It returns + /// \c true if the maps assign the same value for all items in the graph. + /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal + /// and their \c Value types must be comparable using \c %operator==(). + /// + /// \param gr The graph for which the maps are defined. + /// \param map1 The first map. + /// \param map2 The second map. + template + bool mapCompare(const GR& gr, const Map1& map1, const Map2& map2) { + typedef typename Map2::Key Item; + typedef typename ItemSetTraits::ItemIt ItemIt; + + for (ItemIt it(gr); it != INVALID; ++it) { + if (!(map1[it] == map2[it])) return false; + } + return true; + } + + /// \brief Return an item having minimum value of a graph map. + /// + /// This function returns an item (\c Node, \c Arc or \c Edge) having + /// minimum value of the given graph map. + /// If the item set is empty, it returns \c INVALID. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + template + typename Map::Key mapMin(const GR& gr, const Map& map) { + return mapMin(gr, map, std::less()); + } + + /// \brief Return an item having minimum value of a graph map. + /// + /// This function returns an item (\c Node, \c Arc or \c Edge) having + /// minimum value of the given graph map. + /// If the item set is empty, it returns \c INVALID. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param comp Comparison function object. + template + typename Map::Key mapMin(const GR& gr, const Map& map, const Comp& comp) { + typedef typename Map::Key Item; + typedef typename Map::Value Value; + typedef typename ItemSetTraits::ItemIt ItemIt; + + ItemIt min_item(gr); + if (min_item == INVALID) return INVALID; + Value min = map[min_item]; + for (ItemIt it(gr); it != INVALID; ++it) { + if (comp(map[it], min)) { + min = map[it]; + min_item = it; + } + } + return min_item; + } + + /// \brief Return an item having maximum value of a graph map. + /// + /// This function returns an item (\c Node, \c Arc or \c Edge) having + /// maximum value of the given graph map. + /// If the item set is empty, it returns \c INVALID. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + template + typename Map::Key mapMax(const GR& gr, const Map& map) { + return mapMax(gr, map, std::less()); + } + + /// \brief Return an item having maximum value of a graph map. + /// + /// This function returns an item (\c Node, \c Arc or \c Edge) having + /// maximum value of the given graph map. + /// If the item set is empty, it returns \c INVALID. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param comp Comparison function object. + template + typename Map::Key mapMax(const GR& gr, const Map& map, const Comp& comp) { + typedef typename Map::Key Item; + typedef typename Map::Value Value; + typedef typename ItemSetTraits::ItemIt ItemIt; + + ItemIt max_item(gr); + if (max_item == INVALID) return INVALID; + Value max = map[max_item]; + for (ItemIt it(gr); it != INVALID; ++it) { + if (comp(max, map[it])) { + max = map[it]; + max_item = it; + } + } + return max_item; + } + + /// \brief Return the minimum value of a graph map. + /// + /// This function returns the minimum value of the given graph map. + /// The corresponding item set of the graph must not be empty. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + template + typename Map::Value mapMinValue(const GR& gr, const Map& map) { + return map[mapMin(gr, map, std::less())]; + } + + /// \brief Return the minimum value of a graph map. + /// + /// This function returns the minimum value of the given graph map. + /// The corresponding item set of the graph must not be empty. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param comp Comparison function object. + template + typename Map::Value + mapMinValue(const GR& gr, const Map& map, const Comp& comp) { + return map[mapMin(gr, map, comp)]; + } + + /// \brief Return the maximum value of a graph map. + /// + /// This function returns the maximum value of the given graph map. + /// The corresponding item set of the graph must not be empty. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + template + typename Map::Value mapMaxValue(const GR& gr, const Map& map) { + return map[mapMax(gr, map, std::less())]; + } + + /// \brief Return the maximum value of a graph map. + /// + /// This function returns the maximum value of the given graph map. + /// The corresponding item set of the graph must not be empty. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param comp Comparison function object. + template + typename Map::Value + mapMaxValue(const GR& gr, const Map& map, const Comp& comp) { + return map[mapMax(gr, map, comp)]; + } + + /// \brief Return an item having a specified value in a graph map. + /// + /// This function returns an item (\c Node, \c Arc or \c Edge) having + /// the specified assigned value in the given graph map. + /// If no such item exists, it returns \c INVALID. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param val The value that have to be found. + template + typename Map::Key + mapFind(const GR& gr, const Map& map, const typename Map::Value& val) { + typedef typename Map::Key Item; + typedef typename ItemSetTraits::ItemIt ItemIt; + + for (ItemIt it(gr); it != INVALID; ++it) { + if (map[it] == val) return it; + } + return INVALID; + } + + /// \brief Return an item having value for which a certain predicate is + /// true in a graph map. + /// + /// This function returns an item (\c Node, \c Arc or \c Edge) having + /// such assigned value for which the specified predicate is true + /// in the given graph map. + /// If no such item exists, it returns \c INVALID. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param pred The predicate function object. + template + typename Map::Key + mapFindIf(const GR& gr, const Map& map, const Pred& pred) { + typedef typename Map::Key Item; + typedef typename ItemSetTraits::ItemIt ItemIt; + + for (ItemIt it(gr); it != INVALID; ++it) { + if (pred(map[it])) return it; + } + return INVALID; + } + + /// \brief Return the number of items having a specified value in a + /// graph map. + /// + /// This function returns the number of items (\c Node, \c Arc or \c Edge) + /// having the specified assigned value in the given graph map. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param val The value that have to be counted. + template + int mapCount(const GR& gr, const Map& map, const typename Map::Value& val) { + typedef typename Map::Key Item; + typedef typename ItemSetTraits::ItemIt ItemIt; + + int cnt = 0; + for (ItemIt it(gr); it != INVALID; ++it) { + if (map[it] == val) ++cnt; + } + return cnt; + } + + /// \brief Return the number of items having values for which a certain + /// predicate is true in a graph map. + /// + /// This function returns the number of items (\c Node, \c Arc or \c Edge) + /// having such assigned values for which the specified predicate is true + /// in the given graph map. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. + /// \param pred The predicate function object. + template + int mapCountIf(const GR& gr, const Map& map, const Pred& pred) { + typedef typename Map::Key Item; + typedef typename ItemSetTraits::ItemIt ItemIt; + + int cnt = 0; + for (ItemIt it(gr); it != INVALID; ++it) { + if (pred(map[it])) ++cnt; + } + return cnt; + } + + /// \brief Fill a graph map with a certain value. + /// + /// This function sets the specified value for all items (\c Node, + /// \c Arc or \c Edge) in the given graph map. + /// + /// \param gr The graph for which the map is defined. + /// \param map The graph map. It must conform to the + /// \ref concepts::WriteMap "WriteMap" concept. + /// \param val The value. + template + void mapFill(const GR& gr, Map& map, const typename Map::Value& val) { + typedef typename Map::Key Item; + typedef typename ItemSetTraits::ItemIt ItemIt; + + for (ItemIt it(gr); it != INVALID; ++it) { + map.set(it, val); + } + } + + /// @} +} + +#endif // LEMON_MAPS_H diff --git a/lemon/lemon/matching.h b/lemon/lemon/matching.h new file mode 100644 index 0000000..a57d271 --- /dev/null +++ b/lemon/lemon/matching.h @@ -0,0 +1,3505 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_MATCHING_H +#define LEMON_MATCHING_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +///\ingroup matching +///\file +///\brief Maximum matching algorithms in general graphs. + +namespace lemon { + + /// \ingroup matching + /// + /// \brief Maximum cardinality matching in general graphs + /// + /// This class implements Edmonds' alternating forest matching algorithm + /// for finding a maximum cardinality matching in a general undirected graph. + /// It can be started from an arbitrary initial matching + /// (the default is the empty one). + /// + /// The dual solution of the problem is a map of the nodes to + /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D), + /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds + /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph + /// with factor-critical components, the nodes in \c ODD/A form the + /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having + /// a perfect matching. The number of the factor-critical components + /// minus the number of barrier nodes is a lower bound on the + /// unmatched nodes, and the matching is optimal if and only if this bound is + /// tight. This decomposition can be obtained using \ref status() or + /// \ref statusMap() after running the algorithm. + /// + /// \tparam GR The undirected graph type the algorithm runs on. + template + class MaxMatching { + public: + + /// The graph type of the algorithm + typedef GR Graph; + /// The type of the matching map + typedef typename Graph::template NodeMap + MatchingMap; + + ///\brief Status constants for Gallai-Edmonds decomposition. + /// + ///These constants are used for indicating the Gallai-Edmonds + ///decomposition of a graph. The nodes with status \c EVEN (or \c D) + ///induce a subgraph with factor-critical components, the nodes with + ///status \c ODD (or \c A) form the canonical barrier, and the nodes + ///with status \c MATCHED (or \c C) induce a subgraph having a + ///perfect matching. + enum Status { + EVEN = 1, ///< = 1. (\c D is an alias for \c EVEN.) + D = 1, + MATCHED = 0, ///< = 0. (\c C is an alias for \c MATCHED.) + C = 0, + ODD = -1, ///< = -1. (\c A is an alias for \c ODD.) + A = -1, + UNMATCHED = -2 ///< = -2. + }; + + /// The type of the status map + typedef typename Graph::template NodeMap StatusMap; + + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + typedef UnionFindEnum BlossomSet; + typedef ExtendFindEnum TreeSet; + typedef RangeMap NodeIntMap; + typedef MatchingMap EarMap; + typedef std::vector NodeQueue; + + const Graph& _graph; + MatchingMap* _matching; + StatusMap* _status; + + EarMap* _ear; + + IntNodeMap* _blossom_set_index; + BlossomSet* _blossom_set; + NodeIntMap* _blossom_rep; + + IntNodeMap* _tree_set_index; + TreeSet* _tree_set; + + NodeQueue _node_queue; + int _process, _postpone, _last; + + int _node_num; + + private: + + void createStructures() { + _node_num = countNodes(_graph); + if (!_matching) { + _matching = new MatchingMap(_graph); + } + if (!_status) { + _status = new StatusMap(_graph); + } + if (!_ear) { + _ear = new EarMap(_graph); + } + if (!_blossom_set) { + _blossom_set_index = new IntNodeMap(_graph); + _blossom_set = new BlossomSet(*_blossom_set_index); + } + if (!_blossom_rep) { + _blossom_rep = new NodeIntMap(_node_num); + } + if (!_tree_set) { + _tree_set_index = new IntNodeMap(_graph); + _tree_set = new TreeSet(*_tree_set_index); + } + _node_queue.resize(_node_num); + } + + void destroyStructures() { + if (_matching) { + delete _matching; + } + if (_status) { + delete _status; + } + if (_ear) { + delete _ear; + } + if (_blossom_set) { + delete _blossom_set; + delete _blossom_set_index; + } + if (_blossom_rep) { + delete _blossom_rep; + } + if (_tree_set) { + delete _tree_set_index; + delete _tree_set; + } + } + + void processDense(const Node& n) { + _process = _postpone = _last = 0; + _node_queue[_last++] = n; + + while (_process != _last) { + Node u = _node_queue[_process++]; + for (OutArcIt a(_graph, u); a != INVALID; ++a) { + Node v = _graph.target(a); + if ((*_status)[v] == MATCHED) { + extendOnArc(a); + } else if ((*_status)[v] == UNMATCHED) { + augmentOnArc(a); + return; + } + } + } + + while (_postpone != _last) { + Node u = _node_queue[_postpone++]; + + for (OutArcIt a(_graph, u); a != INVALID ; ++a) { + Node v = _graph.target(a); + + if ((*_status)[v] == EVEN) { + if (_blossom_set->find(u) != _blossom_set->find(v)) { + shrinkOnEdge(a); + } + } + + while (_process != _last) { + Node w = _node_queue[_process++]; + for (OutArcIt b(_graph, w); b != INVALID; ++b) { + Node x = _graph.target(b); + if ((*_status)[x] == MATCHED) { + extendOnArc(b); + } else if ((*_status)[x] == UNMATCHED) { + augmentOnArc(b); + return; + } + } + } + } + } + } + + void processSparse(const Node& n) { + _process = _last = 0; + _node_queue[_last++] = n; + while (_process != _last) { + Node u = _node_queue[_process++]; + for (OutArcIt a(_graph, u); a != INVALID; ++a) { + Node v = _graph.target(a); + + if ((*_status)[v] == EVEN) { + if (_blossom_set->find(u) != _blossom_set->find(v)) { + shrinkOnEdge(a); + } + } else if ((*_status)[v] == MATCHED) { + extendOnArc(a); + } else if ((*_status)[v] == UNMATCHED) { + augmentOnArc(a); + return; + } + } + } + } + + void shrinkOnEdge(const Edge& e) { + Node nca = INVALID; + + { + std::set left_set, right_set; + + Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))]; + left_set.insert(left); + + Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))]; + right_set.insert(right); + + while (true) { + if ((*_matching)[left] == INVALID) break; + left = _graph.target((*_matching)[left]); + left = (*_blossom_rep)[_blossom_set-> + find(_graph.target((*_ear)[left]))]; + if (right_set.find(left) != right_set.end()) { + nca = left; + break; + } + left_set.insert(left); + + if ((*_matching)[right] == INVALID) break; + right = _graph.target((*_matching)[right]); + right = (*_blossom_rep)[_blossom_set-> + find(_graph.target((*_ear)[right]))]; + if (left_set.find(right) != left_set.end()) { + nca = right; + break; + } + right_set.insert(right); + } + + if (nca == INVALID) { + if ((*_matching)[left] == INVALID) { + nca = right; + while (left_set.find(nca) == left_set.end()) { + nca = _graph.target((*_matching)[nca]); + nca =(*_blossom_rep)[_blossom_set-> + find(_graph.target((*_ear)[nca]))]; + } + } else { + nca = left; + while (right_set.find(nca) == right_set.end()) { + nca = _graph.target((*_matching)[nca]); + nca = (*_blossom_rep)[_blossom_set-> + find(_graph.target((*_ear)[nca]))]; + } + } + } + } + + { + + Node node = _graph.u(e); + Arc arc = _graph.direct(e, true); + Node base = (*_blossom_rep)[_blossom_set->find(node)]; + + while (base != nca) { + (*_ear)[node] = arc; + + Node n = node; + while (n != base) { + n = _graph.target((*_matching)[n]); + Arc a = (*_ear)[n]; + n = _graph.target(a); + (*_ear)[n] = _graph.oppositeArc(a); + } + node = _graph.target((*_matching)[base]); + _tree_set->erase(base); + _tree_set->erase(node); + _blossom_set->insert(node, _blossom_set->find(base)); + (*_status)[node] = EVEN; + _node_queue[_last++] = node; + arc = _graph.oppositeArc((*_ear)[node]); + node = _graph.target((*_ear)[node]); + base = (*_blossom_rep)[_blossom_set->find(node)]; + _blossom_set->join(_graph.target(arc), base); + } + } + + (*_blossom_rep)[_blossom_set->find(nca)] = nca; + + { + + Node node = _graph.v(e); + Arc arc = _graph.direct(e, false); + Node base = (*_blossom_rep)[_blossom_set->find(node)]; + + while (base != nca) { + (*_ear)[node] = arc; + + Node n = node; + while (n != base) { + n = _graph.target((*_matching)[n]); + Arc a = (*_ear)[n]; + n = _graph.target(a); + (*_ear)[n] = _graph.oppositeArc(a); + } + node = _graph.target((*_matching)[base]); + _tree_set->erase(base); + _tree_set->erase(node); + _blossom_set->insert(node, _blossom_set->find(base)); + (*_status)[node] = EVEN; + _node_queue[_last++] = node; + arc = _graph.oppositeArc((*_ear)[node]); + node = _graph.target((*_ear)[node]); + base = (*_blossom_rep)[_blossom_set->find(node)]; + _blossom_set->join(_graph.target(arc), base); + } + } + + (*_blossom_rep)[_blossom_set->find(nca)] = nca; + } + + void extendOnArc(const Arc& a) { + Node base = _graph.source(a); + Node odd = _graph.target(a); + + (*_ear)[odd] = _graph.oppositeArc(a); + Node even = _graph.target((*_matching)[odd]); + (*_blossom_rep)[_blossom_set->insert(even)] = even; + (*_status)[odd] = ODD; + (*_status)[even] = EVEN; + int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]); + _tree_set->insert(odd, tree); + _tree_set->insert(even, tree); + _node_queue[_last++] = even; + + } + + void augmentOnArc(const Arc& a) { + Node even = _graph.source(a); + Node odd = _graph.target(a); + + int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]); + + (*_matching)[odd] = _graph.oppositeArc(a); + (*_status)[odd] = MATCHED; + + Arc arc = (*_matching)[even]; + (*_matching)[even] = a; + + while (arc != INVALID) { + odd = _graph.target(arc); + arc = (*_ear)[odd]; + even = _graph.target(arc); + (*_matching)[odd] = arc; + arc = (*_matching)[even]; + (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]); + } + + for (typename TreeSet::ItemIt it(*_tree_set, tree); + it != INVALID; ++it) { + if ((*_status)[it] == ODD) { + (*_status)[it] = MATCHED; + } else { + int blossom = _blossom_set->find(it); + for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom); + jt != INVALID; ++jt) { + (*_status)[jt] = MATCHED; + } + _blossom_set->eraseClass(blossom); + } + } + _tree_set->eraseClass(tree); + + } + + public: + + /// \brief Constructor + /// + /// Constructor. + MaxMatching(const Graph& graph) + : _graph(graph), _matching(0), _status(0), _ear(0), + _blossom_set_index(0), _blossom_set(0), _blossom_rep(0), + _tree_set_index(0), _tree_set(0) {} + + ~MaxMatching() { + destroyStructures(); + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to use the + /// \c run() member function.\n + /// If you need better control on the execution, you have to call + /// one of the functions \ref init(), \ref greedyInit() or + /// \ref matchingInit() first, then you can start the algorithm with + /// \ref startSparse() or \ref startDense(). + + ///@{ + + /// \brief Set the initial matching to the empty matching. + /// + /// This function sets the initial matching to the empty matching. + void init() { + createStructures(); + for(NodeIt n(_graph); n != INVALID; ++n) { + (*_matching)[n] = INVALID; + (*_status)[n] = UNMATCHED; + } + } + + /// \brief Find an initial matching in a greedy way. + /// + /// This function finds an initial matching in a greedy way. + void greedyInit() { + createStructures(); + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_matching)[n] = INVALID; + (*_status)[n] = UNMATCHED; + } + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] == INVALID) { + for (OutArcIt a(_graph, n); a != INVALID ; ++a) { + Node v = _graph.target(a); + if ((*_matching)[v] == INVALID && v != n) { + (*_matching)[n] = a; + (*_status)[n] = MATCHED; + (*_matching)[v] = _graph.oppositeArc(a); + (*_status)[v] = MATCHED; + break; + } + } + } + } + } + + + /// \brief Initialize the matching from a map. + /// + /// This function initializes the matching from a \c bool valued edge + /// map. This map should have the property that there are no two incident + /// edges with \c true value, i.e. it really contains a matching. + /// \return \c true if the map contains a matching. + template + bool matchingInit(const MatchingMap& matching) { + createStructures(); + + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_matching)[n] = INVALID; + (*_status)[n] = UNMATCHED; + } + for(EdgeIt e(_graph); e!=INVALID; ++e) { + if (matching[e]) { + + Node u = _graph.u(e); + if ((*_matching)[u] != INVALID) return false; + (*_matching)[u] = _graph.direct(e, true); + (*_status)[u] = MATCHED; + + Node v = _graph.v(e); + if ((*_matching)[v] != INVALID) return false; + (*_matching)[v] = _graph.direct(e, false); + (*_status)[v] = MATCHED; + } + } + return true; + } + + /// \brief Start Edmonds' algorithm + /// + /// This function runs the original Edmonds' algorithm. + /// + /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be + /// called before using this function. + void startSparse() { + for(NodeIt n(_graph); n != INVALID; ++n) { + if ((*_status)[n] == UNMATCHED) { + (*_blossom_rep)[_blossom_set->insert(n)] = n; + _tree_set->insert(n); + (*_status)[n] = EVEN; + processSparse(n); + } + } + } + + /// \brief Start Edmonds' algorithm with a heuristic improvement + /// for dense graphs + /// + /// This function runs Edmonds' algorithm with a heuristic of postponing + /// shrinks, therefore resulting in a faster algorithm for dense graphs. + /// + /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be + /// called before using this function. + void startDense() { + for(NodeIt n(_graph); n != INVALID; ++n) { + if ((*_status)[n] == UNMATCHED) { + (*_blossom_rep)[_blossom_set->insert(n)] = n; + _tree_set->insert(n); + (*_status)[n] = EVEN; + processDense(n); + } + } + } + + + /// \brief Run Edmonds' algorithm + /// + /// This function runs Edmonds' algorithm. An additional heuristic of + /// postponing shrinks is used for relatively dense graphs + /// (for which m>=2*n holds). + void run() { + if (countEdges(_graph) < 2 * countNodes(_graph)) { + greedyInit(); + startSparse(); + } else { + init(); + startDense(); + } + } + + /// @} + + /// \name Primal Solution + /// Functions to get the primal solution, i.e. the maximum matching. + + /// @{ + + /// \brief Return the size (cardinality) of the matching. + /// + /// This function returns the size (cardinality) of the current matching. + /// After run() it returns the size of the maximum matching in the graph. + int matchingSize() const { + int size = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + ++size; + } + } + return size / 2; + } + + /// \brief Return \c true if the given edge is in the matching. + /// + /// This function returns \c true if the given edge is in the current + /// matching. + bool matching(const Edge& edge) const { + return edge == (*_matching)[_graph.u(edge)]; + } + + /// \brief Return the matching arc (or edge) incident to the given node. + /// + /// This function returns the matching arc (or edge) incident to the + /// given node in the current matching or \c INVALID if the node is + /// not covered by the matching. + Arc matching(const Node& n) const { + return (*_matching)[n]; + } + + /// \brief Return a const reference to the matching map. + /// + /// This function returns a const reference to a node map that stores + /// the matching arc (or edge) incident to each node. + const MatchingMap& matchingMap() const { + return *_matching; + } + + /// \brief Return the mate of the given node. + /// + /// This function returns the mate of the given node in the current + /// matching or \c INVALID if the node is not covered by the matching. + Node mate(const Node& n) const { + return (*_matching)[n] != INVALID ? + _graph.target((*_matching)[n]) : INVALID; + } + + /// @} + + /// \name Dual Solution + /// Functions to get the dual solution, i.e. the Gallai-Edmonds + /// decomposition. + + /// @{ + + /// \brief Return the status of the given node in the Edmonds-Gallai + /// decomposition. + /// + /// This function returns the \ref Status "status" of the given node + /// in the Edmonds-Gallai decomposition. + Status status(const Node& n) const { + return (*_status)[n]; + } + + /// \brief Return a const reference to the status map, which stores + /// the Edmonds-Gallai decomposition. + /// + /// This function returns a const reference to a node map that stores the + /// \ref Status "status" of each node in the Edmonds-Gallai decomposition. + const StatusMap& statusMap() const { + return *_status; + } + + /// \brief Return \c true if the given node is in the barrier. + /// + /// This function returns \c true if the given node is in the barrier. + bool barrier(const Node& n) const { + return (*_status)[n] == ODD; + } + + /// @} + + }; + + /// \ingroup matching + /// + /// \brief Weighted matching in general graphs + /// + /// This class provides an efficient implementation of Edmond's + /// maximum weighted matching algorithm. The implementation is based + /// on extensive use of priority queues and provides + /// \f$O(nm\log n)\f$ time complexity. + /// + /// The maximum weighted matching problem is to find a subset of the + /// edges in an undirected graph with maximum overall weight for which + /// each node has at most one incident edge. + /// It can be formulated with the following linear program. + /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f] + /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2} + \quad \forall B\in\mathcal{O}\f] */ + /// \f[x_e \ge 0\quad \forall e\in E\f] + /// \f[\max \sum_{e\in E}x_ew_e\f] + /// where \f$\delta(X)\f$ is the set of edges incident to a node in + /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in + /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality + /// subsets of the nodes. + /// + /// The algorithm calculates an optimal matching and a proof of the + /// optimality. The solution of the dual problem can be used to check + /// the result of the algorithm. The dual linear problem is the + /// following. + /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)} + z_B \ge w_{uv} \quad \forall uv\in E\f] */ + /// \f[y_u \ge 0 \quad \forall u \in V\f] + /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f] + /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}} + \frac{\vert B \vert - 1}{2}z_B\f] */ + /// + /// The algorithm can be executed with the run() function. + /// After it the matching (the primal solution) and the dual solution + /// can be obtained using the query functions and the + /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, + /// which is able to iterate on the nodes of a blossom. + /// If the value type is integer, then the dual solution is multiplied + /// by \ref MaxWeightedMatching::dualScale "4". + /// + /// \tparam GR The undirected graph type the algorithm runs on. + /// \tparam WM The type edge weight map. The default type is + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap". +#ifdef DOXYGEN + template +#else + template > +#endif + class MaxWeightedMatching { + public: + + /// The graph type of the algorithm + typedef GR Graph; + /// The type of the edge weight map + typedef WM WeightMap; + /// The value type of the edge weights + typedef typename WeightMap::Value Value; + + /// The type of the matching map + typedef typename Graph::template NodeMap + MatchingMap; + + /// \brief Scaling factor for dual solution + /// + /// Scaling factor for dual solution. It is equal to 4 or 1 + /// according to the value type. + static const int dualScale = + std::numeric_limits::is_integer ? 4 : 1; + + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + typedef typename Graph::template NodeMap NodePotential; + typedef std::vector BlossomNodeList; + + struct BlossomVariable { + int begin, end; + Value value; + + BlossomVariable(int _begin, int _end, Value _value) + : begin(_begin), end(_end), value(_value) {} + + }; + + typedef std::vector BlossomPotential; + + const Graph& _graph; + const WeightMap& _weight; + + MatchingMap* _matching; + + NodePotential* _node_potential; + + BlossomPotential _blossom_potential; + BlossomNodeList _blossom_node_list; + + int _node_num; + int _blossom_num; + + typedef RangeMap IntIntMap; + + enum Status { + EVEN = -1, MATCHED = 0, ODD = 1 + }; + + typedef HeapUnionFind BlossomSet; + struct BlossomData { + int tree; + Status status; + Arc pred, next; + Value pot, offset; + Node base; + }; + + IntNodeMap *_blossom_index; + BlossomSet *_blossom_set; + RangeMap* _blossom_data; + + IntNodeMap *_node_index; + IntArcMap *_node_heap_index; + + struct NodeData { + + NodeData(IntArcMap& node_heap_index) + : heap(node_heap_index) {} + + int blossom; + Value pot; + BinHeap heap; + std::map heap_index; + + int tree; + }; + + RangeMap* _node_data; + + typedef ExtendFindEnum TreeSet; + + IntIntMap *_tree_set_index; + TreeSet *_tree_set; + + IntNodeMap *_delta1_index; + BinHeap *_delta1; + + IntIntMap *_delta2_index; + BinHeap *_delta2; + + IntEdgeMap *_delta3_index; + BinHeap *_delta3; + + IntIntMap *_delta4_index; + BinHeap *_delta4; + + Value _delta_sum; + int _unmatched; + + typedef MaxWeightedFractionalMatching FractionalMatching; + FractionalMatching *_fractional; + + void createStructures() { + _node_num = countNodes(_graph); + _blossom_num = _node_num * 3 / 2; + + if (!_matching) { + _matching = new MatchingMap(_graph); + } + + if (!_node_potential) { + _node_potential = new NodePotential(_graph); + } + + if (!_blossom_set) { + _blossom_index = new IntNodeMap(_graph); + _blossom_set = new BlossomSet(*_blossom_index); + _blossom_data = new RangeMap(_blossom_num); + } else if (_blossom_data->size() != _blossom_num) { + delete _blossom_data; + _blossom_data = new RangeMap(_blossom_num); + } + + if (!_node_index) { + _node_index = new IntNodeMap(_graph); + _node_heap_index = new IntArcMap(_graph); + _node_data = new RangeMap(_node_num, + NodeData(*_node_heap_index)); + } else { + delete _node_data; + _node_data = new RangeMap(_node_num, + NodeData(*_node_heap_index)); + } + + if (!_tree_set) { + _tree_set_index = new IntIntMap(_blossom_num); + _tree_set = new TreeSet(*_tree_set_index); + } else { + _tree_set_index->resize(_blossom_num); + } + + if (!_delta1) { + _delta1_index = new IntNodeMap(_graph); + _delta1 = new BinHeap(*_delta1_index); + } + + if (!_delta2) { + _delta2_index = new IntIntMap(_blossom_num); + _delta2 = new BinHeap(*_delta2_index); + } else { + _delta2_index->resize(_blossom_num); + } + + if (!_delta3) { + _delta3_index = new IntEdgeMap(_graph); + _delta3 = new BinHeap(*_delta3_index); + } + + if (!_delta4) { + _delta4_index = new IntIntMap(_blossom_num); + _delta4 = new BinHeap(*_delta4_index); + } else { + _delta4_index->resize(_blossom_num); + } + } + + void destroyStructures() { + if (_matching) { + delete _matching; + } + if (_node_potential) { + delete _node_potential; + } + if (_blossom_set) { + delete _blossom_index; + delete _blossom_set; + delete _blossom_data; + } + + if (_node_index) { + delete _node_index; + delete _node_heap_index; + delete _node_data; + } + + if (_tree_set) { + delete _tree_set_index; + delete _tree_set; + } + if (_delta1) { + delete _delta1_index; + delete _delta1; + } + if (_delta2) { + delete _delta2_index; + delete _delta2; + } + if (_delta3) { + delete _delta3_index; + delete _delta3; + } + if (_delta4) { + delete _delta4_index; + delete _delta4; + } + } + + void matchedToEven(int blossom, int tree) { + if (_delta2->state(blossom) == _delta2->IN_HEAP) { + _delta2->erase(blossom); + } + + if (!_blossom_set->trivial(blossom)) { + (*_blossom_data)[blossom].pot -= + 2 * (_delta_sum - (*_blossom_data)[blossom].offset); + } + + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom); + n != INVALID; ++n) { + + _blossom_set->increase(n, std::numeric_limits::max()); + int ni = (*_node_index)[n]; + + (*_node_data)[ni].heap.clear(); + (*_node_data)[ni].heap_index.clear(); + + (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset; + + _delta1->push(n, (*_node_data)[ni].pot); + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.source(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if ((*_blossom_data)[vb].status == EVEN) { + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) { + _delta3->push(e, rw / 2); + } + } else { + typename std::map::iterator it = + (*_node_data)[vi].heap_index.find(tree); + + if (it != (*_node_data)[vi].heap_index.end()) { + if ((*_node_data)[vi].heap[it->second] > rw) { + (*_node_data)[vi].heap.replace(it->second, e); + (*_node_data)[vi].heap.decrease(e, rw); + it->second = e; + } + } else { + (*_node_data)[vi].heap.push(e, rw); + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e)); + } + + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) { + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio()); + + if ((*_blossom_data)[vb].status == MATCHED) { + if (_delta2->state(vb) != _delta2->IN_HEAP) { + _delta2->push(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset) { + _delta2->decrease(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } + } + } + } + } + } + (*_blossom_data)[blossom].offset = 0; + } + + void matchedToOdd(int blossom) { + if (_delta2->state(blossom) == _delta2->IN_HEAP) { + _delta2->erase(blossom); + } + (*_blossom_data)[blossom].offset += _delta_sum; + if (!_blossom_set->trivial(blossom)) { + _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 + + (*_blossom_data)[blossom].offset); + } + } + + void evenToMatched(int blossom, int tree) { + if (!_blossom_set->trivial(blossom)) { + (*_blossom_data)[blossom].pot += 2 * _delta_sum; + } + + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom); + n != INVALID; ++n) { + int ni = (*_node_index)[n]; + (*_node_data)[ni].pot -= _delta_sum; + + _delta1->erase(n); + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.source(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if (vb == blossom) { + if (_delta3->state(e) == _delta3->IN_HEAP) { + _delta3->erase(e); + } + } else if ((*_blossom_data)[vb].status == EVEN) { + + if (_delta3->state(e) == _delta3->IN_HEAP) { + _delta3->erase(e); + } + + int vt = _tree_set->find(vb); + + if (vt != tree) { + + Arc r = _graph.oppositeArc(e); + + typename std::map::iterator it = + (*_node_data)[ni].heap_index.find(vt); + + if (it != (*_node_data)[ni].heap_index.end()) { + if ((*_node_data)[ni].heap[it->second] > rw) { + (*_node_data)[ni].heap.replace(it->second, r); + (*_node_data)[ni].heap.decrease(r, rw); + it->second = r; + } + } else { + (*_node_data)[ni].heap.push(r, rw); + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r)); + } + + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) { + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio()); + + if (_delta2->state(blossom) != _delta2->IN_HEAP) { + _delta2->push(blossom, _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset); + } else if ((*_delta2)[blossom] > + _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset){ + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset); + } + } + } + } else { + + typename std::map::iterator it = + (*_node_data)[vi].heap_index.find(tree); + + if (it != (*_node_data)[vi].heap_index.end()) { + (*_node_data)[vi].heap.erase(it->second); + (*_node_data)[vi].heap_index.erase(it); + if ((*_node_data)[vi].heap.empty()) { + _blossom_set->increase(v, std::numeric_limits::max()); + } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) { + _blossom_set->increase(v, (*_node_data)[vi].heap.prio()); + } + + if ((*_blossom_data)[vb].status == MATCHED) { + if (_blossom_set->classPrio(vb) == + std::numeric_limits::max()) { + _delta2->erase(vb); + } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset) { + _delta2->increase(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } + } + } + } + } + } + } + + void oddToMatched(int blossom) { + (*_blossom_data)[blossom].offset -= _delta_sum; + + if (_blossom_set->classPrio(blossom) != + std::numeric_limits::max()) { + _delta2->push(blossom, _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset); + } + + if (!_blossom_set->trivial(blossom)) { + _delta4->erase(blossom); + } + } + + void oddToEven(int blossom, int tree) { + if (!_blossom_set->trivial(blossom)) { + _delta4->erase(blossom); + (*_blossom_data)[blossom].pot -= + 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset); + } + + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom); + n != INVALID; ++n) { + int ni = (*_node_index)[n]; + + _blossom_set->increase(n, std::numeric_limits::max()); + + (*_node_data)[ni].heap.clear(); + (*_node_data)[ni].heap_index.clear(); + (*_node_data)[ni].pot += + 2 * _delta_sum - (*_blossom_data)[blossom].offset; + + _delta1->push(n, (*_node_data)[ni].pot); + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.source(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if ((*_blossom_data)[vb].status == EVEN) { + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) { + _delta3->push(e, rw / 2); + } + } else { + + typename std::map::iterator it = + (*_node_data)[vi].heap_index.find(tree); + + if (it != (*_node_data)[vi].heap_index.end()) { + if ((*_node_data)[vi].heap[it->second] > rw) { + (*_node_data)[vi].heap.replace(it->second, e); + (*_node_data)[vi].heap.decrease(e, rw); + it->second = e; + } + } else { + (*_node_data)[vi].heap.push(e, rw); + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e)); + } + + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) { + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio()); + + if ((*_blossom_data)[vb].status == MATCHED) { + if (_delta2->state(vb) != _delta2->IN_HEAP) { + _delta2->push(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset) { + _delta2->decrease(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } + } + } + } + } + } + (*_blossom_data)[blossom].offset = 0; + } + + void alternatePath(int even, int tree) { + int odd; + + evenToMatched(even, tree); + (*_blossom_data)[even].status = MATCHED; + + while ((*_blossom_data)[even].pred != INVALID) { + odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred)); + (*_blossom_data)[odd].status = MATCHED; + oddToMatched(odd); + (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred; + + even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred)); + (*_blossom_data)[even].status = MATCHED; + evenToMatched(even, tree); + (*_blossom_data)[even].next = + _graph.oppositeArc((*_blossom_data)[odd].pred); + } + + } + + void destroyTree(int tree) { + for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) { + if ((*_blossom_data)[b].status == EVEN) { + (*_blossom_data)[b].status = MATCHED; + evenToMatched(b, tree); + } else if ((*_blossom_data)[b].status == ODD) { + (*_blossom_data)[b].status = MATCHED; + oddToMatched(b); + } + } + _tree_set->eraseClass(tree); + } + + + void unmatchNode(const Node& node) { + int blossom = _blossom_set->find(node); + int tree = _tree_set->find(blossom); + + alternatePath(blossom, tree); + destroyTree(tree); + + (*_blossom_data)[blossom].base = node; + (*_blossom_data)[blossom].next = INVALID; + } + + void augmentOnEdge(const Edge& edge) { + + int left = _blossom_set->find(_graph.u(edge)); + int right = _blossom_set->find(_graph.v(edge)); + + int left_tree = _tree_set->find(left); + alternatePath(left, left_tree); + destroyTree(left_tree); + + int right_tree = _tree_set->find(right); + alternatePath(right, right_tree); + destroyTree(right_tree); + + (*_blossom_data)[left].next = _graph.direct(edge, true); + (*_blossom_data)[right].next = _graph.direct(edge, false); + } + + void augmentOnArc(const Arc& arc) { + + int left = _blossom_set->find(_graph.source(arc)); + int right = _blossom_set->find(_graph.target(arc)); + + (*_blossom_data)[left].status = MATCHED; + + int right_tree = _tree_set->find(right); + alternatePath(right, right_tree); + destroyTree(right_tree); + + (*_blossom_data)[left].next = arc; + (*_blossom_data)[right].next = _graph.oppositeArc(arc); + } + + void extendOnArc(const Arc& arc) { + int base = _blossom_set->find(_graph.target(arc)); + int tree = _tree_set->find(base); + + int odd = _blossom_set->find(_graph.source(arc)); + _tree_set->insert(odd, tree); + (*_blossom_data)[odd].status = ODD; + matchedToOdd(odd); + (*_blossom_data)[odd].pred = arc; + + int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next)); + (*_blossom_data)[even].pred = (*_blossom_data)[even].next; + _tree_set->insert(even, tree); + (*_blossom_data)[even].status = EVEN; + matchedToEven(even, tree); + } + + void shrinkOnEdge(const Edge& edge, int tree) { + int nca = -1; + std::vector left_path, right_path; + + { + std::set left_set, right_set; + int left = _blossom_set->find(_graph.u(edge)); + left_path.push_back(left); + left_set.insert(left); + + int right = _blossom_set->find(_graph.v(edge)); + right_path.push_back(right); + right_set.insert(right); + + while (true) { + + if ((*_blossom_data)[left].pred == INVALID) break; + + left = + _blossom_set->find(_graph.target((*_blossom_data)[left].pred)); + left_path.push_back(left); + left = + _blossom_set->find(_graph.target((*_blossom_data)[left].pred)); + left_path.push_back(left); + + left_set.insert(left); + + if (right_set.find(left) != right_set.end()) { + nca = left; + break; + } + + if ((*_blossom_data)[right].pred == INVALID) break; + + right = + _blossom_set->find(_graph.target((*_blossom_data)[right].pred)); + right_path.push_back(right); + right = + _blossom_set->find(_graph.target((*_blossom_data)[right].pred)); + right_path.push_back(right); + + right_set.insert(right); + + if (left_set.find(right) != left_set.end()) { + nca = right; + break; + } + + } + + if (nca == -1) { + if ((*_blossom_data)[left].pred == INVALID) { + nca = right; + while (left_set.find(nca) == left_set.end()) { + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + right_path.push_back(nca); + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + right_path.push_back(nca); + } + } else { + nca = left; + while (right_set.find(nca) == right_set.end()) { + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + left_path.push_back(nca); + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + left_path.push_back(nca); + } + } + } + } + + std::vector subblossoms; + Arc prev; + + prev = _graph.direct(edge, true); + for (int i = 0; left_path[i] != nca; i += 2) { + subblossoms.push_back(left_path[i]); + (*_blossom_data)[left_path[i]].next = prev; + _tree_set->erase(left_path[i]); + + subblossoms.push_back(left_path[i + 1]); + (*_blossom_data)[left_path[i + 1]].status = EVEN; + oddToEven(left_path[i + 1], tree); + _tree_set->erase(left_path[i + 1]); + prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred); + } + + int k = 0; + while (right_path[k] != nca) ++k; + + subblossoms.push_back(nca); + (*_blossom_data)[nca].next = prev; + + for (int i = k - 2; i >= 0; i -= 2) { + subblossoms.push_back(right_path[i + 1]); + (*_blossom_data)[right_path[i + 1]].status = EVEN; + oddToEven(right_path[i + 1], tree); + _tree_set->erase(right_path[i + 1]); + + (*_blossom_data)[right_path[i + 1]].next = + (*_blossom_data)[right_path[i + 1]].pred; + + subblossoms.push_back(right_path[i]); + _tree_set->erase(right_path[i]); + } + + int surface = + _blossom_set->join(subblossoms.begin(), subblossoms.end()); + + for (int i = 0; i < int(subblossoms.size()); ++i) { + if (!_blossom_set->trivial(subblossoms[i])) { + (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum; + } + (*_blossom_data)[subblossoms[i]].status = MATCHED; + } + + (*_blossom_data)[surface].pot = -2 * _delta_sum; + (*_blossom_data)[surface].offset = 0; + (*_blossom_data)[surface].status = EVEN; + (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred; + (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred; + + _tree_set->insert(surface, tree); + _tree_set->erase(nca); + } + + void splitBlossom(int blossom) { + Arc next = (*_blossom_data)[blossom].next; + Arc pred = (*_blossom_data)[blossom].pred; + + int tree = _tree_set->find(blossom); + + (*_blossom_data)[blossom].status = MATCHED; + oddToMatched(blossom); + if (_delta2->state(blossom) == _delta2->IN_HEAP) { + _delta2->erase(blossom); + } + + std::vector subblossoms; + _blossom_set->split(blossom, std::back_inserter(subblossoms)); + + Value offset = (*_blossom_data)[blossom].offset; + int b = _blossom_set->find(_graph.source(pred)); + int d = _blossom_set->find(_graph.source(next)); + + int ib = -1, id = -1; + for (int i = 0; i < int(subblossoms.size()); ++i) { + if (subblossoms[i] == b) ib = i; + if (subblossoms[i] == d) id = i; + + (*_blossom_data)[subblossoms[i]].offset = offset; + if (!_blossom_set->trivial(subblossoms[i])) { + (*_blossom_data)[subblossoms[i]].pot -= 2 * offset; + } + if (_blossom_set->classPrio(subblossoms[i]) != + std::numeric_limits::max()) { + _delta2->push(subblossoms[i], + _blossom_set->classPrio(subblossoms[i]) - + (*_blossom_data)[subblossoms[i]].offset); + } + } + + if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) { + for (int i = (id + 1) % subblossoms.size(); + i != ib; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + (*_blossom_data)[sb].next = + _graph.oppositeArc((*_blossom_data)[tb].next); + } + + for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + int ub = subblossoms[(i + 2) % subblossoms.size()]; + + (*_blossom_data)[sb].status = ODD; + matchedToOdd(sb); + _tree_set->insert(sb, tree); + (*_blossom_data)[sb].pred = pred; + (*_blossom_data)[sb].next = + _graph.oppositeArc((*_blossom_data)[tb].next); + + pred = (*_blossom_data)[ub].next; + + (*_blossom_data)[tb].status = EVEN; + matchedToEven(tb, tree); + _tree_set->insert(tb, tree); + (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next; + } + + (*_blossom_data)[subblossoms[id]].status = ODD; + matchedToOdd(subblossoms[id]); + _tree_set->insert(subblossoms[id], tree); + (*_blossom_data)[subblossoms[id]].next = next; + (*_blossom_data)[subblossoms[id]].pred = pred; + + } else { + + for (int i = (ib + 1) % subblossoms.size(); + i != id; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + (*_blossom_data)[sb].next = + _graph.oppositeArc((*_blossom_data)[tb].next); + } + + for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + int ub = subblossoms[(i + 2) % subblossoms.size()]; + + (*_blossom_data)[sb].status = ODD; + matchedToOdd(sb); + _tree_set->insert(sb, tree); + (*_blossom_data)[sb].next = next; + (*_blossom_data)[sb].pred = + _graph.oppositeArc((*_blossom_data)[tb].next); + + (*_blossom_data)[tb].status = EVEN; + matchedToEven(tb, tree); + _tree_set->insert(tb, tree); + (*_blossom_data)[tb].pred = + (*_blossom_data)[tb].next = + _graph.oppositeArc((*_blossom_data)[ub].next); + next = (*_blossom_data)[ub].next; + } + + (*_blossom_data)[subblossoms[ib]].status = ODD; + matchedToOdd(subblossoms[ib]); + _tree_set->insert(subblossoms[ib], tree); + (*_blossom_data)[subblossoms[ib]].next = next; + (*_blossom_data)[subblossoms[ib]].pred = pred; + } + _tree_set->erase(blossom); + } + + void extractBlossom(int blossom, const Node& base, const Arc& matching) { + if (_blossom_set->trivial(blossom)) { + int bi = (*_node_index)[base]; + Value pot = (*_node_data)[bi].pot; + + (*_matching)[base] = matching; + _blossom_node_list.push_back(base); + (*_node_potential)[base] = pot; + } else { + + Value pot = (*_blossom_data)[blossom].pot; + int bn = _blossom_node_list.size(); + + std::vector subblossoms; + _blossom_set->split(blossom, std::back_inserter(subblossoms)); + int b = _blossom_set->find(base); + int ib = -1; + for (int i = 0; i < int(subblossoms.size()); ++i) { + if (subblossoms[i] == b) { ib = i; break; } + } + + for (int i = 1; i < int(subblossoms.size()); i += 2) { + int sb = subblossoms[(ib + i) % subblossoms.size()]; + int tb = subblossoms[(ib + i + 1) % subblossoms.size()]; + + Arc m = (*_blossom_data)[tb].next; + extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m)); + extractBlossom(tb, _graph.source(m), m); + } + extractBlossom(subblossoms[ib], base, matching); + + int en = _blossom_node_list.size(); + + _blossom_potential.push_back(BlossomVariable(bn, en, pot)); + } + } + + void extractMatching() { + std::vector blossoms; + for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) { + blossoms.push_back(c); + } + + for (int i = 0; i < int(blossoms.size()); ++i) { + if ((*_blossom_data)[blossoms[i]].next != INVALID) { + + Value offset = (*_blossom_data)[blossoms[i]].offset; + (*_blossom_data)[blossoms[i]].pot += 2 * offset; + for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]); + n != INVALID; ++n) { + (*_node_data)[(*_node_index)[n]].pot -= offset; + } + + Arc matching = (*_blossom_data)[blossoms[i]].next; + Node base = _graph.source(matching); + extractBlossom(blossoms[i], base, matching); + } else { + Node base = (*_blossom_data)[blossoms[i]].base; + extractBlossom(blossoms[i], base, INVALID); + } + } + } + + public: + + /// \brief Constructor + /// + /// Constructor. + MaxWeightedMatching(const Graph& graph, const WeightMap& weight) + : _graph(graph), _weight(weight), _matching(0), + _node_potential(0), _blossom_potential(), _blossom_node_list(), + _node_num(0), _blossom_num(0), + + _blossom_index(0), _blossom_set(0), _blossom_data(0), + _node_index(0), _node_heap_index(0), _node_data(0), + _tree_set_index(0), _tree_set(0), + + _delta1_index(0), _delta1(0), + _delta2_index(0), _delta2(0), + _delta3_index(0), _delta3(0), + _delta4_index(0), _delta4(0), + + _delta_sum(), _unmatched(0), + + _fractional(0) + {} + + ~MaxWeightedMatching() { + destroyStructures(); + if (_fractional) { + delete _fractional; + } + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to use the + /// \ref run() member function. + + ///@{ + + /// \brief Initialize the algorithm + /// + /// This function initializes the algorithm. + void init() { + createStructures(); + + _blossom_node_list.clear(); + _blossom_potential.clear(); + + for (ArcIt e(_graph); e != INVALID; ++e) { + (*_node_heap_index)[e] = BinHeap::PRE_HEAP; + } + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_delta1_index)[n] = _delta1->PRE_HEAP; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + (*_delta3_index)[e] = _delta3->PRE_HEAP; + } + for (int i = 0; i < _blossom_num; ++i) { + (*_delta2_index)[i] = _delta2->PRE_HEAP; + (*_delta4_index)[i] = _delta4->PRE_HEAP; + } + + _unmatched = _node_num; + + _delta1->clear(); + _delta2->clear(); + _delta3->clear(); + _delta4->clear(); + _blossom_set->clear(); + _tree_set->clear(); + + int index = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + Value max = 0; + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + if (_graph.target(e) == n) continue; + if ((dualScale * _weight[e]) / 2 > max) { + max = (dualScale * _weight[e]) / 2; + } + } + (*_node_index)[n] = index; + (*_node_data)[index].heap_index.clear(); + (*_node_data)[index].heap.clear(); + (*_node_data)[index].pot = max; + _delta1->push(n, max); + int blossom = + _blossom_set->insert(n, std::numeric_limits::max()); + + _tree_set->insert(blossom); + + (*_blossom_data)[blossom].status = EVEN; + (*_blossom_data)[blossom].pred = INVALID; + (*_blossom_data)[blossom].next = INVALID; + (*_blossom_data)[blossom].pot = 0; + (*_blossom_data)[blossom].offset = 0; + ++index; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + int si = (*_node_index)[_graph.u(e)]; + int ti = (*_node_index)[_graph.v(e)]; + if (_graph.u(e) != _graph.v(e)) { + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot - + dualScale * _weight[e]) / 2); + } + } + } + + /// \brief Initialize the algorithm with fractional matching + /// + /// This function initializes the algorithm with a fractional + /// matching. This initialization is also called jumpstart heuristic. + void fractionalInit() { + createStructures(); + + _blossom_node_list.clear(); + _blossom_potential.clear(); + + if (_fractional == 0) { + _fractional = new FractionalMatching(_graph, _weight, false); + } + _fractional->run(); + + for (ArcIt e(_graph); e != INVALID; ++e) { + (*_node_heap_index)[e] = BinHeap::PRE_HEAP; + } + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_delta1_index)[n] = _delta1->PRE_HEAP; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + (*_delta3_index)[e] = _delta3->PRE_HEAP; + } + for (int i = 0; i < _blossom_num; ++i) { + (*_delta2_index)[i] = _delta2->PRE_HEAP; + (*_delta4_index)[i] = _delta4->PRE_HEAP; + } + + _unmatched = 0; + + _delta1->clear(); + _delta2->clear(); + _delta3->clear(); + _delta4->clear(); + _blossom_set->clear(); + _tree_set->clear(); + + int index = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + Value pot = _fractional->nodeValue(n); + (*_node_index)[n] = index; + (*_node_data)[index].pot = pot; + (*_node_data)[index].heap_index.clear(); + (*_node_data)[index].heap.clear(); + int blossom = + _blossom_set->insert(n, std::numeric_limits::max()); + + (*_blossom_data)[blossom].status = MATCHED; + (*_blossom_data)[blossom].pred = INVALID; + (*_blossom_data)[blossom].next = _fractional->matching(n); + if (_fractional->matching(n) == INVALID) { + (*_blossom_data)[blossom].base = n; + } + (*_blossom_data)[blossom].pot = 0; + (*_blossom_data)[blossom].offset = 0; + ++index; + } + + typename Graph::template NodeMap processed(_graph, false); + for (NodeIt n(_graph); n != INVALID; ++n) { + if (processed[n]) continue; + processed[n] = true; + if (_fractional->matching(n) == INVALID) continue; + int num = 1; + Node v = _graph.target(_fractional->matching(n)); + while (n != v) { + processed[v] = true; + v = _graph.target(_fractional->matching(v)); + ++num; + } + + if (num % 2 == 1) { + std::vector subblossoms(num); + + subblossoms[--num] = _blossom_set->find(n); + _delta1->push(n, _fractional->nodeValue(n)); + v = _graph.target(_fractional->matching(n)); + while (n != v) { + subblossoms[--num] = _blossom_set->find(v); + _delta1->push(v, _fractional->nodeValue(v)); + v = _graph.target(_fractional->matching(v)); + } + + int surface = + _blossom_set->join(subblossoms.begin(), subblossoms.end()); + (*_blossom_data)[surface].status = EVEN; + (*_blossom_data)[surface].pred = INVALID; + (*_blossom_data)[surface].next = INVALID; + (*_blossom_data)[surface].pot = 0; + (*_blossom_data)[surface].offset = 0; + + _tree_set->insert(surface); + ++_unmatched; + } + } + + for (EdgeIt e(_graph); e != INVALID; ++e) { + int si = (*_node_index)[_graph.u(e)]; + int sb = _blossom_set->find(_graph.u(e)); + int ti = (*_node_index)[_graph.v(e)]; + int tb = _blossom_set->find(_graph.v(e)); + if ((*_blossom_data)[sb].status == EVEN && + (*_blossom_data)[tb].status == EVEN && sb != tb) { + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot - + dualScale * _weight[e]) / 2); + } + } + + for (NodeIt n(_graph); n != INVALID; ++n) { + int nb = _blossom_set->find(n); + if ((*_blossom_data)[nb].status != MATCHED) continue; + int ni = (*_node_index)[n]; + + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.target(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if ((*_blossom_data)[vb].status == EVEN) { + + int vt = _tree_set->find(vb); + + typename std::map::iterator it = + (*_node_data)[ni].heap_index.find(vt); + + if (it != (*_node_data)[ni].heap_index.end()) { + if ((*_node_data)[ni].heap[it->second] > rw) { + (*_node_data)[ni].heap.replace(it->second, e); + (*_node_data)[ni].heap.decrease(e, rw); + it->second = e; + } + } else { + (*_node_data)[ni].heap.push(e, rw); + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e)); + } + } + } + + if (!(*_node_data)[ni].heap.empty()) { + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio()); + _delta2->push(nb, _blossom_set->classPrio(nb)); + } + } + } + + /// \brief Start the algorithm + /// + /// This function starts the algorithm. + /// + /// \pre \ref init() or \ref fractionalInit() must be called + /// before using this function. + void start() { + enum OpType { + D1, D2, D3, D4 + }; + + while (_unmatched > 0) { + Value d1 = !_delta1->empty() ? + _delta1->prio() : std::numeric_limits::max(); + + Value d2 = !_delta2->empty() ? + _delta2->prio() : std::numeric_limits::max(); + + Value d3 = !_delta3->empty() ? + _delta3->prio() : std::numeric_limits::max(); + + Value d4 = !_delta4->empty() ? + _delta4->prio() : std::numeric_limits::max(); + + _delta_sum = d3; OpType ot = D3; + if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; } + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; } + if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; } + + switch (ot) { + case D1: + { + Node n = _delta1->top(); + unmatchNode(n); + --_unmatched; + } + break; + case D2: + { + int blossom = _delta2->top(); + Node n = _blossom_set->classTop(blossom); + Arc a = (*_node_data)[(*_node_index)[n]].heap.top(); + if ((*_blossom_data)[blossom].next == INVALID) { + augmentOnArc(a); + --_unmatched; + } else { + extendOnArc(a); + } + } + break; + case D3: + { + Edge e = _delta3->top(); + + int left_blossom = _blossom_set->find(_graph.u(e)); + int right_blossom = _blossom_set->find(_graph.v(e)); + + if (left_blossom == right_blossom) { + _delta3->pop(); + } else { + int left_tree = _tree_set->find(left_blossom); + int right_tree = _tree_set->find(right_blossom); + + if (left_tree == right_tree) { + shrinkOnEdge(e, left_tree); + } else { + augmentOnEdge(e); + _unmatched -= 2; + } + } + } break; + case D4: + splitBlossom(_delta4->top()); + break; + } + } + extractMatching(); + } + + /// \brief Run the algorithm. + /// + /// This method runs the \c %MaxWeightedMatching algorithm. + /// + /// \note mwm.run() is just a shortcut of the following code. + /// \code + /// mwm.fractionalInit(); + /// mwm.start(); + /// \endcode + void run() { + fractionalInit(); + start(); + } + + /// @} + + /// \name Primal Solution + /// Functions to get the primal solution, i.e. the maximum weighted + /// matching.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the weight of the matching. + /// + /// This function returns the weight of the found matching. + /// + /// \pre Either run() or start() must be called before using this function. + Value matchingWeight() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + sum += _weight[(*_matching)[n]]; + } + } + return sum / 2; + } + + /// \brief Return the size (cardinality) of the matching. + /// + /// This function returns the size (cardinality) of the found matching. + /// + /// \pre Either run() or start() must be called before using this function. + int matchingSize() const { + int num = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + ++num; + } + } + return num /= 2; + } + + /// \brief Return \c true if the given edge is in the matching. + /// + /// This function returns \c true if the given edge is in the found + /// matching. + /// + /// \pre Either run() or start() must be called before using this function. + bool matching(const Edge& edge) const { + return edge == (*_matching)[_graph.u(edge)]; + } + + /// \brief Return the matching arc (or edge) incident to the given node. + /// + /// This function returns the matching arc (or edge) incident to the + /// given node in the found matching or \c INVALID if the node is + /// not covered by the matching. + /// + /// \pre Either run() or start() must be called before using this function. + Arc matching(const Node& node) const { + return (*_matching)[node]; + } + + /// \brief Return a const reference to the matching map. + /// + /// This function returns a const reference to a node map that stores + /// the matching arc (or edge) incident to each node. + const MatchingMap& matchingMap() const { + return *_matching; + } + + /// \brief Return the mate of the given node. + /// + /// This function returns the mate of the given node in the found + /// matching or \c INVALID if the node is not covered by the matching. + /// + /// \pre Either run() or start() must be called before using this function. + Node mate(const Node& node) const { + return (*_matching)[node] != INVALID ? + _graph.target((*_matching)[node]) : INVALID; + } + + /// @} + + /// \name Dual Solution + /// Functions to get the dual solution.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the value of the dual solution. + /// + /// This function returns the value of the dual solution. + /// It should be equal to the primal value scaled by \ref dualScale + /// "dual scale". + /// + /// \pre Either run() or start() must be called before using this function. + Value dualValue() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + sum += nodeValue(n); + } + for (int i = 0; i < blossomNum(); ++i) { + sum += blossomValue(i) * (blossomSize(i) / 2); + } + return sum; + } + + /// \brief Return the dual value (potential) of the given node. + /// + /// This function returns the dual value (potential) of the given node. + /// + /// \pre Either run() or start() must be called before using this function. + Value nodeValue(const Node& n) const { + return (*_node_potential)[n]; + } + + /// \brief Return the number of the blossoms in the basis. + /// + /// This function returns the number of the blossoms in the basis. + /// + /// \pre Either run() or start() must be called before using this function. + /// \see BlossomIt + int blossomNum() const { + return _blossom_potential.size(); + } + + /// \brief Return the number of the nodes in the given blossom. + /// + /// This function returns the number of the nodes in the given blossom. + /// + /// \pre Either run() or start() must be called before using this function. + /// \see BlossomIt + int blossomSize(int k) const { + return _blossom_potential[k].end - _blossom_potential[k].begin; + } + + /// \brief Return the dual value (ptential) of the given blossom. + /// + /// This function returns the dual value (ptential) of the given blossom. + /// + /// \pre Either run() or start() must be called before using this function. + Value blossomValue(int k) const { + return _blossom_potential[k].value; + } + + /// \brief Iterator for obtaining the nodes of a blossom. + /// + /// This class provides an iterator for obtaining the nodes of the + /// given blossom. It lists a subset of the nodes. + /// Before using this iterator, you must allocate a + /// MaxWeightedMatching class and execute it. + class BlossomIt { + public: + + /// \brief Constructor. + /// + /// Constructor to get the nodes of the given variable. + /// + /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or + /// \ref MaxWeightedMatching::start() "algorithm.start()" must be + /// called before initializing this iterator. + BlossomIt(const MaxWeightedMatching& algorithm, int variable) + : _algorithm(&algorithm) + { + _index = _algorithm->_blossom_potential[variable].begin; + _last = _algorithm->_blossom_potential[variable].end; + } + + /// \brief Conversion to \c Node. + /// + /// Conversion to \c Node. + operator Node() const { + return _algorithm->_blossom_node_list[_index]; + } + + /// \brief Increment operator. + /// + /// Increment operator. + BlossomIt& operator++() { + ++_index; + return *this; + } + + /// \brief Validity checking + /// + /// Checks whether the iterator is invalid. + bool operator==(Invalid) const { return _index == _last; } + + /// \brief Validity checking + /// + /// Checks whether the iterator is valid. + bool operator!=(Invalid) const { return _index != _last; } + + private: + const MaxWeightedMatching* _algorithm; + int _last; + int _index; + }; + + /// @} + + }; + + /// \ingroup matching + /// + /// \brief Weighted perfect matching in general graphs + /// + /// This class provides an efficient implementation of Edmond's + /// maximum weighted perfect matching algorithm. The implementation + /// is based on extensive use of priority queues and provides + /// \f$O(nm\log n)\f$ time complexity. + /// + /// The maximum weighted perfect matching problem is to find a subset of + /// the edges in an undirected graph with maximum overall weight for which + /// each node has exactly one incident edge. + /// It can be formulated with the following linear program. + /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f] + /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2} + \quad \forall B\in\mathcal{O}\f] */ + /// \f[x_e \ge 0\quad \forall e\in E\f] + /// \f[\max \sum_{e\in E}x_ew_e\f] + /// where \f$\delta(X)\f$ is the set of edges incident to a node in + /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in + /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality + /// subsets of the nodes. + /// + /// The algorithm calculates an optimal matching and a proof of the + /// optimality. The solution of the dual problem can be used to check + /// the result of the algorithm. The dual linear problem is the + /// following. + /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge + w_{uv} \quad \forall uv\in E\f] */ + /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f] + /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}} + \frac{\vert B \vert - 1}{2}z_B\f] */ + /// + /// The algorithm can be executed with the run() function. + /// After it the matching (the primal solution) and the dual solution + /// can be obtained using the query functions and the + /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, + /// which is able to iterate on the nodes of a blossom. + /// If the value type is integer, then the dual solution is multiplied + /// by \ref MaxWeightedMatching::dualScale "4". + /// + /// \tparam GR The undirected graph type the algorithm runs on. + /// \tparam WM The type edge weight map. The default type is + /// \ref concepts::Graph::EdgeMap "GR::EdgeMap". +#ifdef DOXYGEN + template +#else + template > +#endif + class MaxWeightedPerfectMatching { + public: + + /// The graph type of the algorithm + typedef GR Graph; + /// The type of the edge weight map + typedef WM WeightMap; + /// The value type of the edge weights + typedef typename WeightMap::Value Value; + + /// \brief Scaling factor for dual solution + /// + /// Scaling factor for dual solution, it is equal to 4 or 1 + /// according to the value type. + static const int dualScale = + std::numeric_limits::is_integer ? 4 : 1; + + /// The type of the matching map + typedef typename Graph::template NodeMap + MatchingMap; + + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + typedef typename Graph::template NodeMap NodePotential; + typedef std::vector BlossomNodeList; + + struct BlossomVariable { + int begin, end; + Value value; + + BlossomVariable(int _begin, int _end, Value _value) + : begin(_begin), end(_end), value(_value) {} + + }; + + typedef std::vector BlossomPotential; + + const Graph& _graph; + const WeightMap& _weight; + + MatchingMap* _matching; + + NodePotential* _node_potential; + + BlossomPotential _blossom_potential; + BlossomNodeList _blossom_node_list; + + int _node_num; + int _blossom_num; + + typedef RangeMap IntIntMap; + + enum Status { + EVEN = -1, MATCHED = 0, ODD = 1 + }; + + typedef HeapUnionFind BlossomSet; + struct BlossomData { + int tree; + Status status; + Arc pred, next; + Value pot, offset; + }; + + IntNodeMap *_blossom_index; + BlossomSet *_blossom_set; + RangeMap* _blossom_data; + + IntNodeMap *_node_index; + IntArcMap *_node_heap_index; + + struct NodeData { + + NodeData(IntArcMap& node_heap_index) + : heap(node_heap_index) {} + + int blossom; + Value pot; + BinHeap heap; + std::map heap_index; + + int tree; + }; + + RangeMap* _node_data; + + typedef ExtendFindEnum TreeSet; + + IntIntMap *_tree_set_index; + TreeSet *_tree_set; + + IntIntMap *_delta2_index; + BinHeap *_delta2; + + IntEdgeMap *_delta3_index; + BinHeap *_delta3; + + IntIntMap *_delta4_index; + BinHeap *_delta4; + + Value _delta_sum; + int _unmatched; + + typedef MaxWeightedPerfectFractionalMatching + FractionalMatching; + FractionalMatching *_fractional; + + void createStructures() { + _node_num = countNodes(_graph); + _blossom_num = _node_num * 3 / 2; + + if (!_matching) { + _matching = new MatchingMap(_graph); + } + + if (!_node_potential) { + _node_potential = new NodePotential(_graph); + } + + if (!_blossom_set) { + _blossom_index = new IntNodeMap(_graph); + _blossom_set = new BlossomSet(*_blossom_index); + _blossom_data = new RangeMap(_blossom_num); + } else if (_blossom_data->size() != _blossom_num) { + delete _blossom_data; + _blossom_data = new RangeMap(_blossom_num); + } + + if (!_node_index) { + _node_index = new IntNodeMap(_graph); + _node_heap_index = new IntArcMap(_graph); + _node_data = new RangeMap(_node_num, + NodeData(*_node_heap_index)); + } else if (_node_data->size() != _node_num) { + delete _node_data; + _node_data = new RangeMap(_node_num, + NodeData(*_node_heap_index)); + } + + if (!_tree_set) { + _tree_set_index = new IntIntMap(_blossom_num); + _tree_set = new TreeSet(*_tree_set_index); + } else { + _tree_set_index->resize(_blossom_num); + } + + if (!_delta2) { + _delta2_index = new IntIntMap(_blossom_num); + _delta2 = new BinHeap(*_delta2_index); + } else { + _delta2_index->resize(_blossom_num); + } + + if (!_delta3) { + _delta3_index = new IntEdgeMap(_graph); + _delta3 = new BinHeap(*_delta3_index); + } + + if (!_delta4) { + _delta4_index = new IntIntMap(_blossom_num); + _delta4 = new BinHeap(*_delta4_index); + } else { + _delta4_index->resize(_blossom_num); + } + } + + void destroyStructures() { + if (_matching) { + delete _matching; + } + if (_node_potential) { + delete _node_potential; + } + if (_blossom_set) { + delete _blossom_index; + delete _blossom_set; + delete _blossom_data; + } + + if (_node_index) { + delete _node_index; + delete _node_heap_index; + delete _node_data; + } + + if (_tree_set) { + delete _tree_set_index; + delete _tree_set; + } + if (_delta2) { + delete _delta2_index; + delete _delta2; + } + if (_delta3) { + delete _delta3_index; + delete _delta3; + } + if (_delta4) { + delete _delta4_index; + delete _delta4; + } + } + + void matchedToEven(int blossom, int tree) { + if (_delta2->state(blossom) == _delta2->IN_HEAP) { + _delta2->erase(blossom); + } + + if (!_blossom_set->trivial(blossom)) { + (*_blossom_data)[blossom].pot -= + 2 * (_delta_sum - (*_blossom_data)[blossom].offset); + } + + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom); + n != INVALID; ++n) { + + _blossom_set->increase(n, std::numeric_limits::max()); + int ni = (*_node_index)[n]; + + (*_node_data)[ni].heap.clear(); + (*_node_data)[ni].heap_index.clear(); + + (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset; + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.source(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if ((*_blossom_data)[vb].status == EVEN) { + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) { + _delta3->push(e, rw / 2); + } + } else { + typename std::map::iterator it = + (*_node_data)[vi].heap_index.find(tree); + + if (it != (*_node_data)[vi].heap_index.end()) { + if ((*_node_data)[vi].heap[it->second] > rw) { + (*_node_data)[vi].heap.replace(it->second, e); + (*_node_data)[vi].heap.decrease(e, rw); + it->second = e; + } + } else { + (*_node_data)[vi].heap.push(e, rw); + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e)); + } + + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) { + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio()); + + if ((*_blossom_data)[vb].status == MATCHED) { + if (_delta2->state(vb) != _delta2->IN_HEAP) { + _delta2->push(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset){ + _delta2->decrease(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } + } + } + } + } + } + (*_blossom_data)[blossom].offset = 0; + } + + void matchedToOdd(int blossom) { + if (_delta2->state(blossom) == _delta2->IN_HEAP) { + _delta2->erase(blossom); + } + (*_blossom_data)[blossom].offset += _delta_sum; + if (!_blossom_set->trivial(blossom)) { + _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 + + (*_blossom_data)[blossom].offset); + } + } + + void evenToMatched(int blossom, int tree) { + if (!_blossom_set->trivial(blossom)) { + (*_blossom_data)[blossom].pot += 2 * _delta_sum; + } + + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom); + n != INVALID; ++n) { + int ni = (*_node_index)[n]; + (*_node_data)[ni].pot -= _delta_sum; + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.source(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if (vb == blossom) { + if (_delta3->state(e) == _delta3->IN_HEAP) { + _delta3->erase(e); + } + } else if ((*_blossom_data)[vb].status == EVEN) { + + if (_delta3->state(e) == _delta3->IN_HEAP) { + _delta3->erase(e); + } + + int vt = _tree_set->find(vb); + + if (vt != tree) { + + Arc r = _graph.oppositeArc(e); + + typename std::map::iterator it = + (*_node_data)[ni].heap_index.find(vt); + + if (it != (*_node_data)[ni].heap_index.end()) { + if ((*_node_data)[ni].heap[it->second] > rw) { + (*_node_data)[ni].heap.replace(it->second, r); + (*_node_data)[ni].heap.decrease(r, rw); + it->second = r; + } + } else { + (*_node_data)[ni].heap.push(r, rw); + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r)); + } + + if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) { + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio()); + + if (_delta2->state(blossom) != _delta2->IN_HEAP) { + _delta2->push(blossom, _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset); + } else if ((*_delta2)[blossom] > + _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset){ + _delta2->decrease(blossom, _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset); + } + } + } + } else { + + typename std::map::iterator it = + (*_node_data)[vi].heap_index.find(tree); + + if (it != (*_node_data)[vi].heap_index.end()) { + (*_node_data)[vi].heap.erase(it->second); + (*_node_data)[vi].heap_index.erase(it); + if ((*_node_data)[vi].heap.empty()) { + _blossom_set->increase(v, std::numeric_limits::max()); + } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) { + _blossom_set->increase(v, (*_node_data)[vi].heap.prio()); + } + + if ((*_blossom_data)[vb].status == MATCHED) { + if (_blossom_set->classPrio(vb) == + std::numeric_limits::max()) { + _delta2->erase(vb); + } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset) { + _delta2->increase(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } + } + } + } + } + } + } + + void oddToMatched(int blossom) { + (*_blossom_data)[blossom].offset -= _delta_sum; + + if (_blossom_set->classPrio(blossom) != + std::numeric_limits::max()) { + _delta2->push(blossom, _blossom_set->classPrio(blossom) - + (*_blossom_data)[blossom].offset); + } + + if (!_blossom_set->trivial(blossom)) { + _delta4->erase(blossom); + } + } + + void oddToEven(int blossom, int tree) { + if (!_blossom_set->trivial(blossom)) { + _delta4->erase(blossom); + (*_blossom_data)[blossom].pot -= + 2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset); + } + + for (typename BlossomSet::ItemIt n(*_blossom_set, blossom); + n != INVALID; ++n) { + int ni = (*_node_index)[n]; + + _blossom_set->increase(n, std::numeric_limits::max()); + + (*_node_data)[ni].heap.clear(); + (*_node_data)[ni].heap_index.clear(); + (*_node_data)[ni].pot += + 2 * _delta_sum - (*_blossom_data)[blossom].offset; + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.source(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if ((*_blossom_data)[vb].status == EVEN) { + if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) { + _delta3->push(e, rw / 2); + } + } else { + + typename std::map::iterator it = + (*_node_data)[vi].heap_index.find(tree); + + if (it != (*_node_data)[vi].heap_index.end()) { + if ((*_node_data)[vi].heap[it->second] > rw) { + (*_node_data)[vi].heap.replace(it->second, e); + (*_node_data)[vi].heap.decrease(e, rw); + it->second = e; + } + } else { + (*_node_data)[vi].heap.push(e, rw); + (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e)); + } + + if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) { + _blossom_set->decrease(v, (*_node_data)[vi].heap.prio()); + + if ((*_blossom_data)[vb].status == MATCHED) { + if (_delta2->state(vb) != _delta2->IN_HEAP) { + _delta2->push(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset) { + _delta2->decrease(vb, _blossom_set->classPrio(vb) - + (*_blossom_data)[vb].offset); + } + } + } + } + } + } + (*_blossom_data)[blossom].offset = 0; + } + + void alternatePath(int even, int tree) { + int odd; + + evenToMatched(even, tree); + (*_blossom_data)[even].status = MATCHED; + + while ((*_blossom_data)[even].pred != INVALID) { + odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred)); + (*_blossom_data)[odd].status = MATCHED; + oddToMatched(odd); + (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred; + + even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred)); + (*_blossom_data)[even].status = MATCHED; + evenToMatched(even, tree); + (*_blossom_data)[even].next = + _graph.oppositeArc((*_blossom_data)[odd].pred); + } + + } + + void destroyTree(int tree) { + for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) { + if ((*_blossom_data)[b].status == EVEN) { + (*_blossom_data)[b].status = MATCHED; + evenToMatched(b, tree); + } else if ((*_blossom_data)[b].status == ODD) { + (*_blossom_data)[b].status = MATCHED; + oddToMatched(b); + } + } + _tree_set->eraseClass(tree); + } + + void augmentOnEdge(const Edge& edge) { + + int left = _blossom_set->find(_graph.u(edge)); + int right = _blossom_set->find(_graph.v(edge)); + + int left_tree = _tree_set->find(left); + alternatePath(left, left_tree); + destroyTree(left_tree); + + int right_tree = _tree_set->find(right); + alternatePath(right, right_tree); + destroyTree(right_tree); + + (*_blossom_data)[left].next = _graph.direct(edge, true); + (*_blossom_data)[right].next = _graph.direct(edge, false); + } + + void extendOnArc(const Arc& arc) { + int base = _blossom_set->find(_graph.target(arc)); + int tree = _tree_set->find(base); + + int odd = _blossom_set->find(_graph.source(arc)); + _tree_set->insert(odd, tree); + (*_blossom_data)[odd].status = ODD; + matchedToOdd(odd); + (*_blossom_data)[odd].pred = arc; + + int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next)); + (*_blossom_data)[even].pred = (*_blossom_data)[even].next; + _tree_set->insert(even, tree); + (*_blossom_data)[even].status = EVEN; + matchedToEven(even, tree); + } + + void shrinkOnEdge(const Edge& edge, int tree) { + int nca = -1; + std::vector left_path, right_path; + + { + std::set left_set, right_set; + int left = _blossom_set->find(_graph.u(edge)); + left_path.push_back(left); + left_set.insert(left); + + int right = _blossom_set->find(_graph.v(edge)); + right_path.push_back(right); + right_set.insert(right); + + while (true) { + + if ((*_blossom_data)[left].pred == INVALID) break; + + left = + _blossom_set->find(_graph.target((*_blossom_data)[left].pred)); + left_path.push_back(left); + left = + _blossom_set->find(_graph.target((*_blossom_data)[left].pred)); + left_path.push_back(left); + + left_set.insert(left); + + if (right_set.find(left) != right_set.end()) { + nca = left; + break; + } + + if ((*_blossom_data)[right].pred == INVALID) break; + + right = + _blossom_set->find(_graph.target((*_blossom_data)[right].pred)); + right_path.push_back(right); + right = + _blossom_set->find(_graph.target((*_blossom_data)[right].pred)); + right_path.push_back(right); + + right_set.insert(right); + + if (left_set.find(right) != left_set.end()) { + nca = right; + break; + } + + } + + if (nca == -1) { + if ((*_blossom_data)[left].pred == INVALID) { + nca = right; + while (left_set.find(nca) == left_set.end()) { + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + right_path.push_back(nca); + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + right_path.push_back(nca); + } + } else { + nca = left; + while (right_set.find(nca) == right_set.end()) { + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + left_path.push_back(nca); + nca = + _blossom_set->find(_graph.target((*_blossom_data)[nca].pred)); + left_path.push_back(nca); + } + } + } + } + + std::vector subblossoms; + Arc prev; + + prev = _graph.direct(edge, true); + for (int i = 0; left_path[i] != nca; i += 2) { + subblossoms.push_back(left_path[i]); + (*_blossom_data)[left_path[i]].next = prev; + _tree_set->erase(left_path[i]); + + subblossoms.push_back(left_path[i + 1]); + (*_blossom_data)[left_path[i + 1]].status = EVEN; + oddToEven(left_path[i + 1], tree); + _tree_set->erase(left_path[i + 1]); + prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred); + } + + int k = 0; + while (right_path[k] != nca) ++k; + + subblossoms.push_back(nca); + (*_blossom_data)[nca].next = prev; + + for (int i = k - 2; i >= 0; i -= 2) { + subblossoms.push_back(right_path[i + 1]); + (*_blossom_data)[right_path[i + 1]].status = EVEN; + oddToEven(right_path[i + 1], tree); + _tree_set->erase(right_path[i + 1]); + + (*_blossom_data)[right_path[i + 1]].next = + (*_blossom_data)[right_path[i + 1]].pred; + + subblossoms.push_back(right_path[i]); + _tree_set->erase(right_path[i]); + } + + int surface = + _blossom_set->join(subblossoms.begin(), subblossoms.end()); + + for (int i = 0; i < int(subblossoms.size()); ++i) { + if (!_blossom_set->trivial(subblossoms[i])) { + (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum; + } + (*_blossom_data)[subblossoms[i]].status = MATCHED; + } + + (*_blossom_data)[surface].pot = -2 * _delta_sum; + (*_blossom_data)[surface].offset = 0; + (*_blossom_data)[surface].status = EVEN; + (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred; + (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred; + + _tree_set->insert(surface, tree); + _tree_set->erase(nca); + } + + void splitBlossom(int blossom) { + Arc next = (*_blossom_data)[blossom].next; + Arc pred = (*_blossom_data)[blossom].pred; + + int tree = _tree_set->find(blossom); + + (*_blossom_data)[blossom].status = MATCHED; + oddToMatched(blossom); + if (_delta2->state(blossom) == _delta2->IN_HEAP) { + _delta2->erase(blossom); + } + + std::vector subblossoms; + _blossom_set->split(blossom, std::back_inserter(subblossoms)); + + Value offset = (*_blossom_data)[blossom].offset; + int b = _blossom_set->find(_graph.source(pred)); + int d = _blossom_set->find(_graph.source(next)); + + int ib = -1, id = -1; + for (int i = 0; i < int(subblossoms.size()); ++i) { + if (subblossoms[i] == b) ib = i; + if (subblossoms[i] == d) id = i; + + (*_blossom_data)[subblossoms[i]].offset = offset; + if (!_blossom_set->trivial(subblossoms[i])) { + (*_blossom_data)[subblossoms[i]].pot -= 2 * offset; + } + if (_blossom_set->classPrio(subblossoms[i]) != + std::numeric_limits::max()) { + _delta2->push(subblossoms[i], + _blossom_set->classPrio(subblossoms[i]) - + (*_blossom_data)[subblossoms[i]].offset); + } + } + + if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) { + for (int i = (id + 1) % subblossoms.size(); + i != ib; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + (*_blossom_data)[sb].next = + _graph.oppositeArc((*_blossom_data)[tb].next); + } + + for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + int ub = subblossoms[(i + 2) % subblossoms.size()]; + + (*_blossom_data)[sb].status = ODD; + matchedToOdd(sb); + _tree_set->insert(sb, tree); + (*_blossom_data)[sb].pred = pred; + (*_blossom_data)[sb].next = + _graph.oppositeArc((*_blossom_data)[tb].next); + + pred = (*_blossom_data)[ub].next; + + (*_blossom_data)[tb].status = EVEN; + matchedToEven(tb, tree); + _tree_set->insert(tb, tree); + (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next; + } + + (*_blossom_data)[subblossoms[id]].status = ODD; + matchedToOdd(subblossoms[id]); + _tree_set->insert(subblossoms[id], tree); + (*_blossom_data)[subblossoms[id]].next = next; + (*_blossom_data)[subblossoms[id]].pred = pred; + + } else { + + for (int i = (ib + 1) % subblossoms.size(); + i != id; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + (*_blossom_data)[sb].next = + _graph.oppositeArc((*_blossom_data)[tb].next); + } + + for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) { + int sb = subblossoms[i]; + int tb = subblossoms[(i + 1) % subblossoms.size()]; + int ub = subblossoms[(i + 2) % subblossoms.size()]; + + (*_blossom_data)[sb].status = ODD; + matchedToOdd(sb); + _tree_set->insert(sb, tree); + (*_blossom_data)[sb].next = next; + (*_blossom_data)[sb].pred = + _graph.oppositeArc((*_blossom_data)[tb].next); + + (*_blossom_data)[tb].status = EVEN; + matchedToEven(tb, tree); + _tree_set->insert(tb, tree); + (*_blossom_data)[tb].pred = + (*_blossom_data)[tb].next = + _graph.oppositeArc((*_blossom_data)[ub].next); + next = (*_blossom_data)[ub].next; + } + + (*_blossom_data)[subblossoms[ib]].status = ODD; + matchedToOdd(subblossoms[ib]); + _tree_set->insert(subblossoms[ib], tree); + (*_blossom_data)[subblossoms[ib]].next = next; + (*_blossom_data)[subblossoms[ib]].pred = pred; + } + _tree_set->erase(blossom); + } + + void extractBlossom(int blossom, const Node& base, const Arc& matching) { + if (_blossom_set->trivial(blossom)) { + int bi = (*_node_index)[base]; + Value pot = (*_node_data)[bi].pot; + + (*_matching)[base] = matching; + _blossom_node_list.push_back(base); + (*_node_potential)[base] = pot; + } else { + + Value pot = (*_blossom_data)[blossom].pot; + int bn = _blossom_node_list.size(); + + std::vector subblossoms; + _blossom_set->split(blossom, std::back_inserter(subblossoms)); + int b = _blossom_set->find(base); + int ib = -1; + for (int i = 0; i < int(subblossoms.size()); ++i) { + if (subblossoms[i] == b) { ib = i; break; } + } + + for (int i = 1; i < int(subblossoms.size()); i += 2) { + int sb = subblossoms[(ib + i) % subblossoms.size()]; + int tb = subblossoms[(ib + i + 1) % subblossoms.size()]; + + Arc m = (*_blossom_data)[tb].next; + extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m)); + extractBlossom(tb, _graph.source(m), m); + } + extractBlossom(subblossoms[ib], base, matching); + + int en = _blossom_node_list.size(); + + _blossom_potential.push_back(BlossomVariable(bn, en, pot)); + } + } + + void extractMatching() { + std::vector blossoms; + for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) { + blossoms.push_back(c); + } + + for (int i = 0; i < int(blossoms.size()); ++i) { + + Value offset = (*_blossom_data)[blossoms[i]].offset; + (*_blossom_data)[blossoms[i]].pot += 2 * offset; + for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]); + n != INVALID; ++n) { + (*_node_data)[(*_node_index)[n]].pot -= offset; + } + + Arc matching = (*_blossom_data)[blossoms[i]].next; + Node base = _graph.source(matching); + extractBlossom(blossoms[i], base, matching); + } + } + + public: + + /// \brief Constructor + /// + /// Constructor. + MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight) + : _graph(graph), _weight(weight), _matching(0), + _node_potential(0), _blossom_potential(), _blossom_node_list(), + _node_num(0), _blossom_num(0), + + _blossom_index(0), _blossom_set(0), _blossom_data(0), + _node_index(0), _node_heap_index(0), _node_data(0), + _tree_set_index(0), _tree_set(0), + + _delta2_index(0), _delta2(0), + _delta3_index(0), _delta3(0), + _delta4_index(0), _delta4(0), + + _delta_sum(), _unmatched(0), + + _fractional(0) + {} + + ~MaxWeightedPerfectMatching() { + destroyStructures(); + if (_fractional) { + delete _fractional; + } + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to use the + /// \ref run() member function. + + ///@{ + + /// \brief Initialize the algorithm + /// + /// This function initializes the algorithm. + void init() { + createStructures(); + + _blossom_node_list.clear(); + _blossom_potential.clear(); + + for (ArcIt e(_graph); e != INVALID; ++e) { + (*_node_heap_index)[e] = BinHeap::PRE_HEAP; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + (*_delta3_index)[e] = _delta3->PRE_HEAP; + } + for (int i = 0; i < _blossom_num; ++i) { + (*_delta2_index)[i] = _delta2->PRE_HEAP; + (*_delta4_index)[i] = _delta4->PRE_HEAP; + } + + _unmatched = _node_num; + + _delta2->clear(); + _delta3->clear(); + _delta4->clear(); + _blossom_set->clear(); + _tree_set->clear(); + + int index = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + Value max = - std::numeric_limits::max(); + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + if (_graph.target(e) == n) continue; + if ((dualScale * _weight[e]) / 2 > max) { + max = (dualScale * _weight[e]) / 2; + } + } + (*_node_index)[n] = index; + (*_node_data)[index].heap_index.clear(); + (*_node_data)[index].heap.clear(); + (*_node_data)[index].pot = max; + int blossom = + _blossom_set->insert(n, std::numeric_limits::max()); + + _tree_set->insert(blossom); + + (*_blossom_data)[blossom].status = EVEN; + (*_blossom_data)[blossom].pred = INVALID; + (*_blossom_data)[blossom].next = INVALID; + (*_blossom_data)[blossom].pot = 0; + (*_blossom_data)[blossom].offset = 0; + ++index; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + int si = (*_node_index)[_graph.u(e)]; + int ti = (*_node_index)[_graph.v(e)]; + if (_graph.u(e) != _graph.v(e)) { + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot - + dualScale * _weight[e]) / 2); + } + } + } + + /// \brief Initialize the algorithm with fractional matching + /// + /// This function initializes the algorithm with a fractional + /// matching. This initialization is also called jumpstart heuristic. + void fractionalInit() { + createStructures(); + + _blossom_node_list.clear(); + _blossom_potential.clear(); + + if (_fractional == 0) { + _fractional = new FractionalMatching(_graph, _weight, false); + } + if (!_fractional->run()) { + _unmatched = -1; + return; + } + + for (ArcIt e(_graph); e != INVALID; ++e) { + (*_node_heap_index)[e] = BinHeap::PRE_HEAP; + } + for (EdgeIt e(_graph); e != INVALID; ++e) { + (*_delta3_index)[e] = _delta3->PRE_HEAP; + } + for (int i = 0; i < _blossom_num; ++i) { + (*_delta2_index)[i] = _delta2->PRE_HEAP; + (*_delta4_index)[i] = _delta4->PRE_HEAP; + } + + _unmatched = 0; + + _delta2->clear(); + _delta3->clear(); + _delta4->clear(); + _blossom_set->clear(); + _tree_set->clear(); + + int index = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + Value pot = _fractional->nodeValue(n); + (*_node_index)[n] = index; + (*_node_data)[index].pot = pot; + (*_node_data)[index].heap_index.clear(); + (*_node_data)[index].heap.clear(); + int blossom = + _blossom_set->insert(n, std::numeric_limits::max()); + + (*_blossom_data)[blossom].status = MATCHED; + (*_blossom_data)[blossom].pred = INVALID; + (*_blossom_data)[blossom].next = _fractional->matching(n); + (*_blossom_data)[blossom].pot = 0; + (*_blossom_data)[blossom].offset = 0; + ++index; + } + + typename Graph::template NodeMap processed(_graph, false); + for (NodeIt n(_graph); n != INVALID; ++n) { + if (processed[n]) continue; + processed[n] = true; + if (_fractional->matching(n) == INVALID) continue; + int num = 1; + Node v = _graph.target(_fractional->matching(n)); + while (n != v) { + processed[v] = true; + v = _graph.target(_fractional->matching(v)); + ++num; + } + + if (num % 2 == 1) { + std::vector subblossoms(num); + + subblossoms[--num] = _blossom_set->find(n); + v = _graph.target(_fractional->matching(n)); + while (n != v) { + subblossoms[--num] = _blossom_set->find(v); + v = _graph.target(_fractional->matching(v)); + } + + int surface = + _blossom_set->join(subblossoms.begin(), subblossoms.end()); + (*_blossom_data)[surface].status = EVEN; + (*_blossom_data)[surface].pred = INVALID; + (*_blossom_data)[surface].next = INVALID; + (*_blossom_data)[surface].pot = 0; + (*_blossom_data)[surface].offset = 0; + + _tree_set->insert(surface); + ++_unmatched; + } + } + + for (EdgeIt e(_graph); e != INVALID; ++e) { + int si = (*_node_index)[_graph.u(e)]; + int sb = _blossom_set->find(_graph.u(e)); + int ti = (*_node_index)[_graph.v(e)]; + int tb = _blossom_set->find(_graph.v(e)); + if ((*_blossom_data)[sb].status == EVEN && + (*_blossom_data)[tb].status == EVEN && sb != tb) { + _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot - + dualScale * _weight[e]) / 2); + } + } + + for (NodeIt n(_graph); n != INVALID; ++n) { + int nb = _blossom_set->find(n); + if ((*_blossom_data)[nb].status != MATCHED) continue; + int ni = (*_node_index)[n]; + + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.target(e); + int vb = _blossom_set->find(v); + int vi = (*_node_index)[v]; + + Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot - + dualScale * _weight[e]; + + if ((*_blossom_data)[vb].status == EVEN) { + + int vt = _tree_set->find(vb); + + typename std::map::iterator it = + (*_node_data)[ni].heap_index.find(vt); + + if (it != (*_node_data)[ni].heap_index.end()) { + if ((*_node_data)[ni].heap[it->second] > rw) { + (*_node_data)[ni].heap.replace(it->second, e); + (*_node_data)[ni].heap.decrease(e, rw); + it->second = e; + } + } else { + (*_node_data)[ni].heap.push(e, rw); + (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e)); + } + } + } + + if (!(*_node_data)[ni].heap.empty()) { + _blossom_set->decrease(n, (*_node_data)[ni].heap.prio()); + _delta2->push(nb, _blossom_set->classPrio(nb)); + } + } + } + + /// \brief Start the algorithm + /// + /// This function starts the algorithm. + /// + /// \pre \ref init() or \ref fractionalInit() must be called before + /// using this function. + bool start() { + enum OpType { + D2, D3, D4 + }; + + if (_unmatched == -1) return false; + + while (_unmatched > 0) { + Value d2 = !_delta2->empty() ? + _delta2->prio() : std::numeric_limits::max(); + + Value d3 = !_delta3->empty() ? + _delta3->prio() : std::numeric_limits::max(); + + Value d4 = !_delta4->empty() ? + _delta4->prio() : std::numeric_limits::max(); + + _delta_sum = d3; OpType ot = D3; + if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; } + if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; } + + if (_delta_sum == std::numeric_limits::max()) { + return false; + } + + switch (ot) { + case D2: + { + int blossom = _delta2->top(); + Node n = _blossom_set->classTop(blossom); + Arc e = (*_node_data)[(*_node_index)[n]].heap.top(); + extendOnArc(e); + } + break; + case D3: + { + Edge e = _delta3->top(); + + int left_blossom = _blossom_set->find(_graph.u(e)); + int right_blossom = _blossom_set->find(_graph.v(e)); + + if (left_blossom == right_blossom) { + _delta3->pop(); + } else { + int left_tree = _tree_set->find(left_blossom); + int right_tree = _tree_set->find(right_blossom); + + if (left_tree == right_tree) { + shrinkOnEdge(e, left_tree); + } else { + augmentOnEdge(e); + _unmatched -= 2; + } + } + } break; + case D4: + splitBlossom(_delta4->top()); + break; + } + } + extractMatching(); + return true; + } + + /// \brief Run the algorithm. + /// + /// This method runs the \c %MaxWeightedPerfectMatching algorithm. + /// + /// \note mwpm.run() is just a shortcut of the following code. + /// \code + /// mwpm.fractionalInit(); + /// mwpm.start(); + /// \endcode + bool run() { + fractionalInit(); + return start(); + } + + /// @} + + /// \name Primal Solution + /// Functions to get the primal solution, i.e. the maximum weighted + /// perfect matching.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the weight of the matching. + /// + /// This function returns the weight of the found matching. + /// + /// \pre Either run() or start() must be called before using this function. + Value matchingWeight() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + if ((*_matching)[n] != INVALID) { + sum += _weight[(*_matching)[n]]; + } + } + return sum / 2; + } + + /// \brief Return \c true if the given edge is in the matching. + /// + /// This function returns \c true if the given edge is in the found + /// matching. + /// + /// \pre Either run() or start() must be called before using this function. + bool matching(const Edge& edge) const { + return static_cast((*_matching)[_graph.u(edge)]) == edge; + } + + /// \brief Return the matching arc (or edge) incident to the given node. + /// + /// This function returns the matching arc (or edge) incident to the + /// given node in the found matching or \c INVALID if the node is + /// not covered by the matching. + /// + /// \pre Either run() or start() must be called before using this function. + Arc matching(const Node& node) const { + return (*_matching)[node]; + } + + /// \brief Return a const reference to the matching map. + /// + /// This function returns a const reference to a node map that stores + /// the matching arc (or edge) incident to each node. + const MatchingMap& matchingMap() const { + return *_matching; + } + + /// \brief Return the mate of the given node. + /// + /// This function returns the mate of the given node in the found + /// matching or \c INVALID if the node is not covered by the matching. + /// + /// \pre Either run() or start() must be called before using this function. + Node mate(const Node& node) const { + return _graph.target((*_matching)[node]); + } + + /// @} + + /// \name Dual Solution + /// Functions to get the dual solution.\n + /// Either \ref run() or \ref start() function should be called before + /// using them. + + /// @{ + + /// \brief Return the value of the dual solution. + /// + /// This function returns the value of the dual solution. + /// It should be equal to the primal value scaled by \ref dualScale + /// "dual scale". + /// + /// \pre Either run() or start() must be called before using this function. + Value dualValue() const { + Value sum = 0; + for (NodeIt n(_graph); n != INVALID; ++n) { + sum += nodeValue(n); + } + for (int i = 0; i < blossomNum(); ++i) { + sum += blossomValue(i) * (blossomSize(i) / 2); + } + return sum; + } + + /// \brief Return the dual value (potential) of the given node. + /// + /// This function returns the dual value (potential) of the given node. + /// + /// \pre Either run() or start() must be called before using this function. + Value nodeValue(const Node& n) const { + return (*_node_potential)[n]; + } + + /// \brief Return the number of the blossoms in the basis. + /// + /// This function returns the number of the blossoms in the basis. + /// + /// \pre Either run() or start() must be called before using this function. + /// \see BlossomIt + int blossomNum() const { + return _blossom_potential.size(); + } + + /// \brief Return the number of the nodes in the given blossom. + /// + /// This function returns the number of the nodes in the given blossom. + /// + /// \pre Either run() or start() must be called before using this function. + /// \see BlossomIt + int blossomSize(int k) const { + return _blossom_potential[k].end - _blossom_potential[k].begin; + } + + /// \brief Return the dual value (ptential) of the given blossom. + /// + /// This function returns the dual value (ptential) of the given blossom. + /// + /// \pre Either run() or start() must be called before using this function. + Value blossomValue(int k) const { + return _blossom_potential[k].value; + } + + /// \brief Iterator for obtaining the nodes of a blossom. + /// + /// This class provides an iterator for obtaining the nodes of the + /// given blossom. It lists a subset of the nodes. + /// Before using this iterator, you must allocate a + /// MaxWeightedPerfectMatching class and execute it. + class BlossomIt { + public: + + /// \brief Constructor. + /// + /// Constructor to get the nodes of the given variable. + /// + /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" + /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" + /// must be called before initializing this iterator. + BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable) + : _algorithm(&algorithm) + { + _index = _algorithm->_blossom_potential[variable].begin; + _last = _algorithm->_blossom_potential[variable].end; + } + + /// \brief Conversion to \c Node. + /// + /// Conversion to \c Node. + operator Node() const { + return _algorithm->_blossom_node_list[_index]; + } + + /// \brief Increment operator. + /// + /// Increment operator. + BlossomIt& operator++() { + ++_index; + return *this; + } + + /// \brief Validity checking + /// + /// This function checks whether the iterator is invalid. + bool operator==(Invalid) const { return _index == _last; } + + /// \brief Validity checking + /// + /// This function checks whether the iterator is valid. + bool operator!=(Invalid) const { return _index != _last; } + + private: + const MaxWeightedPerfectMatching* _algorithm; + int _last; + int _index; + }; + + /// @} + + }; + +} //END OF NAMESPACE LEMON + +#endif //LEMON_MATCHING_H diff --git a/lemon/lemon/math.h b/lemon/lemon/math.h new file mode 100644 index 0000000..215ac58 --- /dev/null +++ b/lemon/lemon/math.h @@ -0,0 +1,72 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_MATH_H +#define LEMON_MATH_H + +///\ingroup misc +///\file +///\brief Some extensions to the standard \c cmath library. +/// +///Some extensions to the standard \c cmath library. +/// +///This file includes the standard math library (cmath). + +#include + +namespace lemon { + + /// \addtogroup misc + /// @{ + + /// The Euler constant + const long double E = 2.7182818284590452353602874713526625L; + /// log_2(e) + const long double LOG2E = 1.4426950408889634073599246810018921L; + /// log_10(e) + const long double LOG10E = 0.4342944819032518276511289189166051L; + /// ln(2) + const long double LN2 = 0.6931471805599453094172321214581766L; + /// ln(10) + const long double LN10 = 2.3025850929940456840179914546843642L; + /// pi + const long double PI = 3.1415926535897932384626433832795029L; + /// pi/2 + const long double PI_2 = 1.5707963267948966192313216916397514L; + /// pi/4 + const long double PI_4 = 0.7853981633974483096156608458198757L; + /// sqrt(2) + const long double SQRT2 = 1.4142135623730950488016887242096981L; + /// 1/sqrt(2) + const long double SQRT1_2 = 0.7071067811865475244008443621048490L; + + ///Check whether the parameter is NaN or not + + ///This function checks whether the parameter is NaN or not. + ///Is should be equivalent with std::isnan(), but it is not + ///provided by all compilers. + inline bool isNaN(double v) + { + return v!=v; + } + + /// @} + +} //namespace lemon + +#endif //LEMON_TOLERANCE_H diff --git a/lemon/lemon/min_cost_arborescence.h b/lemon/lemon/min_cost_arborescence.h new file mode 100644 index 0000000..249e5ed --- /dev/null +++ b/lemon/lemon/min_cost_arborescence.h @@ -0,0 +1,808 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_MIN_COST_ARBORESCENCE_H +#define LEMON_MIN_COST_ARBORESCENCE_H + +///\ingroup spantree +///\file +///\brief Minimum Cost Arborescence algorithm. + +#include + +#include +#include +#include + +namespace lemon { + + + /// \brief Default traits class for MinCostArborescence class. + /// + /// Default traits class for MinCostArborescence class. + /// \param GR Digraph type. + /// \param CM Type of the cost map. + template + struct MinCostArborescenceDefaultTraits{ + + /// \brief The digraph type the algorithm runs on. + typedef GR Digraph; + + /// \brief The type of the map that stores the arc costs. + /// + /// The type of the map that stores the arc costs. + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. + typedef CM CostMap; + + /// \brief The value type of the costs. + /// + /// The value type of the costs. + typedef typename CostMap::Value Value; + + /// \brief The type of the map that stores which arcs are in the + /// arborescence. + /// + /// The type of the map that stores which arcs are in the + /// arborescence. It must conform to the \ref concepts::WriteMap + /// "WriteMap" concept, and its value type must be \c bool + /// (or convertible). Initially it will be set to \c false on each + /// arc, then it will be set on each arborescence arc once. + typedef typename Digraph::template ArcMap ArborescenceMap; + + /// \brief Instantiates a \c ArborescenceMap. + /// + /// This function instantiates a \c ArborescenceMap. + /// \param digraph The digraph to which we would like to calculate + /// the \c ArborescenceMap. + static ArborescenceMap *createArborescenceMap(const Digraph &digraph){ + return new ArborescenceMap(digraph); + } + + /// \brief The type of the \c PredMap + /// + /// The type of the \c PredMap. It must confrom to the + /// \ref concepts::WriteMap "WriteMap" concept, and its value type + /// must be the \c Arc type of the digraph. + typedef typename Digraph::template NodeMap PredMap; + + /// \brief Instantiates a \c PredMap. + /// + /// This function instantiates a \c PredMap. + /// \param digraph The digraph to which we would like to define the + /// \c PredMap. + static PredMap *createPredMap(const Digraph &digraph){ + return new PredMap(digraph); + } + + }; + + /// \ingroup spantree + /// + /// \brief Minimum Cost Arborescence algorithm class. + /// + /// This class provides an efficient implementation of the + /// Minimum Cost Arborescence algorithm. The arborescence is a tree + /// which is directed from a given source node of the digraph. One or + /// more sources should be given to the algorithm and it will calculate + /// the minimum cost subgraph that is the union of arborescences with the + /// given sources and spans all the nodes which are reachable from the + /// sources. The time complexity of the algorithm is O(n2+e). + /// + /// The algorithm also provides an optimal dual solution, therefore + /// the optimality of the solution can be checked. + /// + /// \param GR The digraph type the algorithm runs on. + /// \param CM A read-only arc map storing the costs of the + /// arcs. It is read once for each arc, so the map may involve in + /// relatively time consuming process to compute the arc costs if + /// it is necessary. The default map type is \ref + /// concepts::Digraph::ArcMap "Digraph::ArcMap". + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref MinCostArborescenceDefaultTraits + /// "MinCostArborescenceDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifndef DOXYGEN + template , + typename TR = + MinCostArborescenceDefaultTraits > +#else + template +#endif + class MinCostArborescence { + public: + + /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" + /// of the algorithm. + typedef TR Traits; + /// The type of the underlying digraph. + typedef typename Traits::Digraph Digraph; + /// The type of the map that stores the arc costs. + typedef typename Traits::CostMap CostMap; + ///The type of the costs of the arcs. + typedef typename Traits::Value Value; + ///The type of the predecessor map. + typedef typename Traits::PredMap PredMap; + ///The type of the map that stores which arcs are in the arborescence. + typedef typename Traits::ArborescenceMap ArborescenceMap; + + typedef MinCostArborescence Create; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + struct CostArc { + + Arc arc; + Value value; + + CostArc() {} + CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {} + + }; + + const Digraph *_digraph; + const CostMap *_cost; + + PredMap *_pred; + bool local_pred; + + ArborescenceMap *_arborescence; + bool local_arborescence; + + typedef typename Digraph::template ArcMap ArcOrder; + ArcOrder *_arc_order; + + typedef typename Digraph::template NodeMap NodeOrder; + NodeOrder *_node_order; + + typedef typename Digraph::template NodeMap CostArcMap; + CostArcMap *_cost_arcs; + + struct StackLevel { + + std::vector arcs; + int node_level; + + }; + + std::vector level_stack; + std::vector queue; + + typedef std::vector DualNodeList; + + DualNodeList _dual_node_list; + + struct DualVariable { + int begin, end; + Value value; + + DualVariable(int _begin, int _end, Value _value) + : begin(_begin), end(_end), value(_value) {} + + }; + + typedef std::vector DualVariables; + + DualVariables _dual_variables; + + typedef typename Digraph::template NodeMap HeapCrossRef; + + HeapCrossRef *_heap_cross_ref; + + typedef BinHeap Heap; + + Heap *_heap; + + protected: + + MinCostArborescence() {} + + private: + + void createStructures() { + if (!_pred) { + local_pred = true; + _pred = Traits::createPredMap(*_digraph); + } + if (!_arborescence) { + local_arborescence = true; + _arborescence = Traits::createArborescenceMap(*_digraph); + } + if (!_arc_order) { + _arc_order = new ArcOrder(*_digraph); + } + if (!_node_order) { + _node_order = new NodeOrder(*_digraph); + } + if (!_cost_arcs) { + _cost_arcs = new CostArcMap(*_digraph); + } + if (!_heap_cross_ref) { + _heap_cross_ref = new HeapCrossRef(*_digraph, -1); + } + if (!_heap) { + _heap = new Heap(*_heap_cross_ref); + } + } + + void destroyStructures() { + if (local_arborescence) { + delete _arborescence; + } + if (local_pred) { + delete _pred; + } + if (_arc_order) { + delete _arc_order; + } + if (_node_order) { + delete _node_order; + } + if (_cost_arcs) { + delete _cost_arcs; + } + if (_heap) { + delete _heap; + } + if (_heap_cross_ref) { + delete _heap_cross_ref; + } + } + + Arc prepare(Node node) { + std::vector nodes; + (*_node_order)[node] = _dual_node_list.size(); + StackLevel level; + level.node_level = _dual_node_list.size(); + _dual_node_list.push_back(node); + for (InArcIt it(*_digraph, node); it != INVALID; ++it) { + Arc arc = it; + Node source = _digraph->source(arc); + Value value = (*_cost)[it]; + if (source == node || (*_node_order)[source] == -3) continue; + if ((*_cost_arcs)[source].arc == INVALID) { + (*_cost_arcs)[source].arc = arc; + (*_cost_arcs)[source].value = value; + nodes.push_back(source); + } else { + if ((*_cost_arcs)[source].value > value) { + (*_cost_arcs)[source].arc = arc; + (*_cost_arcs)[source].value = value; + } + } + } + CostArc minimum = (*_cost_arcs)[nodes[0]]; + for (int i = 1; i < int(nodes.size()); ++i) { + if ((*_cost_arcs)[nodes[i]].value < minimum.value) { + minimum = (*_cost_arcs)[nodes[i]]; + } + } + (*_arc_order)[minimum.arc] = _dual_variables.size(); + DualVariable var(_dual_node_list.size() - 1, + _dual_node_list.size(), minimum.value); + _dual_variables.push_back(var); + for (int i = 0; i < int(nodes.size()); ++i) { + (*_cost_arcs)[nodes[i]].value -= minimum.value; + level.arcs.push_back((*_cost_arcs)[nodes[i]]); + (*_cost_arcs)[nodes[i]].arc = INVALID; + } + level_stack.push_back(level); + return minimum.arc; + } + + Arc contract(Node node) { + int node_bottom = bottom(node); + std::vector nodes; + while (!level_stack.empty() && + level_stack.back().node_level >= node_bottom) { + for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) { + Arc arc = level_stack.back().arcs[i].arc; + Node source = _digraph->source(arc); + Value value = level_stack.back().arcs[i].value; + if ((*_node_order)[source] >= node_bottom) continue; + if ((*_cost_arcs)[source].arc == INVALID) { + (*_cost_arcs)[source].arc = arc; + (*_cost_arcs)[source].value = value; + nodes.push_back(source); + } else { + if ((*_cost_arcs)[source].value > value) { + (*_cost_arcs)[source].arc = arc; + (*_cost_arcs)[source].value = value; + } + } + } + level_stack.pop_back(); + } + CostArc minimum = (*_cost_arcs)[nodes[0]]; + for (int i = 1; i < int(nodes.size()); ++i) { + if ((*_cost_arcs)[nodes[i]].value < minimum.value) { + minimum = (*_cost_arcs)[nodes[i]]; + } + } + (*_arc_order)[minimum.arc] = _dual_variables.size(); + DualVariable var(node_bottom, _dual_node_list.size(), minimum.value); + _dual_variables.push_back(var); + StackLevel level; + level.node_level = node_bottom; + for (int i = 0; i < int(nodes.size()); ++i) { + (*_cost_arcs)[nodes[i]].value -= minimum.value; + level.arcs.push_back((*_cost_arcs)[nodes[i]]); + (*_cost_arcs)[nodes[i]].arc = INVALID; + } + level_stack.push_back(level); + return minimum.arc; + } + + int bottom(Node node) { + int k = level_stack.size() - 1; + while (level_stack[k].node_level > (*_node_order)[node]) { + --k; + } + return level_stack[k].node_level; + } + + void finalize(Arc arc) { + Node node = _digraph->target(arc); + _heap->push(node, (*_arc_order)[arc]); + _pred->set(node, arc); + while (!_heap->empty()) { + Node source = _heap->top(); + _heap->pop(); + (*_node_order)[source] = -1; + for (OutArcIt it(*_digraph, source); it != INVALID; ++it) { + if ((*_arc_order)[it] < 0) continue; + Node target = _digraph->target(it); + switch(_heap->state(target)) { + case Heap::PRE_HEAP: + _heap->push(target, (*_arc_order)[it]); + _pred->set(target, it); + break; + case Heap::IN_HEAP: + if ((*_arc_order)[it] < (*_heap)[target]) { + _heap->decrease(target, (*_arc_order)[it]); + _pred->set(target, it); + } + break; + case Heap::POST_HEAP: + break; + } + } + _arborescence->set((*_pred)[source], true); + } + } + + + public: + + /// \name Named Template Parameters + + /// @{ + + template + struct SetArborescenceMapTraits : public Traits { + typedef T ArborescenceMap; + static ArborescenceMap *createArborescenceMap(const Digraph &) + { + LEMON_ASSERT(false, "ArborescenceMap is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for + /// setting \c ArborescenceMap type + /// + /// \ref named-templ-param "Named parameter" for setting + /// \c ArborescenceMap type. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept, + /// and its value type must be \c bool (or convertible). + /// Initially it will be set to \c false on each arc, + /// then it will be set on each arborescence arc once. + template + struct SetArborescenceMap + : public MinCostArborescence > { + }; + + template + struct SetPredMapTraits : public Traits { + typedef T PredMap; + static PredMap *createPredMap(const Digraph &) + { + LEMON_ASSERT(false, "PredMap is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for + /// setting \c PredMap type + /// + /// \ref named-templ-param "Named parameter" for setting + /// \c PredMap type. + /// It must meet the \ref concepts::WriteMap "WriteMap" concept, + /// and its value type must be the \c Arc type of the digraph. + template + struct SetPredMap + : public MinCostArborescence > { + }; + + /// @} + + /// \brief Constructor. + /// + /// \param digraph The digraph the algorithm will run on. + /// \param cost The cost map used by the algorithm. + MinCostArborescence(const Digraph& digraph, const CostMap& cost) + : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false), + _arborescence(0), local_arborescence(false), + _arc_order(0), _node_order(0), _cost_arcs(0), + _heap_cross_ref(0), _heap(0) {} + + /// \brief Destructor. + ~MinCostArborescence() { + destroyStructures(); + } + + /// \brief Sets the arborescence map. + /// + /// Sets the arborescence map. + /// \return (*this) + MinCostArborescence& arborescenceMap(ArborescenceMap& m) { + if (local_arborescence) { + delete _arborescence; + } + local_arborescence = false; + _arborescence = &m; + return *this; + } + + /// \brief Sets the predecessor map. + /// + /// Sets the predecessor map. + /// \return (*this) + MinCostArborescence& predMap(PredMap& m) { + if (local_pred) { + delete _pred; + } + local_pred = false; + _pred = &m; + return *this; + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to use + /// one of the member functions called \c run(...). \n + /// If you need better control on the execution, + /// you have to call \ref init() first, then you can add several + /// source nodes with \ref addSource(). + /// Finally \ref start() will perform the arborescence + /// computation. + + ///@{ + + /// \brief Initializes the internal data structures. + /// + /// Initializes the internal data structures. + /// + void init() { + createStructures(); + _heap->clear(); + for (NodeIt it(*_digraph); it != INVALID; ++it) { + (*_cost_arcs)[it].arc = INVALID; + (*_node_order)[it] = -3; + (*_heap_cross_ref)[it] = Heap::PRE_HEAP; + _pred->set(it, INVALID); + } + for (ArcIt it(*_digraph); it != INVALID; ++it) { + _arborescence->set(it, false); + (*_arc_order)[it] = -1; + } + _dual_node_list.clear(); + _dual_variables.clear(); + } + + /// \brief Adds a new source node. + /// + /// Adds a new source node to the algorithm. + void addSource(Node source) { + std::vector nodes; + nodes.push_back(source); + while (!nodes.empty()) { + Node node = nodes.back(); + nodes.pop_back(); + for (OutArcIt it(*_digraph, node); it != INVALID; ++it) { + Node target = _digraph->target(it); + if ((*_node_order)[target] == -3) { + (*_node_order)[target] = -2; + nodes.push_back(target); + queue.push_back(target); + } + } + } + (*_node_order)[source] = -1; + } + + /// \brief Processes the next node in the priority queue. + /// + /// Processes the next node in the priority queue. + /// + /// \return The processed node. + /// + /// \warning The queue must not be empty. + Node processNextNode() { + Node node = queue.back(); + queue.pop_back(); + if ((*_node_order)[node] == -2) { + Arc arc = prepare(node); + Node source = _digraph->source(arc); + while ((*_node_order)[source] != -1) { + if ((*_node_order)[source] >= 0) { + arc = contract(source); + } else { + arc = prepare(source); + } + source = _digraph->source(arc); + } + finalize(arc); + level_stack.clear(); + } + return node; + } + + /// \brief Returns the number of the nodes to be processed. + /// + /// Returns the number of the nodes to be processed in the priority + /// queue. + int queueSize() const { + return queue.size(); + } + + /// \brief Returns \c false if there are nodes to be processed. + /// + /// Returns \c false if there are nodes to be processed. + bool emptyQueue() const { + return queue.empty(); + } + + /// \brief Executes the algorithm. + /// + /// Executes the algorithm. + /// + /// \pre init() must be called and at least one node should be added + /// with addSource() before using this function. + /// + ///\note mca.start() is just a shortcut of the following code. + ///\code + ///while (!mca.emptyQueue()) { + /// mca.processNextNode(); + ///} + ///\endcode + void start() { + while (!emptyQueue()) { + processNextNode(); + } + } + + /// \brief Runs %MinCostArborescence algorithm from node \c s. + /// + /// This method runs the %MinCostArborescence algorithm from + /// a root node \c s. + /// + /// \note mca.run(s) is just a shortcut of the following code. + /// \code + /// mca.init(); + /// mca.addSource(s); + /// mca.start(); + /// \endcode + void run(Node s) { + init(); + addSource(s); + start(); + } + + ///@} + + /// \name Query Functions + /// The result of the %MinCostArborescence algorithm can be obtained + /// using these functions.\n + /// Either run() or start() must be called before using them. + + /// @{ + + /// \brief Returns the cost of the arborescence. + /// + /// Returns the cost of the arborescence. + Value arborescenceCost() const { + Value sum = 0; + for (ArcIt it(*_digraph); it != INVALID; ++it) { + if (arborescence(it)) { + sum += (*_cost)[it]; + } + } + return sum; + } + + /// \brief Returns \c true if the arc is in the arborescence. + /// + /// Returns \c true if the given arc is in the arborescence. + /// \param arc An arc of the digraph. + /// \pre \ref run() must be called before using this function. + bool arborescence(Arc arc) const { + return (*_pred)[_digraph->target(arc)] == arc; + } + + /// \brief Returns a const reference to the arborescence map. + /// + /// Returns a const reference to the arborescence map. + /// \pre \ref run() must be called before using this function. + const ArborescenceMap& arborescenceMap() const { + return *_arborescence; + } + + /// \brief Returns the predecessor arc of the given node. + /// + /// Returns the predecessor arc of the given node. + /// \pre \ref run() must be called before using this function. + Arc pred(Node node) const { + return (*_pred)[node]; + } + + /// \brief Returns a const reference to the pred map. + /// + /// Returns a const reference to the pred map. + /// \pre \ref run() must be called before using this function. + const PredMap& predMap() const { + return *_pred; + } + + /// \brief Indicates that a node is reachable from the sources. + /// + /// Indicates that a node is reachable from the sources. + bool reached(Node node) const { + return (*_node_order)[node] != -3; + } + + /// \brief Indicates that a node is processed. + /// + /// Indicates that a node is processed. The arborescence path exists + /// from the source to the given node. + bool processed(Node node) const { + return (*_node_order)[node] == -1; + } + + /// \brief Returns the number of the dual variables in basis. + /// + /// Returns the number of the dual variables in basis. + int dualNum() const { + return _dual_variables.size(); + } + + /// \brief Returns the value of the dual solution. + /// + /// Returns the value of the dual solution. It should be + /// equal to the arborescence value. + Value dualValue() const { + Value sum = 0; + for (int i = 0; i < int(_dual_variables.size()); ++i) { + sum += _dual_variables[i].value; + } + return sum; + } + + /// \brief Returns the number of the nodes in the dual variable. + /// + /// Returns the number of the nodes in the dual variable. + int dualSize(int k) const { + return _dual_variables[k].end - _dual_variables[k].begin; + } + + /// \brief Returns the value of the dual variable. + /// + /// Returns the the value of the dual variable. + Value dualValue(int k) const { + return _dual_variables[k].value; + } + + /// \brief LEMON iterator for getting a dual variable. + /// + /// This class provides a common style LEMON iterator for getting a + /// dual variable of \ref MinCostArborescence algorithm. + /// It iterates over a subset of the nodes. + class DualIt { + public: + + /// \brief Constructor. + /// + /// Constructor for getting the nodeset of the dual variable + /// of \ref MinCostArborescence algorithm. + DualIt(const MinCostArborescence& algorithm, int variable) + : _algorithm(&algorithm) + { + _index = _algorithm->_dual_variables[variable].begin; + _last = _algorithm->_dual_variables[variable].end; + } + + /// \brief Conversion to \c Node. + /// + /// Conversion to \c Node. + operator Node() const { + return _algorithm->_dual_node_list[_index]; + } + + /// \brief Increment operator. + /// + /// Increment operator. + DualIt& operator++() { + ++_index; + return *this; + } + + /// \brief Validity checking + /// + /// Checks whether the iterator is invalid. + bool operator==(Invalid) const { + return _index == _last; + } + + /// \brief Validity checking + /// + /// Checks whether the iterator is valid. + bool operator!=(Invalid) const { + return _index != _last; + } + + private: + const MinCostArborescence* _algorithm; + int _index, _last; + }; + + /// @} + + }; + + /// \ingroup spantree + /// + /// \brief Function type interface for MinCostArborescence algorithm. + /// + /// Function type interface for MinCostArborescence algorithm. + /// \param digraph The digraph the algorithm runs on. + /// \param cost An arc map storing the costs. + /// \param source The source node of the arborescence. + /// \retval arborescence An arc map with \c bool (or convertible) value + /// type that stores the arborescence. + /// \return The total cost of the arborescence. + /// + /// \sa MinCostArborescence + template + typename CostMap::Value minCostArborescence(const Digraph& digraph, + const CostMap& cost, + typename Digraph::Node source, + ArborescenceMap& arborescence) { + typename MinCostArborescence + ::template SetArborescenceMap + ::Create mca(digraph, cost); + mca.arborescenceMap(arborescence); + mca.run(source); + return mca.arborescenceCost(); + } + +} + +#endif diff --git a/lemon/lemon/nauty_reader.h b/lemon/lemon/nauty_reader.h new file mode 100644 index 0000000..896f2a6 --- /dev/null +++ b/lemon/lemon/nauty_reader.h @@ -0,0 +1,113 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_NAUTY_READER_H +#define LEMON_NAUTY_READER_H + +#include +#include +#include + +/// \ingroup nauty_group +/// \file +/// \brief Nauty file reader. + +namespace lemon { + + /// \ingroup nauty_group + /// + /// \brief Nauty file reader + /// + /// The \e geng program is in the \e gtools suite of the nauty + /// package. This tool can generate all non-isomorphic undirected + /// graphs of several classes with given node number (e.g. + /// general, connected, biconnected, triangle-free, 4-cycle-free, + /// bipartite and graphs with given edge number and degree + /// constraints). This function reads a \e nauty \e graph6 \e format + /// line from the given stream and builds it in the given graph. + /// + /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/ + /// + /// For example, the number of all non-isomorphic planar graphs + /// can be computed with the following code. + ///\code + /// int num = 0; + /// SmartGraph graph; + /// while (readNautyGraph(graph, std::cin)) { + /// PlanarityChecking pc(graph); + /// if (pc.run()) ++num; + /// } + /// std::cout << "Number of planar graphs: " << num << std::endl; + ///\endcode + /// + /// The nauty files are quite huge, therefore instead of the direct + /// file generation pipelining is recommended. For example, + ///\code + /// ./geng -c 10 | ./num_of_planar_graphs + ///\endcode + template + std::istream& readNautyGraph(Graph& graph, std::istream& is = std::cin) { + graph.clear(); + + std::string line; + if (getline(is, line)) { + int index = 0; + + int n; + + if (line[index] == '>') { + index += 10; + } + + char c = line[index++]; c -= 63; + if (c != 63) { + n = int(c); + } else { + c = line[index++]; c -= 63; + n = (int(c) << 12); + c = line[index++]; c -= 63; + n |= (int(c) << 6); + c = line[index++]; c -= 63; + n |= int(c); + } + + std::vector nodes; + for (int i = 0; i < n; ++i) { + nodes.push_back(graph.addNode()); + } + + int bit = -1; + for (int j = 0; j < n; ++j) { + for (int i = 0; i < j; ++i) { + if (bit == -1) { + c = line[index++]; c -= 63; + bit = 5; + } + bool b = (c & (1 << (bit--))) != 0; + + if (b) { + graph.addEdge(nodes[i], nodes[j]); + } + } + } + } + return is; + } +} + +#endif diff --git a/lemon/lemon/network_simplex.h b/lemon/lemon/network_simplex.h new file mode 100644 index 0000000..5c029bf --- /dev/null +++ b/lemon/lemon/network_simplex.h @@ -0,0 +1,1621 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_NETWORK_SIMPLEX_H +#define LEMON_NETWORK_SIMPLEX_H + +/// \ingroup min_cost_flow_algs +/// +/// \file +/// \brief Network Simplex algorithm for finding a minimum cost flow. + +#include +#include +#include + +#include +#include + +namespace lemon { + + /// \addtogroup min_cost_flow_algs + /// @{ + + /// \brief Implementation of the primal Network Simplex algorithm + /// for finding a \ref min_cost_flow "minimum cost flow". + /// + /// \ref NetworkSimplex implements the primal Network Simplex algorithm + /// for finding a \ref min_cost_flow "minimum cost flow" + /// \ref amo93networkflows, \ref dantzig63linearprog, + /// \ref kellyoneill91netsimplex. + /// This algorithm is a highly efficient specialized version of the + /// linear programming simplex method directly for the minimum cost + /// flow problem. + /// + /// In general, %NetworkSimplex is the fastest implementation available + /// in LEMON for this problem. + /// Moreover, it supports both directions of the supply/demand inequality + /// constraints. For more information, see \ref SupplyType. + /// + /// Most of the parameters of the problem (except for the digraph) + /// can be given using separate functions, and the algorithm can be + /// executed using the \ref run() function. If some parameters are not + /// specified, then default values will be used. + /// + /// \tparam GR The digraph type the algorithm runs on. + /// \tparam V The number type used for flow amounts, capacity bounds + /// and supply values in the algorithm. By default, it is \c int. + /// \tparam C The number type used for costs and potentials in the + /// algorithm. By default, it is the same as \c V. + /// + /// \warning Both number types must be signed and all input data must + /// be integer. + /// + /// \note %NetworkSimplex provides five different pivot rule + /// implementations, from which the most efficient one is used + /// by default. For more information, see \ref PivotRule. + template + class NetworkSimplex + { + public: + + /// The type of the flow amounts, capacity bounds and supply values + typedef V Value; + /// The type of the arc costs + typedef C Cost; + + public: + + /// \brief Problem type constants for the \c run() function. + /// + /// Enum type containing the problem type constants that can be + /// returned by the \ref run() function of the algorithm. + enum ProblemType { + /// The problem has no feasible solution (flow). + INFEASIBLE, + /// The problem has optimal solution (i.e. it is feasible and + /// bounded), and the algorithm has found optimal flow and node + /// potentials (primal and dual solutions). + OPTIMAL, + /// The objective function of the problem is unbounded, i.e. + /// there is a directed cycle having negative total cost and + /// infinite upper bound. + UNBOUNDED + }; + + /// \brief Constants for selecting the type of the supply constraints. + /// + /// Enum type containing constants for selecting the supply type, + /// i.e. the direction of the inequalities in the supply/demand + /// constraints of the \ref min_cost_flow "minimum cost flow problem". + /// + /// The default supply type is \c GEQ, the \c LEQ type can be + /// selected using \ref supplyType(). + /// The equality form is a special case of both supply types. + enum SupplyType { + /// This option means that there are "greater or equal" + /// supply/demand constraints in the definition of the problem. + GEQ, + /// This option means that there are "less or equal" + /// supply/demand constraints in the definition of the problem. + LEQ + }; + + /// \brief Constants for selecting the pivot rule. + /// + /// Enum type containing constants for selecting the pivot rule for + /// the \ref run() function. + /// + /// \ref NetworkSimplex provides five different pivot rule + /// implementations that significantly affect the running time + /// of the algorithm. + /// By default, \ref BLOCK_SEARCH "Block Search" is used, which + /// proved to be the most efficient and the most robust on various + /// test inputs. + /// However, another pivot rule can be selected using the \ref run() + /// function with the proper parameter. + enum PivotRule { + + /// The \e First \e Eligible pivot rule. + /// The next eligible arc is selected in a wraparound fashion + /// in every iteration. + FIRST_ELIGIBLE, + + /// The \e Best \e Eligible pivot rule. + /// The best eligible arc is selected in every iteration. + BEST_ELIGIBLE, + + /// The \e Block \e Search pivot rule. + /// A specified number of arcs are examined in every iteration + /// in a wraparound fashion and the best eligible arc is selected + /// from this block. + BLOCK_SEARCH, + + /// The \e Candidate \e List pivot rule. + /// In a major iteration a candidate list is built from eligible arcs + /// in a wraparound fashion and in the following minor iterations + /// the best eligible arc is selected from this list. + CANDIDATE_LIST, + + /// The \e Altering \e Candidate \e List pivot rule. + /// It is a modified version of the Candidate List method. + /// It keeps only the several best eligible arcs from the former + /// candidate list and extends this list in every iteration. + ALTERING_LIST + }; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + typedef std::vector IntVector; + typedef std::vector ValueVector; + typedef std::vector CostVector; + typedef std::vector BoolVector; + // Note: vector is used instead of vector for efficiency reasons + + // State constants for arcs + enum ArcState { + STATE_UPPER = -1, + STATE_TREE = 0, + STATE_LOWER = 1 + }; + + typedef std::vector StateVector; + // Note: vector is used instead of vector for + // efficiency reasons + + private: + + // Data related to the underlying digraph + const GR &_graph; + int _node_num; + int _arc_num; + int _all_arc_num; + int _search_arc_num; + + // Parameters of the problem + bool _have_lower; + SupplyType _stype; + Value _sum_supply; + + // Data structures for storing the digraph + IntNodeMap _node_id; + IntArcMap _arc_id; + IntVector _source; + IntVector _target; + bool _arc_mixing; + + // Node and arc data + ValueVector _lower; + ValueVector _upper; + ValueVector _cap; + CostVector _cost; + ValueVector _supply; + ValueVector _flow; + CostVector _pi; + + // Data for storing the spanning tree structure + IntVector _parent; + IntVector _pred; + IntVector _thread; + IntVector _rev_thread; + IntVector _succ_num; + IntVector _last_succ; + IntVector _dirty_revs; + BoolVector _forward; + StateVector _state; + int _root; + + // Temporary data used in the current pivot iteration + int in_arc, join, u_in, v_in, u_out, v_out; + int first, second, right, last; + int stem, par_stem, new_stem; + Value delta; + + const Value MAX; + + public: + + /// \brief Constant for infinite upper bounds (capacities). + /// + /// Constant for infinite upper bounds (capacities). + /// It is \c std::numeric_limits::infinity() if available, + /// \c std::numeric_limits::max() otherwise. + const Value INF; + + private: + + // Implementation of the First Eligible pivot rule + class FirstEligiblePivotRule + { + private: + + // References to the NetworkSimplex class + const IntVector &_source; + const IntVector &_target; + const CostVector &_cost; + const StateVector &_state; + const CostVector &_pi; + int &_in_arc; + int _search_arc_num; + + // Pivot rule data + int _next_arc; + + public: + + // Constructor + FirstEligiblePivotRule(NetworkSimplex &ns) : + _source(ns._source), _target(ns._target), + _cost(ns._cost), _state(ns._state), _pi(ns._pi), + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num), + _next_arc(0) + {} + + // Find next entering arc + bool findEnteringArc() { + Cost c; + for (int e = _next_arc; e != _search_arc_num; ++e) { + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < 0) { + _in_arc = e; + _next_arc = e + 1; + return true; + } + } + for (int e = 0; e != _next_arc; ++e) { + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < 0) { + _in_arc = e; + _next_arc = e + 1; + return true; + } + } + return false; + } + + }; //class FirstEligiblePivotRule + + + // Implementation of the Best Eligible pivot rule + class BestEligiblePivotRule + { + private: + + // References to the NetworkSimplex class + const IntVector &_source; + const IntVector &_target; + const CostVector &_cost; + const StateVector &_state; + const CostVector &_pi; + int &_in_arc; + int _search_arc_num; + + public: + + // Constructor + BestEligiblePivotRule(NetworkSimplex &ns) : + _source(ns._source), _target(ns._target), + _cost(ns._cost), _state(ns._state), _pi(ns._pi), + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num) + {} + + // Find next entering arc + bool findEnteringArc() { + Cost c, min = 0; + for (int e = 0; e != _search_arc_num; ++e) { + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < min) { + min = c; + _in_arc = e; + } + } + return min < 0; + } + + }; //class BestEligiblePivotRule + + + // Implementation of the Block Search pivot rule + class BlockSearchPivotRule + { + private: + + // References to the NetworkSimplex class + const IntVector &_source; + const IntVector &_target; + const CostVector &_cost; + const StateVector &_state; + const CostVector &_pi; + int &_in_arc; + int _search_arc_num; + + // Pivot rule data + int _block_size; + int _next_arc; + + public: + + // Constructor + BlockSearchPivotRule(NetworkSimplex &ns) : + _source(ns._source), _target(ns._target), + _cost(ns._cost), _state(ns._state), _pi(ns._pi), + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num), + _next_arc(0) + { + // The main parameters of the pivot rule + const double BLOCK_SIZE_FACTOR = 1.0; + const int MIN_BLOCK_SIZE = 10; + + _block_size = std::max( int(BLOCK_SIZE_FACTOR * + std::sqrt(double(_search_arc_num))), + MIN_BLOCK_SIZE ); + } + + // Find next entering arc + bool findEnteringArc() { + Cost c, min = 0; + int cnt = _block_size; + int e; + for (e = _next_arc; e != _search_arc_num; ++e) { + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < min) { + min = c; + _in_arc = e; + } + if (--cnt == 0) { + if (min < 0) goto search_end; + cnt = _block_size; + } + } + for (e = 0; e != _next_arc; ++e) { + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < min) { + min = c; + _in_arc = e; + } + if (--cnt == 0) { + if (min < 0) goto search_end; + cnt = _block_size; + } + } + if (min >= 0) return false; + + search_end: + _next_arc = e; + return true; + } + + }; //class BlockSearchPivotRule + + + // Implementation of the Candidate List pivot rule + class CandidateListPivotRule + { + private: + + // References to the NetworkSimplex class + const IntVector &_source; + const IntVector &_target; + const CostVector &_cost; + const StateVector &_state; + const CostVector &_pi; + int &_in_arc; + int _search_arc_num; + + // Pivot rule data + IntVector _candidates; + int _list_length, _minor_limit; + int _curr_length, _minor_count; + int _next_arc; + + public: + + /// Constructor + CandidateListPivotRule(NetworkSimplex &ns) : + _source(ns._source), _target(ns._target), + _cost(ns._cost), _state(ns._state), _pi(ns._pi), + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num), + _next_arc(0) + { + // The main parameters of the pivot rule + const double LIST_LENGTH_FACTOR = 0.25; + const int MIN_LIST_LENGTH = 10; + const double MINOR_LIMIT_FACTOR = 0.1; + const int MIN_MINOR_LIMIT = 3; + + _list_length = std::max( int(LIST_LENGTH_FACTOR * + std::sqrt(double(_search_arc_num))), + MIN_LIST_LENGTH ); + _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length), + MIN_MINOR_LIMIT ); + _curr_length = _minor_count = 0; + _candidates.resize(_list_length); + } + + /// Find next entering arc + bool findEnteringArc() { + Cost min, c; + int e; + if (_curr_length > 0 && _minor_count < _minor_limit) { + // Minor iteration: select the best eligible arc from the + // current candidate list + ++_minor_count; + min = 0; + for (int i = 0; i < _curr_length; ++i) { + e = _candidates[i]; + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < min) { + min = c; + _in_arc = e; + } + else if (c >= 0) { + _candidates[i--] = _candidates[--_curr_length]; + } + } + if (min < 0) return true; + } + + // Major iteration: build a new candidate list + min = 0; + _curr_length = 0; + for (e = _next_arc; e != _search_arc_num; ++e) { + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < 0) { + _candidates[_curr_length++] = e; + if (c < min) { + min = c; + _in_arc = e; + } + if (_curr_length == _list_length) goto search_end; + } + } + for (e = 0; e != _next_arc; ++e) { + c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (c < 0) { + _candidates[_curr_length++] = e; + if (c < min) { + min = c; + _in_arc = e; + } + if (_curr_length == _list_length) goto search_end; + } + } + if (_curr_length == 0) return false; + + search_end: + _minor_count = 1; + _next_arc = e; + return true; + } + + }; //class CandidateListPivotRule + + + // Implementation of the Altering Candidate List pivot rule + class AlteringListPivotRule + { + private: + + // References to the NetworkSimplex class + const IntVector &_source; + const IntVector &_target; + const CostVector &_cost; + const StateVector &_state; + const CostVector &_pi; + int &_in_arc; + int _search_arc_num; + + // Pivot rule data + int _block_size, _head_length, _curr_length; + int _next_arc; + IntVector _candidates; + CostVector _cand_cost; + + // Functor class to compare arcs during sort of the candidate list + class SortFunc + { + private: + const CostVector &_map; + public: + SortFunc(const CostVector &map) : _map(map) {} + bool operator()(int left, int right) { + return _map[left] > _map[right]; + } + }; + + SortFunc _sort_func; + + public: + + // Constructor + AlteringListPivotRule(NetworkSimplex &ns) : + _source(ns._source), _target(ns._target), + _cost(ns._cost), _state(ns._state), _pi(ns._pi), + _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num), + _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost) + { + // The main parameters of the pivot rule + const double BLOCK_SIZE_FACTOR = 1.0; + const int MIN_BLOCK_SIZE = 10; + const double HEAD_LENGTH_FACTOR = 0.1; + const int MIN_HEAD_LENGTH = 3; + + _block_size = std::max( int(BLOCK_SIZE_FACTOR * + std::sqrt(double(_search_arc_num))), + MIN_BLOCK_SIZE ); + _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size), + MIN_HEAD_LENGTH ); + _candidates.resize(_head_length + _block_size); + _curr_length = 0; + } + + // Find next entering arc + bool findEnteringArc() { + // Check the current candidate list + int e; + for (int i = 0; i != _curr_length; ++i) { + e = _candidates[i]; + _cand_cost[e] = _state[e] * + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (_cand_cost[e] >= 0) { + _candidates[i--] = _candidates[--_curr_length]; + } + } + + // Extend the list + int cnt = _block_size; + int limit = _head_length; + + for (e = _next_arc; e != _search_arc_num; ++e) { + _cand_cost[e] = _state[e] * + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (_cand_cost[e] < 0) { + _candidates[_curr_length++] = e; + } + if (--cnt == 0) { + if (_curr_length > limit) goto search_end; + limit = 0; + cnt = _block_size; + } + } + for (e = 0; e != _next_arc; ++e) { + _cand_cost[e] = _state[e] * + (_cost[e] + _pi[_source[e]] - _pi[_target[e]]); + if (_cand_cost[e] < 0) { + _candidates[_curr_length++] = e; + } + if (--cnt == 0) { + if (_curr_length > limit) goto search_end; + limit = 0; + cnt = _block_size; + } + } + if (_curr_length == 0) return false; + + search_end: + + // Make heap of the candidate list (approximating a partial sort) + make_heap( _candidates.begin(), _candidates.begin() + _curr_length, + _sort_func ); + + // Pop the first element of the heap + _in_arc = _candidates[0]; + _next_arc = e; + pop_heap( _candidates.begin(), _candidates.begin() + _curr_length, + _sort_func ); + _curr_length = std::min(_head_length, _curr_length - 1); + return true; + } + + }; //class AlteringListPivotRule + + public: + + /// \brief Constructor. + /// + /// The constructor of the class. + /// + /// \param graph The digraph the algorithm runs on. + /// \param arc_mixing Indicate if the arcs have to be stored in a + /// mixed order in the internal data structure. + /// In special cases, it could lead to better overall performance, + /// but it is usually slower. Therefore it is disabled by default. + NetworkSimplex(const GR& graph, bool arc_mixing = false) : + _graph(graph), _node_id(graph), _arc_id(graph), + _arc_mixing(arc_mixing), + MAX(std::numeric_limits::max()), + INF(std::numeric_limits::has_infinity ? + std::numeric_limits::infinity() : MAX) + { + // Check the number types + LEMON_ASSERT(std::numeric_limits::is_signed, + "The flow type of NetworkSimplex must be signed"); + LEMON_ASSERT(std::numeric_limits::is_signed, + "The cost type of NetworkSimplex must be signed"); + + // Reset data structures + reset(); + } + + /// \name Parameters + /// The parameters of the algorithm can be specified using these + /// functions. + + /// @{ + + /// \brief Set the lower bounds on the arcs. + /// + /// This function sets the lower bounds on the arcs. + /// If it is not used before calling \ref run(), the lower bounds + /// will be set to zero on all arcs. + /// + /// \param map An arc map storing the lower bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + NetworkSimplex& lowerMap(const LowerMap& map) { + _have_lower = true; + for (ArcIt a(_graph); a != INVALID; ++a) { + _lower[_arc_id[a]] = map[a]; + } + return *this; + } + + /// \brief Set the upper bounds (capacities) on the arcs. + /// + /// This function sets the upper bounds (capacities) on the arcs. + /// If it is not used before calling \ref run(), the upper bounds + /// will be set to \ref INF on all arcs (i.e. the flow value will be + /// unbounded from above). + /// + /// \param map An arc map storing the upper bounds. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + NetworkSimplex& upperMap(const UpperMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _upper[_arc_id[a]] = map[a]; + } + return *this; + } + + /// \brief Set the costs of the arcs. + /// + /// This function sets the costs of the arcs. + /// If it is not used before calling \ref run(), the costs + /// will be set to \c 1 on all arcs. + /// + /// \param map An arc map storing the costs. + /// Its \c Value type must be convertible to the \c Cost type + /// of the algorithm. + /// + /// \return (*this) + template + NetworkSimplex& costMap(const CostMap& map) { + for (ArcIt a(_graph); a != INVALID; ++a) { + _cost[_arc_id[a]] = map[a]; + } + return *this; + } + + /// \brief Set the supply values of the nodes. + /// + /// This function sets the supply values of the nodes. + /// If neither this function nor \ref stSupply() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// \param map A node map storing the supply values. + /// Its \c Value type must be convertible to the \c Value type + /// of the algorithm. + /// + /// \return (*this) + template + NetworkSimplex& supplyMap(const SupplyMap& map) { + for (NodeIt n(_graph); n != INVALID; ++n) { + _supply[_node_id[n]] = map[n]; + } + return *this; + } + + /// \brief Set single source and target nodes and a supply value. + /// + /// This function sets a single source node and a single target node + /// and the required flow value. + /// If neither this function nor \ref supplyMap() is used before + /// calling \ref run(), the supply of each node will be set to zero. + /// + /// Using this function has the same effect as using \ref supplyMap() + /// with such a map in which \c k is assigned to \c s, \c -k is + /// assigned to \c t and all other nodes have zero supply value. + /// + /// \param s The source node. + /// \param t The target node. + /// \param k The required amount of flow from node \c s to node \c t + /// (i.e. the supply of \c s and the demand of \c t). + /// + /// \return (*this) + NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) { + for (int i = 0; i != _node_num; ++i) { + _supply[i] = 0; + } + _supply[_node_id[s]] = k; + _supply[_node_id[t]] = -k; + return *this; + } + + /// \brief Set the type of the supply constraints. + /// + /// This function sets the type of the supply/demand constraints. + /// If it is not used before calling \ref run(), the \ref GEQ supply + /// type will be used. + /// + /// For more information, see \ref SupplyType. + /// + /// \return (*this) + NetworkSimplex& supplyType(SupplyType supply_type) { + _stype = supply_type; + return *this; + } + + /// @} + + /// \name Execution Control + /// The algorithm can be executed using \ref run(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// The paramters can be specified using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), + /// \ref supplyType(). + /// For example, + /// \code + /// NetworkSimplex ns(graph); + /// ns.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// This function can be called more than once. All the given parameters + /// are kept for the next call, unless \ref resetParams() or \ref reset() + /// is used, thus only the modified parameters have to be set again. + /// If the underlying digraph was also modified after the construction + /// of the class (or the last \ref reset() call), then the \ref reset() + /// function must be called. + /// + /// \param pivot_rule The pivot rule that will be used during the + /// algorithm. For more information, see \ref PivotRule. + /// + /// \return \c INFEASIBLE if no feasible flow exists, + /// \n \c OPTIMAL if the problem has optimal solution + /// (i.e. it is feasible and bounded), and the algorithm has found + /// optimal flow and node potentials (primal and dual solutions), + /// \n \c UNBOUNDED if the objective function of the problem is + /// unbounded, i.e. there is a directed cycle having negative total + /// cost and infinite upper bound. + /// + /// \see ProblemType, PivotRule + /// \see resetParams(), reset() + ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) { + if (!init()) return INFEASIBLE; + return start(pivot_rule); + } + + /// \brief Reset all the parameters that have been given before. + /// + /// This function resets all the paramaters that have been given + /// before using functions \ref lowerMap(), \ref upperMap(), + /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType(). + /// + /// It is useful for multiple \ref run() calls. Basically, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// For example, + /// \code + /// NetworkSimplex ns(graph); + /// + /// // First run + /// ns.lowerMap(lower).upperMap(upper).costMap(cost) + /// .supplyMap(sup).run(); + /// + /// // Run again with modified cost map (resetParams() is not called, + /// // so only the cost map have to be set again) + /// cost[e] += 100; + /// ns.costMap(cost).run(); + /// + /// // Run again from scratch using resetParams() + /// // (the lower bounds will be set to zero on all arcs) + /// ns.resetParams(); + /// ns.upperMap(capacity).costMap(cost) + /// .supplyMap(sup).run(); + /// \endcode + /// + /// \return (*this) + /// + /// \see reset(), run() + NetworkSimplex& resetParams() { + for (int i = 0; i != _node_num; ++i) { + _supply[i] = 0; + } + for (int i = 0; i != _arc_num; ++i) { + _lower[i] = 0; + _upper[i] = INF; + _cost[i] = 1; + } + _have_lower = false; + _stype = GEQ; + return *this; + } + + /// \brief Reset the internal data structures and all the parameters + /// that have been given before. + /// + /// This function resets the internal data structures and all the + /// paramaters that have been given before using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), + /// \ref supplyType(). + /// + /// It is useful for multiple \ref run() calls. Basically, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// See \ref resetParams() for examples. + /// + /// \return (*this) + /// + /// \see resetParams(), run() + NetworkSimplex& reset() { + // Resize vectors + _node_num = countNodes(_graph); + _arc_num = countArcs(_graph); + int all_node_num = _node_num + 1; + int max_arc_num = _arc_num + 2 * _node_num; + + _source.resize(max_arc_num); + _target.resize(max_arc_num); + + _lower.resize(_arc_num); + _upper.resize(_arc_num); + _cap.resize(max_arc_num); + _cost.resize(max_arc_num); + _supply.resize(all_node_num); + _flow.resize(max_arc_num); + _pi.resize(all_node_num); + + _parent.resize(all_node_num); + _pred.resize(all_node_num); + _forward.resize(all_node_num); + _thread.resize(all_node_num); + _rev_thread.resize(all_node_num); + _succ_num.resize(all_node_num); + _last_succ.resize(all_node_num); + _state.resize(max_arc_num); + + // Copy the graph + int i = 0; + for (NodeIt n(_graph); n != INVALID; ++n, ++i) { + _node_id[n] = i; + } + if (_arc_mixing) { + // Store the arcs in a mixed order + int k = std::max(int(std::sqrt(double(_arc_num))), 10); + int i = 0, j = 0; + for (ArcIt a(_graph); a != INVALID; ++a) { + _arc_id[a] = i; + _source[i] = _node_id[_graph.source(a)]; + _target[i] = _node_id[_graph.target(a)]; + if ((i += k) >= _arc_num) i = ++j; + } + } else { + // Store the arcs in the original order + int i = 0; + for (ArcIt a(_graph); a != INVALID; ++a, ++i) { + _arc_id[a] = i; + _source[i] = _node_id[_graph.source(a)]; + _target[i] = _node_id[_graph.target(a)]; + } + } + + // Reset parameters + resetParams(); + return *this; + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions.\n + /// The \ref run() function must be called before using them. + + /// @{ + + /// \brief Return the total cost of the found flow. + /// + /// This function returns the total cost of the found flow. + /// Its complexity is O(e). + /// + /// \note The return type of the function can be specified as a + /// template parameter. For example, + /// \code + /// ns.totalCost(); + /// \endcode + /// It is useful if the total cost cannot be stored in the \c Cost + /// type of the algorithm, which is the default return type of the + /// function. + /// + /// \pre \ref run() must be called before using this function. + template + Number totalCost() const { + Number c = 0; + for (ArcIt a(_graph); a != INVALID; ++a) { + int i = _arc_id[a]; + c += Number(_flow[i]) * Number(_cost[i]); + } + return c; + } + +#ifndef DOXYGEN + Cost totalCost() const { + return totalCost(); + } +#endif + + /// \brief Return the flow on the given arc. + /// + /// This function returns the flow on the given arc. + /// + /// \pre \ref run() must be called before using this function. + Value flow(const Arc& a) const { + return _flow[_arc_id[a]]; + } + + /// \brief Return the flow map (the primal solution). + /// + /// This function copies the flow value on each arc into the given + /// map. The \c Value type of the algorithm must be convertible to + /// the \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void flowMap(FlowMap &map) const { + for (ArcIt a(_graph); a != INVALID; ++a) { + map.set(a, _flow[_arc_id[a]]); + } + } + + /// \brief Return the potential (dual value) of the given node. + /// + /// This function returns the potential (dual value) of the + /// given node. + /// + /// \pre \ref run() must be called before using this function. + Cost potential(const Node& n) const { + return _pi[_node_id[n]]; + } + + /// \brief Return the potential map (the dual solution). + /// + /// This function copies the potential (dual value) of each node + /// into the given map. + /// The \c Cost type of the algorithm must be convertible to the + /// \c Value type of the map. + /// + /// \pre \ref run() must be called before using this function. + template + void potentialMap(PotentialMap &map) const { + for (NodeIt n(_graph); n != INVALID; ++n) { + map.set(n, _pi[_node_id[n]]); + } + } + + /// @} + + private: + + // Initialize internal data structures + bool init() { + if (_node_num == 0) return false; + + // Check the sum of supply values + _sum_supply = 0; + for (int i = 0; i != _node_num; ++i) { + _sum_supply += _supply[i]; + } + if ( !((_stype == GEQ && _sum_supply <= 0) || + (_stype == LEQ && _sum_supply >= 0)) ) return false; + + // Remove non-zero lower bounds + if (_have_lower) { + for (int i = 0; i != _arc_num; ++i) { + Value c = _lower[i]; + if (c >= 0) { + _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF; + } else { + _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF; + } + _supply[_source[i]] -= c; + _supply[_target[i]] += c; + } + } else { + for (int i = 0; i != _arc_num; ++i) { + _cap[i] = _upper[i]; + } + } + + // Initialize artifical cost + Cost ART_COST; + if (std::numeric_limits::is_exact) { + ART_COST = std::numeric_limits::max() / 2 + 1; + } else { + ART_COST = 0; + for (int i = 0; i != _arc_num; ++i) { + if (_cost[i] > ART_COST) ART_COST = _cost[i]; + } + ART_COST = (ART_COST + 1) * _node_num; + } + + // Initialize arc maps + for (int i = 0; i != _arc_num; ++i) { + _flow[i] = 0; + _state[i] = STATE_LOWER; + } + + // Set data for the artificial root node + _root = _node_num; + _parent[_root] = -1; + _pred[_root] = -1; + _thread[_root] = 0; + _rev_thread[0] = _root; + _succ_num[_root] = _node_num + 1; + _last_succ[_root] = _root - 1; + _supply[_root] = -_sum_supply; + _pi[_root] = 0; + + // Add artificial arcs and initialize the spanning tree data structure + if (_sum_supply == 0) { + // EQ supply constraints + _search_arc_num = _arc_num; + _all_arc_num = _arc_num + _node_num; + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) { + _parent[u] = _root; + _pred[u] = e; + _thread[u] = u + 1; + _rev_thread[u + 1] = u; + _succ_num[u] = 1; + _last_succ[u] = u; + _cap[e] = INF; + _state[e] = STATE_TREE; + if (_supply[u] >= 0) { + _forward[u] = true; + _pi[u] = 0; + _source[e] = u; + _target[e] = _root; + _flow[e] = _supply[u]; + _cost[e] = 0; + } else { + _forward[u] = false; + _pi[u] = ART_COST; + _source[e] = _root; + _target[e] = u; + _flow[e] = -_supply[u]; + _cost[e] = ART_COST; + } + } + } + else if (_sum_supply > 0) { + // LEQ supply constraints + _search_arc_num = _arc_num + _node_num; + int f = _arc_num + _node_num; + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) { + _parent[u] = _root; + _thread[u] = u + 1; + _rev_thread[u + 1] = u; + _succ_num[u] = 1; + _last_succ[u] = u; + if (_supply[u] >= 0) { + _forward[u] = true; + _pi[u] = 0; + _pred[u] = e; + _source[e] = u; + _target[e] = _root; + _cap[e] = INF; + _flow[e] = _supply[u]; + _cost[e] = 0; + _state[e] = STATE_TREE; + } else { + _forward[u] = false; + _pi[u] = ART_COST; + _pred[u] = f; + _source[f] = _root; + _target[f] = u; + _cap[f] = INF; + _flow[f] = -_supply[u]; + _cost[f] = ART_COST; + _state[f] = STATE_TREE; + _source[e] = u; + _target[e] = _root; + _cap[e] = INF; + _flow[e] = 0; + _cost[e] = 0; + _state[e] = STATE_LOWER; + ++f; + } + } + _all_arc_num = f; + } + else { + // GEQ supply constraints + _search_arc_num = _arc_num + _node_num; + int f = _arc_num + _node_num; + for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) { + _parent[u] = _root; + _thread[u] = u + 1; + _rev_thread[u + 1] = u; + _succ_num[u] = 1; + _last_succ[u] = u; + if (_supply[u] <= 0) { + _forward[u] = false; + _pi[u] = 0; + _pred[u] = e; + _source[e] = _root; + _target[e] = u; + _cap[e] = INF; + _flow[e] = -_supply[u]; + _cost[e] = 0; + _state[e] = STATE_TREE; + } else { + _forward[u] = true; + _pi[u] = -ART_COST; + _pred[u] = f; + _source[f] = u; + _target[f] = _root; + _cap[f] = INF; + _flow[f] = _supply[u]; + _state[f] = STATE_TREE; + _cost[f] = ART_COST; + _source[e] = _root; + _target[e] = u; + _cap[e] = INF; + _flow[e] = 0; + _cost[e] = 0; + _state[e] = STATE_LOWER; + ++f; + } + } + _all_arc_num = f; + } + + return true; + } + + // Find the join node + void findJoinNode() { + int u = _source[in_arc]; + int v = _target[in_arc]; + while (u != v) { + if (_succ_num[u] < _succ_num[v]) { + u = _parent[u]; + } else { + v = _parent[v]; + } + } + join = u; + } + + // Find the leaving arc of the cycle and returns true if the + // leaving arc is not the same as the entering arc + bool findLeavingArc() { + // Initialize first and second nodes according to the direction + // of the cycle + if (_state[in_arc] == STATE_LOWER) { + first = _source[in_arc]; + second = _target[in_arc]; + } else { + first = _target[in_arc]; + second = _source[in_arc]; + } + delta = _cap[in_arc]; + int result = 0; + Value d; + int e; + + // Search the cycle along the path form the first node to the root + for (int u = first; u != join; u = _parent[u]) { + e = _pred[u]; + d = _forward[u] ? + _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]); + if (d < delta) { + delta = d; + u_out = u; + result = 1; + } + } + // Search the cycle along the path form the second node to the root + for (int u = second; u != join; u = _parent[u]) { + e = _pred[u]; + d = _forward[u] ? + (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e]; + if (d <= delta) { + delta = d; + u_out = u; + result = 2; + } + } + + if (result == 1) { + u_in = first; + v_in = second; + } else { + u_in = second; + v_in = first; + } + return result != 0; + } + + // Change _flow and _state vectors + void changeFlow(bool change) { + // Augment along the cycle + if (delta > 0) { + Value val = _state[in_arc] * delta; + _flow[in_arc] += val; + for (int u = _source[in_arc]; u != join; u = _parent[u]) { + _flow[_pred[u]] += _forward[u] ? -val : val; + } + for (int u = _target[in_arc]; u != join; u = _parent[u]) { + _flow[_pred[u]] += _forward[u] ? val : -val; + } + } + // Update the state of the entering and leaving arcs + if (change) { + _state[in_arc] = STATE_TREE; + _state[_pred[u_out]] = + (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER; + } else { + _state[in_arc] = -_state[in_arc]; + } + } + + // Update the tree structure + void updateTreeStructure() { + int u, w; + int old_rev_thread = _rev_thread[u_out]; + int old_succ_num = _succ_num[u_out]; + int old_last_succ = _last_succ[u_out]; + v_out = _parent[u_out]; + + u = _last_succ[u_in]; // the last successor of u_in + right = _thread[u]; // the node after it + + // Handle the case when old_rev_thread equals to v_in + // (it also means that join and v_out coincide) + if (old_rev_thread == v_in) { + last = _thread[_last_succ[u_out]]; + } else { + last = _thread[v_in]; + } + + // Update _thread and _parent along the stem nodes (i.e. the nodes + // between u_in and u_out, whose parent have to be changed) + _thread[v_in] = stem = u_in; + _dirty_revs.clear(); + _dirty_revs.push_back(v_in); + par_stem = v_in; + while (stem != u_out) { + // Insert the next stem node into the thread list + new_stem = _parent[stem]; + _thread[u] = new_stem; + _dirty_revs.push_back(u); + + // Remove the subtree of stem from the thread list + w = _rev_thread[stem]; + _thread[w] = right; + _rev_thread[right] = w; + + // Change the parent node and shift stem nodes + _parent[stem] = par_stem; + par_stem = stem; + stem = new_stem; + + // Update u and right + u = _last_succ[stem] == _last_succ[par_stem] ? + _rev_thread[par_stem] : _last_succ[stem]; + right = _thread[u]; + } + _parent[u_out] = par_stem; + _thread[u] = last; + _rev_thread[last] = u; + _last_succ[u_out] = u; + + // Remove the subtree of u_out from the thread list except for + // the case when old_rev_thread equals to v_in + // (it also means that join and v_out coincide) + if (old_rev_thread != v_in) { + _thread[old_rev_thread] = right; + _rev_thread[right] = old_rev_thread; + } + + // Update _rev_thread using the new _thread values + for (int i = 0; i != int(_dirty_revs.size()); ++i) { + u = _dirty_revs[i]; + _rev_thread[_thread[u]] = u; + } + + // Update _pred, _forward, _last_succ and _succ_num for the + // stem nodes from u_out to u_in + int tmp_sc = 0, tmp_ls = _last_succ[u_out]; + u = u_out; + while (u != u_in) { + w = _parent[u]; + _pred[u] = _pred[w]; + _forward[u] = !_forward[w]; + tmp_sc += _succ_num[u] - _succ_num[w]; + _succ_num[u] = tmp_sc; + _last_succ[w] = tmp_ls; + u = w; + } + _pred[u_in] = in_arc; + _forward[u_in] = (u_in == _source[in_arc]); + _succ_num[u_in] = old_succ_num; + + // Set limits for updating _last_succ form v_in and v_out + // towards the root + int up_limit_in = -1; + int up_limit_out = -1; + if (_last_succ[join] == v_in) { + up_limit_out = join; + } else { + up_limit_in = join; + } + + // Update _last_succ from v_in towards the root + for (u = v_in; u != up_limit_in && _last_succ[u] == v_in; + u = _parent[u]) { + _last_succ[u] = _last_succ[u_out]; + } + // Update _last_succ from v_out towards the root + if (join != old_rev_thread && v_in != old_rev_thread) { + for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; + u = _parent[u]) { + _last_succ[u] = old_rev_thread; + } + } else { + for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ; + u = _parent[u]) { + _last_succ[u] = _last_succ[u_out]; + } + } + + // Update _succ_num from v_in to join + for (u = v_in; u != join; u = _parent[u]) { + _succ_num[u] += old_succ_num; + } + // Update _succ_num from v_out to join + for (u = v_out; u != join; u = _parent[u]) { + _succ_num[u] -= old_succ_num; + } + } + + // Update potentials + void updatePotential() { + Cost sigma = _forward[u_in] ? + _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] : + _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]]; + // Update potentials in the subtree, which has been moved + int end = _thread[_last_succ[u_in]]; + for (int u = u_in; u != end; u = _thread[u]) { + _pi[u] += sigma; + } + } + + // Heuristic initial pivots + bool initialPivots() { + Value curr, total = 0; + std::vector supply_nodes, demand_nodes; + for (NodeIt u(_graph); u != INVALID; ++u) { + curr = _supply[_node_id[u]]; + if (curr > 0) { + total += curr; + supply_nodes.push_back(u); + } + else if (curr < 0) { + demand_nodes.push_back(u); + } + } + if (_sum_supply > 0) total -= _sum_supply; + if (total <= 0) return true; + + IntVector arc_vector; + if (_sum_supply >= 0) { + if (supply_nodes.size() == 1 && demand_nodes.size() == 1) { + // Perform a reverse graph search from the sink to the source + typename GR::template NodeMap reached(_graph, false); + Node s = supply_nodes[0], t = demand_nodes[0]; + std::vector stack; + reached[t] = true; + stack.push_back(t); + while (!stack.empty()) { + Node u, v = stack.back(); + stack.pop_back(); + if (v == s) break; + for (InArcIt a(_graph, v); a != INVALID; ++a) { + if (reached[u = _graph.source(a)]) continue; + int j = _arc_id[a]; + if (_cap[j] >= total) { + arc_vector.push_back(j); + reached[u] = true; + stack.push_back(u); + } + } + } + } else { + // Find the min. cost incomming arc for each demand node + for (int i = 0; i != int(demand_nodes.size()); ++i) { + Node v = demand_nodes[i]; + Cost c, min_cost = std::numeric_limits::max(); + Arc min_arc = INVALID; + for (InArcIt a(_graph, v); a != INVALID; ++a) { + c = _cost[_arc_id[a]]; + if (c < min_cost) { + min_cost = c; + min_arc = a; + } + } + if (min_arc != INVALID) { + arc_vector.push_back(_arc_id[min_arc]); + } + } + } + } else { + // Find the min. cost outgoing arc for each supply node + for (int i = 0; i != int(supply_nodes.size()); ++i) { + Node u = supply_nodes[i]; + Cost c, min_cost = std::numeric_limits::max(); + Arc min_arc = INVALID; + for (OutArcIt a(_graph, u); a != INVALID; ++a) { + c = _cost[_arc_id[a]]; + if (c < min_cost) { + min_cost = c; + min_arc = a; + } + } + if (min_arc != INVALID) { + arc_vector.push_back(_arc_id[min_arc]); + } + } + } + + // Perform heuristic initial pivots + for (int i = 0; i != int(arc_vector.size()); ++i) { + in_arc = arc_vector[i]; + if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] - + _pi[_target[in_arc]]) >= 0) continue; + findJoinNode(); + bool change = findLeavingArc(); + if (delta >= MAX) return false; + changeFlow(change); + if (change) { + updateTreeStructure(); + updatePotential(); + } + } + return true; + } + + // Execute the algorithm + ProblemType start(PivotRule pivot_rule) { + // Select the pivot rule implementation + switch (pivot_rule) { + case FIRST_ELIGIBLE: + return start(); + case BEST_ELIGIBLE: + return start(); + case BLOCK_SEARCH: + return start(); + case CANDIDATE_LIST: + return start(); + case ALTERING_LIST: + return start(); + } + return INFEASIBLE; // avoid warning + } + + template + ProblemType start() { + PivotRuleImpl pivot(*this); + + // Perform heuristic initial pivots + if (!initialPivots()) return UNBOUNDED; + + // Execute the Network Simplex algorithm + while (pivot.findEnteringArc()) { + findJoinNode(); + bool change = findLeavingArc(); + if (delta >= MAX) return UNBOUNDED; + changeFlow(change); + if (change) { + updateTreeStructure(); + updatePotential(); + } + } + + // Check feasibility + for (int e = _search_arc_num; e != _all_arc_num; ++e) { + if (_flow[e] != 0) return INFEASIBLE; + } + + // Transform the solution and the supply map to the original form + if (_have_lower) { + for (int i = 0; i != _arc_num; ++i) { + Value c = _lower[i]; + if (c != 0) { + _flow[i] += c; + _supply[_source[i]] += c; + _supply[_target[i]] -= c; + } + } + } + + // Shift potentials to meet the requirements of the GEQ/LEQ type + // optimality conditions + if (_sum_supply == 0) { + if (_stype == GEQ) { + Cost max_pot = -std::numeric_limits::max(); + for (int i = 0; i != _node_num; ++i) { + if (_pi[i] > max_pot) max_pot = _pi[i]; + } + if (max_pot > 0) { + for (int i = 0; i != _node_num; ++i) + _pi[i] -= max_pot; + } + } else { + Cost min_pot = std::numeric_limits::max(); + for (int i = 0; i != _node_num; ++i) { + if (_pi[i] < min_pot) min_pot = _pi[i]; + } + if (min_pot < 0) { + for (int i = 0; i != _node_num; ++i) + _pi[i] -= min_pot; + } + } + } + + return OPTIMAL; + } + + }; //class NetworkSimplex + + ///@} + +} //namespace lemon + +#endif //LEMON_NETWORK_SIMPLEX_H diff --git a/lemon/lemon/pairing_heap.h b/lemon/lemon/pairing_heap.h new file mode 100644 index 0000000..da6ebcb --- /dev/null +++ b/lemon/lemon/pairing_heap.h @@ -0,0 +1,474 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_PAIRING_HEAP_H +#define LEMON_PAIRING_HEAP_H + +///\file +///\ingroup heaps +///\brief Pairing heap implementation. + +#include +#include +#include +#include + +namespace lemon { + + /// \ingroup heaps + /// + ///\brief Pairing Heap. + /// + /// This class implements the \e pairing \e heap data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". + /// + /// The methods \ref increase() and \ref erase() are not efficient + /// in a pairing heap. In case of many calls of these operations, + /// it is better to use other heap structure, e.g. \ref BinHeap + /// "binary heap". + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. +#ifdef DOXYGEN + template +#else + template > +#endif + class PairingHeap { + public: + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Functor type for comparing the priorities. + typedef CMP Compare; + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + private: + class store; + + std::vector _data; + int _min; + ItemIntMap &_iim; + Compare _comp; + int _num_items; + + public: + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit PairingHeap(ItemIntMap &map) + : _min(0), _iim(map), _num_items(0) {} + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + PairingHeap(ItemIntMap &map, const Compare &comp) + : _min(0), _iim(map), _comp(comp), _num_items(0) {} + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _num_items; } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _num_items==0; } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { + _data.clear(); + _min = 0; + _num_items = 0; + } + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// \param item The item. + /// \param value The priority. + void set (const Item& item, const Prio& value) { + int i=_iim[item]; + if ( i>=0 && _data[i].in ) { + if ( _comp(value, _data[i].prio) ) decrease(item, value); + if ( _comp(_data[i].prio, value) ) increase(item, value); + } else push(item, value); + } + + /// \brief Insert an item into the heap with the given priority. + /// + /// This function inserts the given item into the heap with the + /// given priority. + /// \param item The item to insert. + /// \param value The priority of the item. + /// \pre \e item must not be stored in the heap. + void push (const Item& item, const Prio& value) { + int i=_iim[item]; + if( i<0 ) { + int s=_data.size(); + _iim.set(item, s); + store st; + st.name=item; + _data.push_back(st); + i=s; + } else { + _data[i].parent=_data[i].child=-1; + _data[i].left_child=false; + _data[i].degree=0; + _data[i].in=true; + } + + _data[i].prio=value; + + if ( _num_items!=0 ) { + if ( _comp( value, _data[_min].prio) ) { + fuse(i,_min); + _min=i; + } + else fuse(_min,i); + } + else _min=i; + + ++_num_items; + } + + /// \brief Return the item having minimum priority. + /// + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { return _data[_min].name; } + + /// \brief The minimum priority. + /// + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + const Prio& prio() const { return _data[_min].prio; } + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param item The item. + /// \pre \e item must be in the heap. + const Prio& operator[](const Item& item) const { + return _data[_iim[item]].prio; + } + + /// \brief Remove the item having minimum priority. + /// + /// This function removes the item having minimum priority. + /// \pre The heap must be non-empty. + void pop() { + std::vector trees; + int i=0, child_right = 0; + _data[_min].in=false; + + if( -1!=_data[_min].child ) { + i=_data[_min].child; + trees.push_back(i); + _data[i].parent = -1; + _data[_min].child = -1; + + int ch=-1; + while( _data[i].child!=-1 ) { + ch=_data[i].child; + if( _data[ch].left_child && i==_data[ch].parent ) { + break; + } else { + if( _data[ch].left_child ) { + child_right=_data[ch].parent; + _data[ch].parent = i; + --_data[i].degree; + } + else { + child_right=ch; + _data[i].child=-1; + _data[i].degree=0; + } + _data[child_right].parent = -1; + trees.push_back(child_right); + i = child_right; + } + } + + int num_child = trees.size(); + int other; + for( i=0; i=2) { + if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) { + other=trees[i]; + trees[i]=trees[i-2]; + trees[i-2]=other; + } + fuse( trees[i-2], trees[i] ); + i-=2; + } + _min = trees[0]; + } + else { + _min = _data[_min].child; + } + + if (_min >= 0) _data[_min].left_child = false; + --_num_items; + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param item The item to delete. + /// \pre \e item must be in the heap. + void erase (const Item& item) { + int i=_iim[item]; + if ( i>=0 && _data[i].in ) { + decrease( item, _data[_min].prio-1 ); + pop(); + } + } + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param item The item. + /// \param value The priority. + /// \pre \e item must be stored in the heap with priority at least \e value. + void decrease (Item item, const Prio& value) { + int i=_iim[item]; + _data[i].prio=value; + int p=_data[i].parent; + + if( _data[i].left_child && i!=_data[p].child ) { + p=_data[p].parent; + } + + if ( p!=-1 && _comp(value,_data[p].prio) ) { + cut(i,p); + if ( _comp(_data[_min].prio,value) ) { + fuse(_min,i); + } else { + fuse(i,_min); + _min=i; + } + } + } + + /// \brief Increase the priority of an item to the given value. + /// + /// This function increases the priority of an item to the given value. + /// \param item The item. + /// \param value The priority. + /// \pre \e item must be stored in the heap with priority at most \e value. + void increase (Item item, const Prio& value) { + erase(item); + push(item,value); + } + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param item The item. + State state(const Item &item) const { + int i=_iim[item]; + if( i>=0 ) { + if( _data[i].in ) i=0; + else i=-2; + } + return State(i); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) erase(i); + _iim[i]=st; + break; + case IN_HEAP: + break; + } + } + + private: + + void cut(int a, int b) { + int child_a; + switch (_data[a].degree) { + case 2: + child_a = _data[_data[a].child].parent; + if( _data[a].left_child ) { + _data[child_a].left_child=true; + _data[b].child=child_a; + _data[child_a].parent=_data[a].parent; + } + else { + _data[child_a].left_child=false; + _data[child_a].parent=b; + if( a!=_data[b].child ) + _data[_data[b].child].parent=child_a; + else + _data[b].child=child_a; + } + --_data[a].degree; + _data[_data[a].child].parent=a; + break; + + case 1: + child_a = _data[a].child; + if( !_data[child_a].left_child ) { + --_data[a].degree; + if( _data[a].left_child ) { + _data[child_a].left_child=true; + _data[child_a].parent=_data[a].parent; + _data[b].child=child_a; + } + else { + _data[child_a].left_child=false; + _data[child_a].parent=b; + if( a!=_data[b].child ) + _data[_data[b].child].parent=child_a; + else + _data[b].child=child_a; + } + _data[a].child=-1; + } + else { + --_data[b].degree; + if( _data[a].left_child ) { + _data[b].child = + (1==_data[b].degree) ? _data[a].parent : -1; + } else { + if (1==_data[b].degree) + _data[_data[b].child].parent=b; + else + _data[b].child=-1; + } + } + break; + + case 0: + --_data[b].degree; + if( _data[a].left_child ) { + _data[b].child = + (0!=_data[b].degree) ? _data[a].parent : -1; + } else { + if( 0!=_data[b].degree ) + _data[_data[b].child].parent=b; + else + _data[b].child=-1; + } + break; + } + _data[a].parent=-1; + _data[a].left_child=false; + } + + void fuse(int a, int b) { + int child_a = _data[a].child; + int child_b = _data[b].child; + _data[a].child=b; + _data[b].parent=a; + _data[b].left_child=true; + + if( -1!=child_a ) { + _data[b].child=child_a; + _data[child_a].parent=b; + _data[child_a].left_child=false; + ++_data[b].degree; + + if( -1!=child_b ) { + _data[b].child=child_b; + _data[child_b].parent=child_a; + } + } + else { ++_data[a].degree; } + } + + class store { + friend class PairingHeap; + + Item name; + int parent; + int child; + bool left_child; + int degree; + bool in; + Prio prio; + + store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {} + }; + }; + +} //namespace lemon + +#endif //LEMON_PAIRING_HEAP_H + diff --git a/lemon/lemon/path.h b/lemon/lemon/path.h new file mode 100644 index 0000000..f009145 --- /dev/null +++ b/lemon/lemon/path.h @@ -0,0 +1,1112 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup paths +///\file +///\brief Classes for representing paths in digraphs. +/// + +#ifndef LEMON_PATH_H +#define LEMON_PATH_H + +#include +#include + +#include +#include +#include + +namespace lemon { + + /// \addtogroup paths + /// @{ + + + /// \brief A structure for representing directed paths in a digraph. + /// + /// A structure for representing directed path in a digraph. + /// \tparam GR The digraph type in which the path is. + /// + /// In a sense, the path can be treated as a list of arcs. The + /// lemon path type stores just this list. As a consequence, it + /// cannot enumerate the nodes of the path and the source node of + /// a zero length path is undefined. + /// + /// This implementation is a back and front insertable and erasable + /// path type. It can be indexed in O(1) time. The front and back + /// insertion and erase is done in O(1) (amortized) time. The + /// implementation uses two vectors for storing the front and back + /// insertions. + template + class Path { + public: + + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + + /// \brief Default constructor + /// + /// Default constructor + Path() {} + + /// \brief Template copy constructor + /// + /// This constuctor initializes the path from any other path type. + /// It simply makes a copy of the given path. + template + Path(const CPath& cpath) { + pathCopy(cpath, *this); + } + + /// \brief Template copy assignment + /// + /// This operator makes a copy of a path of any other type. + template + Path& operator=(const CPath& cpath) { + pathCopy(cpath, *this); + return *this; + } + + /// \brief LEMON style iterator for path arcs + /// + /// This class is used to iterate on the arcs of the paths. + class ArcIt { + friend class Path; + public: + /// \brief Default constructor + ArcIt() {} + /// \brief Invalid constructor + ArcIt(Invalid) : path(0), idx(-1) {} + /// \brief Initializate the iterator to the first arc of path + ArcIt(const Path &_path) + : path(&_path), idx(_path.empty() ? -1 : 0) {} + + private: + + ArcIt(const Path &_path, int _idx) + : path(&_path), idx(_idx) {} + + public: + + /// \brief Conversion to Arc + operator const Arc&() const { + return path->nth(idx); + } + + /// \brief Next arc + ArcIt& operator++() { + ++idx; + if (idx >= path->length()) idx = -1; + return *this; + } + + /// \brief Comparison operator + bool operator==(const ArcIt& e) const { return idx==e.idx; } + /// \brief Comparison operator + bool operator!=(const ArcIt& e) const { return idx!=e.idx; } + /// \brief Comparison operator + bool operator<(const ArcIt& e) const { return idx[0..length() - 1] range. + const Arc& nth(int n) const { + return n < int(head.size()) ? *(head.rbegin() + n) : + *(tail.begin() + (n - head.size())); + } + + /// \brief Initialize arc iterator to point to the nth arc + /// + /// \pre \c n is in the [0..length() - 1] range. + ArcIt nthIt(int n) const { + return ArcIt(*this, n); + } + + /// \brief The first arc of the path + const Arc& front() const { + return head.empty() ? tail.front() : head.back(); + } + + /// \brief Add a new arc before the current path + void addFront(const Arc& arc) { + head.push_back(arc); + } + + /// \brief Erase the first arc of the path + void eraseFront() { + if (!head.empty()) { + head.pop_back(); + } else { + head.clear(); + int halfsize = tail.size() / 2; + head.resize(halfsize); + std::copy(tail.begin() + 1, tail.begin() + halfsize + 1, + head.rbegin()); + std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin()); + tail.resize(tail.size() - halfsize - 1); + } + } + + /// \brief The last arc of the path + const Arc& back() const { + return tail.empty() ? head.front() : tail.back(); + } + + /// \brief Add a new arc behind the current path + void addBack(const Arc& arc) { + tail.push_back(arc); + } + + /// \brief Erase the last arc of the path + void eraseBack() { + if (!tail.empty()) { + tail.pop_back(); + } else { + int halfsize = head.size() / 2; + tail.resize(halfsize); + std::copy(head.begin() + 1, head.begin() + halfsize + 1, + tail.rbegin()); + std::copy(head.begin() + halfsize + 1, head.end(), head.begin()); + head.resize(head.size() - halfsize - 1); + } + } + + typedef True BuildTag; + + template + void build(const CPath& path) { + int len = path.length(); + tail.reserve(len); + for (typename CPath::ArcIt it(path); it != INVALID; ++it) { + tail.push_back(it); + } + } + + template + void buildRev(const CPath& path) { + int len = path.length(); + head.reserve(len); + for (typename CPath::RevArcIt it(path); it != INVALID; ++it) { + head.push_back(it); + } + } + + protected: + typedef std::vector Container; + Container head, tail; + + }; + + /// \brief A structure for representing directed paths in a digraph. + /// + /// A structure for representing directed path in a digraph. + /// \tparam GR The digraph type in which the path is. + /// + /// In a sense, the path can be treated as a list of arcs. The + /// lemon path type stores just this list. As a consequence it + /// cannot enumerate the nodes in the path and the zero length paths + /// cannot store the source. + /// + /// This implementation is a just back insertable and erasable path + /// type. It can be indexed in O(1) time. The back insertion and + /// erasure is amortized O(1) time. This implementation is faster + /// then the \c Path type because it use just one vector for the + /// arcs. + template + class SimplePath { + public: + + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + + /// \brief Default constructor + /// + /// Default constructor + SimplePath() {} + + /// \brief Template copy constructor + /// + /// This path can be initialized with any other path type. It just + /// makes a copy of the given path. + template + SimplePath(const CPath& cpath) { + pathCopy(cpath, *this); + } + + /// \brief Template copy assignment + /// + /// This path can be initialized with any other path type. It just + /// makes a copy of the given path. + template + SimplePath& operator=(const CPath& cpath) { + pathCopy(cpath, *this); + return *this; + } + + /// \brief Iterator class to iterate on the arcs of the paths + /// + /// This class is used to iterate on the arcs of the paths + /// + /// Of course it converts to Digraph::Arc + class ArcIt { + friend class SimplePath; + public: + /// Default constructor + ArcIt() {} + /// Invalid constructor + ArcIt(Invalid) : path(0), idx(-1) {} + /// \brief Initializate the constructor to the first arc of path + ArcIt(const SimplePath &_path) + : path(&_path), idx(_path.empty() ? -1 : 0) {} + + private: + + /// Constructor with starting point + ArcIt(const SimplePath &_path, int _idx) + : idx(_idx), path(&_path) {} + + public: + + ///Conversion to Digraph::Arc + operator const Arc&() const { + return path->nth(idx); + } + + /// Next arc + ArcIt& operator++() { + ++idx; + if (idx >= path->length()) idx = -1; + return *this; + } + + /// Comparison operator + bool operator==(const ArcIt& e) const { return idx==e.idx; } + /// Comparison operator + bool operator!=(const ArcIt& e) const { return idx!=e.idx; } + /// Comparison operator + bool operator<(const ArcIt& e) const { return idx[0..length() - 1] range. + const Arc& nth(int n) const { + return data[n]; + } + + /// \brief Initializes arc iterator to point to the nth arc. + ArcIt nthIt(int n) const { + return ArcIt(*this, n); + } + + /// \brief The first arc of the path. + const Arc& front() const { + return data.front(); + } + + /// \brief The last arc of the path. + const Arc& back() const { + return data.back(); + } + + /// \brief Add a new arc behind the current path. + void addBack(const Arc& arc) { + data.push_back(arc); + } + + /// \brief Erase the last arc of the path + void eraseBack() { + data.pop_back(); + } + + typedef True BuildTag; + + template + void build(const CPath& path) { + int len = path.length(); + data.resize(len); + int index = 0; + for (typename CPath::ArcIt it(path); it != INVALID; ++it) { + data[index] = it;; + ++index; + } + } + + template + void buildRev(const CPath& path) { + int len = path.length(); + data.resize(len); + int index = len; + for (typename CPath::RevArcIt it(path); it != INVALID; ++it) { + --index; + data[index] = it;; + } + } + + protected: + typedef std::vector Container; + Container data; + + }; + + /// \brief A structure for representing directed paths in a digraph. + /// + /// A structure for representing directed path in a digraph. + /// \tparam GR The digraph type in which the path is. + /// + /// In a sense, the path can be treated as a list of arcs. The + /// lemon path type stores just this list. As a consequence it + /// cannot enumerate the nodes in the path and the zero length paths + /// cannot store the source. + /// + /// This implementation is a back and front insertable and erasable + /// path type. It can be indexed in O(k) time, where k is the rank + /// of the arc in the path. The length can be computed in O(n) + /// time. The front and back insertion and erasure is O(1) time + /// and it can be splited and spliced in O(1) time. + template + class ListPath { + public: + + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + + protected: + + // the std::list<> is incompatible + // hard to create invalid iterator + struct Node { + Arc arc; + Node *next, *prev; + }; + + Node *first, *last; + + std::allocator alloc; + + public: + + /// \brief Default constructor + /// + /// Default constructor + ListPath() : first(0), last(0) {} + + /// \brief Template copy constructor + /// + /// This path can be initialized with any other path type. It just + /// makes a copy of the given path. + template + ListPath(const CPath& cpath) : first(0), last(0) { + pathCopy(cpath, *this); + } + + /// \brief Destructor of the path + /// + /// Destructor of the path + ~ListPath() { + clear(); + } + + /// \brief Template copy assignment + /// + /// This path can be initialized with any other path type. It just + /// makes a copy of the given path. + template + ListPath& operator=(const CPath& cpath) { + pathCopy(cpath, *this); + return *this; + } + + /// \brief Iterator class to iterate on the arcs of the paths + /// + /// This class is used to iterate on the arcs of the paths + /// + /// Of course it converts to Digraph::Arc + class ArcIt { + friend class ListPath; + public: + /// Default constructor + ArcIt() {} + /// Invalid constructor + ArcIt(Invalid) : path(0), node(0) {} + /// \brief Initializate the constructor to the first arc of path + ArcIt(const ListPath &_path) + : path(&_path), node(_path.first) {} + + protected: + + ArcIt(const ListPath &_path, Node *_node) + : path(&_path), node(_node) {} + + + public: + + ///Conversion to Digraph::Arc + operator const Arc&() const { + return node->arc; + } + + /// Next arc + ArcIt& operator++() { + node = node->next; + return *this; + } + + /// Comparison operator + bool operator==(const ArcIt& e) const { return node==e.node; } + /// Comparison operator + bool operator!=(const ArcIt& e) const { return node!=e.node; } + /// Comparison operator + bool operator<(const ArcIt& e) const { return node[0..length() - 1] range. + const Arc& nth(int n) const { + Node *node = first; + for (int i = 0; i < n; ++i) { + node = node->next; + } + return node->arc; + } + + /// \brief Initializes arc iterator to point to the nth arc. + ArcIt nthIt(int n) const { + Node *node = first; + for (int i = 0; i < n; ++i) { + node = node->next; + } + return ArcIt(*this, node); + } + + /// \brief Length of the path. + int length() const { + int len = 0; + Node *node = first; + while (node != 0) { + node = node->next; + ++len; + } + return len; + } + + /// \brief Return true if the path is empty. + bool empty() const { return first == 0; } + + /// \brief Reset the path to an empty one. + void clear() { + while (first != 0) { + last = first->next; + alloc.destroy(first); + alloc.deallocate(first, 1); + first = last; + } + } + + /// \brief The first arc of the path + const Arc& front() const { + return first->arc; + } + + /// \brief Add a new arc before the current path + void addFront(const Arc& arc) { + Node *node = alloc.allocate(1); + alloc.construct(node, Node()); + node->prev = 0; + node->next = first; + node->arc = arc; + if (first) { + first->prev = node; + first = node; + } else { + first = last = node; + } + } + + /// \brief Erase the first arc of the path + void eraseFront() { + Node *node = first; + first = first->next; + if (first) { + first->prev = 0; + } else { + last = 0; + } + alloc.destroy(node); + alloc.deallocate(node, 1); + } + + /// \brief The last arc of the path. + const Arc& back() const { + return last->arc; + } + + /// \brief Add a new arc behind the current path. + void addBack(const Arc& arc) { + Node *node = alloc.allocate(1); + alloc.construct(node, Node()); + node->next = 0; + node->prev = last; + node->arc = arc; + if (last) { + last->next = node; + last = node; + } else { + last = first = node; + } + } + + /// \brief Erase the last arc of the path + void eraseBack() { + Node *node = last; + last = last->prev; + if (last) { + last->next = 0; + } else { + first = 0; + } + alloc.destroy(node); + alloc.deallocate(node, 1); + } + + /// \brief Splice a path to the back of the current path. + /// + /// It splices \c tpath to the back of the current path and \c + /// tpath becomes empty. The time complexity of this function is + /// O(1). + void spliceBack(ListPath& tpath) { + if (first) { + if (tpath.first) { + last->next = tpath.first; + tpath.first->prev = last; + last = tpath.last; + } + } else { + first = tpath.first; + last = tpath.last; + } + tpath.first = tpath.last = 0; + } + + /// \brief Splice a path to the front of the current path. + /// + /// It splices \c tpath before the current path and \c tpath + /// becomes empty. The time complexity of this function + /// is O(1). + void spliceFront(ListPath& tpath) { + if (first) { + if (tpath.first) { + first->prev = tpath.last; + tpath.last->next = first; + first = tpath.first; + } + } else { + first = tpath.first; + last = tpath.last; + } + tpath.first = tpath.last = 0; + } + + /// \brief Splice a path into the current path. + /// + /// It splices the \c tpath into the current path before the + /// position of \c it iterator and \c tpath becomes empty. The + /// time complexity of this function is O(1). If the \c it is + /// \c INVALID then it will splice behind the current path. + void splice(ArcIt it, ListPath& tpath) { + if (it.node) { + if (tpath.first) { + tpath.first->prev = it.node->prev; + if (it.node->prev) { + it.node->prev->next = tpath.first; + } else { + first = tpath.first; + } + it.node->prev = tpath.last; + tpath.last->next = it.node; + } + } else { + if (first) { + if (tpath.first) { + last->next = tpath.first; + tpath.first->prev = last; + last = tpath.last; + } + } else { + first = tpath.first; + last = tpath.last; + } + } + tpath.first = tpath.last = 0; + } + + /// \brief Split the current path. + /// + /// It splits the current path into two parts. The part before + /// the iterator \c it will remain in the current path and the part + /// starting with + /// \c it will put into \c tpath. If \c tpath have arcs + /// before the operation they are removed first. The time + /// complexity of this function is O(1) plus the the time of emtying + /// \c tpath. If \c it is \c INVALID then it just clears \c tpath + void split(ArcIt it, ListPath& tpath) { + tpath.clear(); + if (it.node) { + tpath.first = it.node; + tpath.last = last; + if (it.node->prev) { + last = it.node->prev; + last->next = 0; + } else { + first = last = 0; + } + it.node->prev = 0; + } + } + + + typedef True BuildTag; + + template + void build(const CPath& path) { + for (typename CPath::ArcIt it(path); it != INVALID; ++it) { + addBack(it); + } + } + + template + void buildRev(const CPath& path) { + for (typename CPath::RevArcIt it(path); it != INVALID; ++it) { + addFront(it); + } + } + + }; + + /// \brief A structure for representing directed paths in a digraph. + /// + /// A structure for representing directed path in a digraph. + /// \tparam GR The digraph type in which the path is. + /// + /// In a sense, the path can be treated as a list of arcs. The + /// lemon path type stores just this list. As a consequence it + /// cannot enumerate the nodes in the path and the source node of + /// a zero length path is undefined. + /// + /// This implementation is completly static, i.e. it can be copy constucted + /// or copy assigned from another path, but otherwise it cannot be + /// modified. + /// + /// Being the the most memory efficient path type in LEMON, + /// it is intented to be + /// used when you want to store a large number of paths. + template + class StaticPath { + public: + + typedef GR Digraph; + typedef typename Digraph::Arc Arc; + + /// \brief Default constructor + /// + /// Default constructor + StaticPath() : len(0), arcs(0) {} + + /// \brief Template copy constructor + /// + /// This path can be initialized from any other path type. + template + StaticPath(const CPath& cpath) : arcs(0) { + pathCopy(cpath, *this); + } + + /// \brief Destructor of the path + /// + /// Destructor of the path + ~StaticPath() { + if (arcs) delete[] arcs; + } + + /// \brief Template copy assignment + /// + /// This path can be made equal to any other path type. It simply + /// makes a copy of the given path. + template + StaticPath& operator=(const CPath& cpath) { + pathCopy(cpath, *this); + return *this; + } + + /// \brief Iterator class to iterate on the arcs of the paths + /// + /// This class is used to iterate on the arcs of the paths + /// + /// Of course it converts to Digraph::Arc + class ArcIt { + friend class StaticPath; + public: + /// Default constructor + ArcIt() {} + /// Invalid constructor + ArcIt(Invalid) : path(0), idx(-1) {} + /// Initializate the constructor to the first arc of path + ArcIt(const StaticPath &_path) + : path(&_path), idx(_path.empty() ? -1 : 0) {} + + private: + + /// Constructor with starting point + ArcIt(const StaticPath &_path, int _idx) + : idx(_idx), path(&_path) {} + + public: + + ///Conversion to Digraph::Arc + operator const Arc&() const { + return path->nth(idx); + } + + /// Next arc + ArcIt& operator++() { + ++idx; + if (idx >= path->length()) idx = -1; + return *this; + } + + /// Comparison operator + bool operator==(const ArcIt& e) const { return idx==e.idx; } + /// Comparison operator + bool operator!=(const ArcIt& e) const { return idx!=e.idx; } + /// Comparison operator + bool operator<(const ArcIt& e) const { return idx[0..length() - 1] range. + const Arc& nth(int n) const { + return arcs[n]; + } + + /// \brief The arc iterator pointing to the nth arc. + ArcIt nthIt(int n) const { + return ArcIt(*this, n); + } + + /// \brief The length of the path. + int length() const { return len; } + + /// \brief Return true when the path is empty. + int empty() const { return len == 0; } + + /// \brief Erase all arcs in the digraph. + void clear() { + len = 0; + if (arcs) delete[] arcs; + arcs = 0; + } + + /// \brief The first arc of the path. + const Arc& front() const { + return arcs[0]; + } + + /// \brief The last arc of the path. + const Arc& back() const { + return arcs[len - 1]; + } + + + typedef True BuildTag; + + template + void build(const CPath& path) { + len = path.length(); + arcs = new Arc[len]; + int index = 0; + for (typename CPath::ArcIt it(path); it != INVALID; ++it) { + arcs[index] = it; + ++index; + } + } + + template + void buildRev(const CPath& path) { + len = path.length(); + arcs = new Arc[len]; + int index = len; + for (typename CPath::RevArcIt it(path); it != INVALID; ++it) { + --index; + arcs[index] = it; + } + } + + private: + int len; + Arc* arcs; + }; + + /////////////////////////////////////////////////////////////////////// + // Additional utilities + /////////////////////////////////////////////////////////////////////// + + namespace _path_bits { + + template + struct RevPathTagIndicator { + static const bool value = false; + }; + + template + struct RevPathTagIndicator< + Path, + typename enable_if::type + > { + static const bool value = true; + }; + + template + struct BuildTagIndicator { + static const bool value = false; + }; + + template + struct BuildTagIndicator< + Path, + typename enable_if::type + > { + static const bool value = true; + }; + + template ::value> + struct PathCopySelectorForward { + static void copy(const From& from, To& to) { + to.clear(); + for (typename From::ArcIt it(from); it != INVALID; ++it) { + to.addBack(it); + } + } + }; + + template + struct PathCopySelectorForward { + static void copy(const From& from, To& to) { + to.clear(); + to.build(from); + } + }; + + template ::value> + struct PathCopySelectorBackward { + static void copy(const From& from, To& to) { + to.clear(); + for (typename From::RevArcIt it(from); it != INVALID; ++it) { + to.addFront(it); + } + } + }; + + template + struct PathCopySelectorBackward { + static void copy(const From& from, To& to) { + to.clear(); + to.buildRev(from); + } + }; + + + template ::value> + struct PathCopySelector { + static void copy(const From& from, To& to) { + PathCopySelectorForward::copy(from, to); + } + }; + + template + struct PathCopySelector { + static void copy(const From& from, To& to) { + PathCopySelectorBackward::copy(from, to); + } + }; + + } + + + /// \brief Make a copy of a path. + /// + /// This function makes a copy of a path. + template + void pathCopy(const From& from, To& to) { + checkConcept, From>(); + _path_bits::PathCopySelector::copy(from, to); + } + + /// \brief Deprecated version of \ref pathCopy(). + /// + /// Deprecated version of \ref pathCopy() (only for reverse compatibility). + template + void copyPath(To& to, const From& from) { + pathCopy(from, to); + } + + /// \brief Check the consistency of a path. + /// + /// This function checks that the target of each arc is the same + /// as the source of the next one. + /// + template + bool checkPath(const Digraph& digraph, const Path& path) { + typename Path::ArcIt it(path); + if (it == INVALID) return true; + typename Digraph::Node node = digraph.target(it); + ++it; + while (it != INVALID) { + if (digraph.source(it) != node) return false; + node = digraph.target(it); + ++it; + } + return true; + } + + /// \brief The source of a path + /// + /// This function returns the source node of the given path. + /// If the path is empty, then it returns \c INVALID. + template + typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) { + return path.empty() ? INVALID : digraph.source(path.front()); + } + + /// \brief The target of a path + /// + /// This function returns the target node of the given path. + /// If the path is empty, then it returns \c INVALID. + template + typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) { + return path.empty() ? INVALID : digraph.target(path.back()); + } + + /// \brief Class which helps to iterate through the nodes of a path + /// + /// In a sense, the path can be treated as a list of arcs. The + /// lemon path type stores only this list. As a consequence, it + /// cannot enumerate the nodes in the path and the zero length paths + /// cannot have a source node. + /// + /// This class implements the node iterator of a path structure. To + /// provide this feature, the underlying digraph should be passed to + /// the constructor of the iterator. + template + class PathNodeIt { + private: + const typename Path::Digraph *_digraph; + typename Path::ArcIt _it; + typename Path::Digraph::Node _nd; + + public: + + typedef typename Path::Digraph Digraph; + typedef typename Digraph::Node Node; + + /// Default constructor + PathNodeIt() {} + /// Invalid constructor + PathNodeIt(Invalid) + : _digraph(0), _it(INVALID), _nd(INVALID) {} + /// Constructor + PathNodeIt(const Digraph& digraph, const Path& path) + : _digraph(&digraph), _it(path) { + _nd = (_it != INVALID ? _digraph->source(_it) : INVALID); + } + /// Constructor + PathNodeIt(const Digraph& digraph, const Path& path, const Node& src) + : _digraph(&digraph), _it(path), _nd(src) {} + + ///Conversion to Digraph::Node + operator Node() const { + return _nd; + } + + /// Next node + PathNodeIt& operator++() { + if (_it == INVALID) _nd = INVALID; + else { + _nd = _digraph->target(_it); + ++_it; + } + return *this; + } + + /// Comparison operator + bool operator==(const PathNodeIt& n) const { + return _it == n._it && _nd == n._nd; + } + /// Comparison operator + bool operator!=(const PathNodeIt& n) const { + return _it != n._it || _nd != n._nd; + } + /// Comparison operator + bool operator<(const PathNodeIt& n) const { + return (_it < n._it && _nd != INVALID); + } + + }; + + ///@} + +} // namespace lemon + +#endif // LEMON_PATH_H diff --git a/lemon/lemon/planarity.h b/lemon/lemon/planarity.h new file mode 100644 index 0000000..c5edaea --- /dev/null +++ b/lemon/lemon/planarity.h @@ -0,0 +1,2755 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_PLANARITY_H +#define LEMON_PLANARITY_H + +/// \ingroup planar +/// \file +/// \brief Planarity checking, embedding, drawing and coloring + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace lemon { + + namespace _planarity_bits { + + template + struct PlanarityVisitor : DfsVisitor { + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + typedef typename Graph::template NodeMap PredMap; + + typedef typename Graph::template EdgeMap TreeMap; + + typedef typename Graph::template NodeMap OrderMap; + typedef std::vector OrderList; + + typedef typename Graph::template NodeMap LowMap; + typedef typename Graph::template NodeMap AncestorMap; + + PlanarityVisitor(const Graph& graph, + PredMap& pred_map, TreeMap& tree_map, + OrderMap& order_map, OrderList& order_list, + AncestorMap& ancestor_map, LowMap& low_map) + : _graph(graph), _pred_map(pred_map), _tree_map(tree_map), + _order_map(order_map), _order_list(order_list), + _ancestor_map(ancestor_map), _low_map(low_map) {} + + void reach(const Node& node) { + _order_map[node] = _order_list.size(); + _low_map[node] = _order_list.size(); + _ancestor_map[node] = _order_list.size(); + _order_list.push_back(node); + } + + void discover(const Arc& arc) { + Node source = _graph.source(arc); + Node target = _graph.target(arc); + + _tree_map[arc] = true; + _pred_map[target] = arc; + } + + void examine(const Arc& arc) { + Node source = _graph.source(arc); + Node target = _graph.target(arc); + + if (_order_map[target] < _order_map[source] && !_tree_map[arc]) { + if (_low_map[source] > _order_map[target]) { + _low_map[source] = _order_map[target]; + } + if (_ancestor_map[source] > _order_map[target]) { + _ancestor_map[source] = _order_map[target]; + } + } + } + + void backtrack(const Arc& arc) { + Node source = _graph.source(arc); + Node target = _graph.target(arc); + + if (_low_map[source] > _low_map[target]) { + _low_map[source] = _low_map[target]; + } + } + + const Graph& _graph; + PredMap& _pred_map; + TreeMap& _tree_map; + OrderMap& _order_map; + OrderList& _order_list; + AncestorMap& _ancestor_map; + LowMap& _low_map; + }; + + template + struct NodeDataNode { + int prev, next; + int visited; + typename Graph::Arc first; + bool inverted; + }; + + template + struct NodeDataNode { + int prev, next; + int visited; + }; + + template + struct ChildListNode { + typedef typename Graph::Node Node; + Node first; + Node prev, next; + }; + + template + struct ArcListNode { + typename Graph::Arc prev, next; + }; + + template + class PlanarityChecking { + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + const Graph& _graph; + + private: + + typedef typename Graph::template NodeMap PredMap; + + typedef typename Graph::template EdgeMap TreeMap; + + typedef typename Graph::template NodeMap OrderMap; + typedef std::vector OrderList; + + typedef typename Graph::template NodeMap LowMap; + typedef typename Graph::template NodeMap AncestorMap; + + typedef _planarity_bits::NodeDataNode NodeDataNode; + typedef std::vector NodeData; + + typedef _planarity_bits::ChildListNode ChildListNode; + typedef typename Graph::template NodeMap ChildLists; + + typedef typename Graph::template NodeMap > MergeRoots; + + typedef typename Graph::template NodeMap EmbedArc; + + public: + + PlanarityChecking(const Graph& graph) : _graph(graph) {} + + bool run() { + typedef _planarity_bits::PlanarityVisitor Visitor; + + PredMap pred_map(_graph, INVALID); + TreeMap tree_map(_graph, false); + + OrderMap order_map(_graph, -1); + OrderList order_list; + + AncestorMap ancestor_map(_graph, -1); + LowMap low_map(_graph, -1); + + Visitor visitor(_graph, pred_map, tree_map, + order_map, order_list, ancestor_map, low_map); + DfsVisit visit(_graph, visitor); + visit.run(); + + ChildLists child_lists(_graph); + createChildLists(tree_map, order_map, low_map, child_lists); + + NodeData node_data(2 * order_list.size()); + + EmbedArc embed_arc(_graph, false); + + MergeRoots merge_roots(_graph); + + for (int i = order_list.size() - 1; i >= 0; --i) { + + Node node = order_list[i]; + + Node source = node; + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && tree_map[e]) { + initFace(target, node_data, order_map, order_list); + } + } + + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && !tree_map[e]) { + embed_arc[target] = true; + walkUp(target, source, i, pred_map, low_map, + order_map, order_list, node_data, merge_roots); + } + } + + for (typename MergeRoots::Value::iterator it = + merge_roots[node].begin(); + it != merge_roots[node].end(); ++it) { + int rn = *it; + walkDown(rn, i, node_data, order_list, child_lists, + ancestor_map, low_map, embed_arc, merge_roots); + } + merge_roots[node].clear(); + + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && !tree_map[e]) { + if (embed_arc[target]) { + return false; + } + } + } + } + + return true; + } + + private: + + void createChildLists(const TreeMap& tree_map, const OrderMap& order_map, + const LowMap& low_map, ChildLists& child_lists) { + + for (NodeIt n(_graph); n != INVALID; ++n) { + Node source = n; + + std::vector targets; + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && tree_map[e]) { + targets.push_back(target); + } + } + + if (targets.size() == 0) { + child_lists[source].first = INVALID; + } else if (targets.size() == 1) { + child_lists[source].first = targets[0]; + child_lists[targets[0]].prev = INVALID; + child_lists[targets[0]].next = INVALID; + } else { + radixSort(targets.begin(), targets.end(), mapToFunctor(low_map)); + for (int i = 1; i < int(targets.size()); ++i) { + child_lists[targets[i]].prev = targets[i - 1]; + child_lists[targets[i - 1]].next = targets[i]; + } + child_lists[targets.back()].next = INVALID; + child_lists[targets.front()].prev = INVALID; + child_lists[source].first = targets.front(); + } + } + } + + void walkUp(const Node& node, Node root, int rorder, + const PredMap& pred_map, const LowMap& low_map, + const OrderMap& order_map, const OrderList& order_list, + NodeData& node_data, MergeRoots& merge_roots) { + + int na, nb; + bool da, db; + + na = nb = order_map[node]; + da = true; db = false; + + while (true) { + + if (node_data[na].visited == rorder) break; + if (node_data[nb].visited == rorder) break; + + node_data[na].visited = rorder; + node_data[nb].visited = rorder; + + int rn = -1; + + if (na >= int(order_list.size())) { + rn = na; + } else if (nb >= int(order_list.size())) { + rn = nb; + } + + if (rn == -1) { + int nn; + + nn = da ? node_data[na].prev : node_data[na].next; + da = node_data[nn].prev != na; + na = nn; + + nn = db ? node_data[nb].prev : node_data[nb].next; + db = node_data[nn].prev != nb; + nb = nn; + + } else { + + Node rep = order_list[rn - order_list.size()]; + Node parent = _graph.source(pred_map[rep]); + + if (low_map[rep] < rorder) { + merge_roots[parent].push_back(rn); + } else { + merge_roots[parent].push_front(rn); + } + + if (parent != root) { + na = nb = order_map[parent]; + da = true; db = false; + } else { + break; + } + } + } + } + + void walkDown(int rn, int rorder, NodeData& node_data, + OrderList& order_list, ChildLists& child_lists, + AncestorMap& ancestor_map, LowMap& low_map, + EmbedArc& embed_arc, MergeRoots& merge_roots) { + + std::vector > merge_stack; + + for (int di = 0; di < 2; ++di) { + bool rd = di == 0; + int pn = rn; + int n = rd ? node_data[rn].next : node_data[rn].prev; + + while (n != rn) { + + Node node = order_list[n]; + + if (embed_arc[node]) { + + // Merging components on the critical path + while (!merge_stack.empty()) { + + // Component root + int cn = merge_stack.back().first; + bool cd = merge_stack.back().second; + merge_stack.pop_back(); + + // Parent of component + int dn = merge_stack.back().first; + bool dd = merge_stack.back().second; + merge_stack.pop_back(); + + Node parent = order_list[dn]; + + // Erasing from merge_roots + merge_roots[parent].pop_front(); + + Node child = order_list[cn - order_list.size()]; + + // Erasing from child_lists + if (child_lists[child].prev != INVALID) { + child_lists[child_lists[child].prev].next = + child_lists[child].next; + } else { + child_lists[parent].first = child_lists[child].next; + } + + if (child_lists[child].next != INVALID) { + child_lists[child_lists[child].next].prev = + child_lists[child].prev; + } + + // Merging external faces + { + int en = cn; + cn = cd ? node_data[cn].prev : node_data[cn].next; + cd = node_data[cn].next == en; + + } + + if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn; + if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn; + + } + + bool d = pn == node_data[n].prev; + + if (node_data[n].prev == node_data[n].next && + node_data[n].inverted) { + d = !d; + } + + // Embedding arc into external face + if (rd) node_data[rn].next = n; else node_data[rn].prev = n; + if (d) node_data[n].prev = rn; else node_data[n].next = rn; + pn = rn; + + embed_arc[order_list[n]] = false; + } + + if (!merge_roots[node].empty()) { + + bool d = pn == node_data[n].prev; + + merge_stack.push_back(std::make_pair(n, d)); + + int rn = merge_roots[node].front(); + + int xn = node_data[rn].next; + Node xnode = order_list[xn]; + + int yn = node_data[rn].prev; + Node ynode = order_list[yn]; + + bool rd; + if (!external(xnode, rorder, child_lists, + ancestor_map, low_map)) { + rd = true; + } else if (!external(ynode, rorder, child_lists, + ancestor_map, low_map)) { + rd = false; + } else if (pertinent(xnode, embed_arc, merge_roots)) { + rd = true; + } else { + rd = false; + } + + merge_stack.push_back(std::make_pair(rn, rd)); + + pn = rn; + n = rd ? xn : yn; + + } else if (!external(node, rorder, child_lists, + ancestor_map, low_map)) { + int nn = (node_data[n].next != pn ? + node_data[n].next : node_data[n].prev); + + bool nd = n == node_data[nn].prev; + + if (nd) node_data[nn].prev = pn; + else node_data[nn].next = pn; + + if (n == node_data[pn].prev) node_data[pn].prev = nn; + else node_data[pn].next = nn; + + node_data[nn].inverted = + (node_data[nn].prev == node_data[nn].next && nd != rd); + + n = nn; + } + else break; + + } + + if (!merge_stack.empty() || n == rn) { + break; + } + } + } + + void initFace(const Node& node, NodeData& node_data, + const OrderMap& order_map, const OrderList& order_list) { + int n = order_map[node]; + int rn = n + order_list.size(); + + node_data[n].next = node_data[n].prev = rn; + node_data[rn].next = node_data[rn].prev = n; + + node_data[n].visited = order_list.size(); + node_data[rn].visited = order_list.size(); + + } + + bool external(const Node& node, int rorder, + ChildLists& child_lists, AncestorMap& ancestor_map, + LowMap& low_map) { + Node child = child_lists[node].first; + + if (child != INVALID) { + if (low_map[child] < rorder) return true; + } + + if (ancestor_map[node] < rorder) return true; + + return false; + } + + bool pertinent(const Node& node, const EmbedArc& embed_arc, + const MergeRoots& merge_roots) { + return !merge_roots[node].empty() || embed_arc[node]; + } + + }; + + } + + /// \ingroup planar + /// + /// \brief Planarity checking of an undirected simple graph + /// + /// This function implements the Boyer-Myrvold algorithm for + /// planarity checking of an undirected simple graph. It is a simplified + /// version of the PlanarEmbedding algorithm class because neither + /// the embedding nor the Kuratowski subdivisons are computed. + template + bool checkPlanarity(const GR& graph) { + _planarity_bits::PlanarityChecking pc(graph); + return pc.run(); + } + + /// \ingroup planar + /// + /// \brief Planar embedding of an undirected simple graph + /// + /// This class implements the Boyer-Myrvold algorithm for planar + /// embedding of an undirected simple graph. The planar embedding is an + /// ordering of the outgoing edges of the nodes, which is a possible + /// configuration to draw the graph in the plane. If there is not + /// such ordering then the graph contains a K5 (full graph + /// with 5 nodes) or a K3,3 (complete bipartite graph on + /// 3 Red and 3 Blue nodes) subdivision. + /// + /// The current implementation calculates either an embedding or a + /// Kuratowski subdivision. The running time of the algorithm is O(n). + /// + /// \see PlanarDrawing, checkPlanarity() + template + class PlanarEmbedding { + private: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + const Graph& _graph; + typename Graph::template ArcMap _embedding; + + typename Graph::template EdgeMap _kuratowski; + + private: + + typedef typename Graph::template NodeMap PredMap; + + typedef typename Graph::template EdgeMap TreeMap; + + typedef typename Graph::template NodeMap OrderMap; + typedef std::vector OrderList; + + typedef typename Graph::template NodeMap LowMap; + typedef typename Graph::template NodeMap AncestorMap; + + typedef _planarity_bits::NodeDataNode NodeDataNode; + typedef std::vector NodeData; + + typedef _planarity_bits::ChildListNode ChildListNode; + typedef typename Graph::template NodeMap ChildLists; + + typedef typename Graph::template NodeMap > MergeRoots; + + typedef typename Graph::template NodeMap EmbedArc; + + typedef _planarity_bits::ArcListNode ArcListNode; + typedef typename Graph::template ArcMap ArcLists; + + typedef typename Graph::template NodeMap FlipMap; + + typedef typename Graph::template NodeMap TypeMap; + + enum IsolatorNodeType { + HIGHX = 6, LOWX = 7, + HIGHY = 8, LOWY = 9, + ROOT = 10, PERTINENT = 11, + INTERNAL = 12 + }; + + public: + + /// \brief The map type for storing the embedding + /// + /// The map type for storing the embedding. + /// \see embeddingMap() + typedef typename Graph::template ArcMap EmbeddingMap; + + /// \brief Constructor + /// + /// Constructor. + /// \pre The graph must be simple, i.e. it should not + /// contain parallel or loop arcs. + PlanarEmbedding(const Graph& graph) + : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {} + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// \param kuratowski If this parameter is set to \c false, then the + /// algorithm does not compute a Kuratowski subdivision. + /// \return \c true if the graph is planar. + bool run(bool kuratowski = true) { + typedef _planarity_bits::PlanarityVisitor Visitor; + + PredMap pred_map(_graph, INVALID); + TreeMap tree_map(_graph, false); + + OrderMap order_map(_graph, -1); + OrderList order_list; + + AncestorMap ancestor_map(_graph, -1); + LowMap low_map(_graph, -1); + + Visitor visitor(_graph, pred_map, tree_map, + order_map, order_list, ancestor_map, low_map); + DfsVisit visit(_graph, visitor); + visit.run(); + + ChildLists child_lists(_graph); + createChildLists(tree_map, order_map, low_map, child_lists); + + NodeData node_data(2 * order_list.size()); + + EmbedArc embed_arc(_graph, INVALID); + + MergeRoots merge_roots(_graph); + + ArcLists arc_lists(_graph); + + FlipMap flip_map(_graph, false); + + for (int i = order_list.size() - 1; i >= 0; --i) { + + Node node = order_list[i]; + + node_data[i].first = INVALID; + + Node source = node; + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && tree_map[e]) { + initFace(target, arc_lists, node_data, + pred_map, order_map, order_list); + } + } + + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && !tree_map[e]) { + embed_arc[target] = e; + walkUp(target, source, i, pred_map, low_map, + order_map, order_list, node_data, merge_roots); + } + } + + for (typename MergeRoots::Value::iterator it = + merge_roots[node].begin(); it != merge_roots[node].end(); ++it) { + int rn = *it; + walkDown(rn, i, node_data, arc_lists, flip_map, order_list, + child_lists, ancestor_map, low_map, embed_arc, merge_roots); + } + merge_roots[node].clear(); + + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && !tree_map[e]) { + if (embed_arc[target] != INVALID) { + if (kuratowski) { + isolateKuratowski(e, node_data, arc_lists, flip_map, + order_map, order_list, pred_map, child_lists, + ancestor_map, low_map, + embed_arc, merge_roots); + } + return false; + } + } + } + } + + for (int i = 0; i < int(order_list.size()); ++i) { + + mergeRemainingFaces(order_list[i], node_data, order_list, order_map, + child_lists, arc_lists); + storeEmbedding(order_list[i], node_data, order_map, pred_map, + arc_lists, flip_map); + } + + return true; + } + + /// \brief Give back the successor of an arc + /// + /// This function gives back the successor of an arc. It makes + /// possible to query the cyclic order of the outgoing arcs from + /// a node. + Arc next(const Arc& arc) const { + return _embedding[arc]; + } + + /// \brief Give back the calculated embedding map + /// + /// This function gives back the calculated embedding map, which + /// contains the successor of each arc in the cyclic order of the + /// outgoing arcs of its source node. + const EmbeddingMap& embeddingMap() const { + return _embedding; + } + + /// \brief Give back \c true if the given edge is in the Kuratowski + /// subdivision + /// + /// This function gives back \c true if the given edge is in the found + /// Kuratowski subdivision. + /// \pre The \c run() function must be called with \c true parameter + /// before using this function. + bool kuratowski(const Edge& edge) const { + return _kuratowski[edge]; + } + + private: + + void createChildLists(const TreeMap& tree_map, const OrderMap& order_map, + const LowMap& low_map, ChildLists& child_lists) { + + for (NodeIt n(_graph); n != INVALID; ++n) { + Node source = n; + + std::vector targets; + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node target = _graph.target(e); + + if (order_map[source] < order_map[target] && tree_map[e]) { + targets.push_back(target); + } + } + + if (targets.size() == 0) { + child_lists[source].first = INVALID; + } else if (targets.size() == 1) { + child_lists[source].first = targets[0]; + child_lists[targets[0]].prev = INVALID; + child_lists[targets[0]].next = INVALID; + } else { + radixSort(targets.begin(), targets.end(), mapToFunctor(low_map)); + for (int i = 1; i < int(targets.size()); ++i) { + child_lists[targets[i]].prev = targets[i - 1]; + child_lists[targets[i - 1]].next = targets[i]; + } + child_lists[targets.back()].next = INVALID; + child_lists[targets.front()].prev = INVALID; + child_lists[source].first = targets.front(); + } + } + } + + void walkUp(const Node& node, Node root, int rorder, + const PredMap& pred_map, const LowMap& low_map, + const OrderMap& order_map, const OrderList& order_list, + NodeData& node_data, MergeRoots& merge_roots) { + + int na, nb; + bool da, db; + + na = nb = order_map[node]; + da = true; db = false; + + while (true) { + + if (node_data[na].visited == rorder) break; + if (node_data[nb].visited == rorder) break; + + node_data[na].visited = rorder; + node_data[nb].visited = rorder; + + int rn = -1; + + if (na >= int(order_list.size())) { + rn = na; + } else if (nb >= int(order_list.size())) { + rn = nb; + } + + if (rn == -1) { + int nn; + + nn = da ? node_data[na].prev : node_data[na].next; + da = node_data[nn].prev != na; + na = nn; + + nn = db ? node_data[nb].prev : node_data[nb].next; + db = node_data[nn].prev != nb; + nb = nn; + + } else { + + Node rep = order_list[rn - order_list.size()]; + Node parent = _graph.source(pred_map[rep]); + + if (low_map[rep] < rorder) { + merge_roots[parent].push_back(rn); + } else { + merge_roots[parent].push_front(rn); + } + + if (parent != root) { + na = nb = order_map[parent]; + da = true; db = false; + } else { + break; + } + } + } + } + + void walkDown(int rn, int rorder, NodeData& node_data, + ArcLists& arc_lists, FlipMap& flip_map, + OrderList& order_list, ChildLists& child_lists, + AncestorMap& ancestor_map, LowMap& low_map, + EmbedArc& embed_arc, MergeRoots& merge_roots) { + + std::vector > merge_stack; + + for (int di = 0; di < 2; ++di) { + bool rd = di == 0; + int pn = rn; + int n = rd ? node_data[rn].next : node_data[rn].prev; + + while (n != rn) { + + Node node = order_list[n]; + + if (embed_arc[node] != INVALID) { + + // Merging components on the critical path + while (!merge_stack.empty()) { + + // Component root + int cn = merge_stack.back().first; + bool cd = merge_stack.back().second; + merge_stack.pop_back(); + + // Parent of component + int dn = merge_stack.back().first; + bool dd = merge_stack.back().second; + merge_stack.pop_back(); + + Node parent = order_list[dn]; + + // Erasing from merge_roots + merge_roots[parent].pop_front(); + + Node child = order_list[cn - order_list.size()]; + + // Erasing from child_lists + if (child_lists[child].prev != INVALID) { + child_lists[child_lists[child].prev].next = + child_lists[child].next; + } else { + child_lists[parent].first = child_lists[child].next; + } + + if (child_lists[child].next != INVALID) { + child_lists[child_lists[child].next].prev = + child_lists[child].prev; + } + + // Merging arcs + flipping + Arc de = node_data[dn].first; + Arc ce = node_data[cn].first; + + flip_map[order_list[cn - order_list.size()]] = cd != dd; + if (cd != dd) { + std::swap(arc_lists[ce].prev, arc_lists[ce].next); + ce = arc_lists[ce].prev; + std::swap(arc_lists[ce].prev, arc_lists[ce].next); + } + + { + Arc dne = arc_lists[de].next; + Arc cne = arc_lists[ce].next; + + arc_lists[de].next = cne; + arc_lists[ce].next = dne; + + arc_lists[dne].prev = ce; + arc_lists[cne].prev = de; + } + + if (dd) { + node_data[dn].first = ce; + } + + // Merging external faces + { + int en = cn; + cn = cd ? node_data[cn].prev : node_data[cn].next; + cd = node_data[cn].next == en; + + if (node_data[cn].prev == node_data[cn].next && + node_data[cn].inverted) { + cd = !cd; + } + } + + if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn; + if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn; + + } + + bool d = pn == node_data[n].prev; + + if (node_data[n].prev == node_data[n].next && + node_data[n].inverted) { + d = !d; + } + + // Add new arc + { + Arc arc = embed_arc[node]; + Arc re = node_data[rn].first; + + arc_lists[arc_lists[re].next].prev = arc; + arc_lists[arc].next = arc_lists[re].next; + arc_lists[arc].prev = re; + arc_lists[re].next = arc; + + if (!rd) { + node_data[rn].first = arc; + } + + Arc rev = _graph.oppositeArc(arc); + Arc e = node_data[n].first; + + arc_lists[arc_lists[e].next].prev = rev; + arc_lists[rev].next = arc_lists[e].next; + arc_lists[rev].prev = e; + arc_lists[e].next = rev; + + if (d) { + node_data[n].first = rev; + } + + } + + // Embedding arc into external face + if (rd) node_data[rn].next = n; else node_data[rn].prev = n; + if (d) node_data[n].prev = rn; else node_data[n].next = rn; + pn = rn; + + embed_arc[order_list[n]] = INVALID; + } + + if (!merge_roots[node].empty()) { + + bool d = pn == node_data[n].prev; + if (node_data[n].prev == node_data[n].next && + node_data[n].inverted) { + d = !d; + } + + merge_stack.push_back(std::make_pair(n, d)); + + int rn = merge_roots[node].front(); + + int xn = node_data[rn].next; + Node xnode = order_list[xn]; + + int yn = node_data[rn].prev; + Node ynode = order_list[yn]; + + bool rd; + if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) { + rd = true; + } else if (!external(ynode, rorder, child_lists, + ancestor_map, low_map)) { + rd = false; + } else if (pertinent(xnode, embed_arc, merge_roots)) { + rd = true; + } else { + rd = false; + } + + merge_stack.push_back(std::make_pair(rn, rd)); + + pn = rn; + n = rd ? xn : yn; + + } else if (!external(node, rorder, child_lists, + ancestor_map, low_map)) { + int nn = (node_data[n].next != pn ? + node_data[n].next : node_data[n].prev); + + bool nd = n == node_data[nn].prev; + + if (nd) node_data[nn].prev = pn; + else node_data[nn].next = pn; + + if (n == node_data[pn].prev) node_data[pn].prev = nn; + else node_data[pn].next = nn; + + node_data[nn].inverted = + (node_data[nn].prev == node_data[nn].next && nd != rd); + + n = nn; + } + else break; + + } + + if (!merge_stack.empty() || n == rn) { + break; + } + } + } + + void initFace(const Node& node, ArcLists& arc_lists, + NodeData& node_data, const PredMap& pred_map, + const OrderMap& order_map, const OrderList& order_list) { + int n = order_map[node]; + int rn = n + order_list.size(); + + node_data[n].next = node_data[n].prev = rn; + node_data[rn].next = node_data[rn].prev = n; + + node_data[n].visited = order_list.size(); + node_data[rn].visited = order_list.size(); + + node_data[n].inverted = false; + node_data[rn].inverted = false; + + Arc arc = pred_map[node]; + Arc rev = _graph.oppositeArc(arc); + + node_data[rn].first = arc; + node_data[n].first = rev; + + arc_lists[arc].prev = arc; + arc_lists[arc].next = arc; + + arc_lists[rev].prev = rev; + arc_lists[rev].next = rev; + + } + + void mergeRemainingFaces(const Node& node, NodeData& node_data, + OrderList& order_list, OrderMap& order_map, + ChildLists& child_lists, ArcLists& arc_lists) { + while (child_lists[node].first != INVALID) { + int dd = order_map[node]; + Node child = child_lists[node].first; + int cd = order_map[child] + order_list.size(); + child_lists[node].first = child_lists[child].next; + + Arc de = node_data[dd].first; + Arc ce = node_data[cd].first; + + if (de != INVALID) { + Arc dne = arc_lists[de].next; + Arc cne = arc_lists[ce].next; + + arc_lists[de].next = cne; + arc_lists[ce].next = dne; + + arc_lists[dne].prev = ce; + arc_lists[cne].prev = de; + } + + node_data[dd].first = ce; + + } + } + + void storeEmbedding(const Node& node, NodeData& node_data, + OrderMap& order_map, PredMap& pred_map, + ArcLists& arc_lists, FlipMap& flip_map) { + + if (node_data[order_map[node]].first == INVALID) return; + + if (pred_map[node] != INVALID) { + Node source = _graph.source(pred_map[node]); + flip_map[node] = flip_map[node] != flip_map[source]; + } + + Arc first = node_data[order_map[node]].first; + Arc prev = first; + + Arc arc = flip_map[node] ? + arc_lists[prev].prev : arc_lists[prev].next; + + _embedding[prev] = arc; + + while (arc != first) { + Arc next = arc_lists[arc].prev == prev ? + arc_lists[arc].next : arc_lists[arc].prev; + prev = arc; arc = next; + _embedding[prev] = arc; + } + } + + + bool external(const Node& node, int rorder, + ChildLists& child_lists, AncestorMap& ancestor_map, + LowMap& low_map) { + Node child = child_lists[node].first; + + if (child != INVALID) { + if (low_map[child] < rorder) return true; + } + + if (ancestor_map[node] < rorder) return true; + + return false; + } + + bool pertinent(const Node& node, const EmbedArc& embed_arc, + const MergeRoots& merge_roots) { + return !merge_roots[node].empty() || embed_arc[node] != INVALID; + } + + int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists, + AncestorMap& ancestor_map, LowMap& low_map) { + int low_point; + + Node child = child_lists[node].first; + + if (child != INVALID) { + low_point = low_map[child]; + } else { + low_point = order_map[node]; + } + + if (low_point > ancestor_map[node]) { + low_point = ancestor_map[node]; + } + + return low_point; + } + + int findComponentRoot(Node root, Node node, ChildLists& child_lists, + OrderMap& order_map, OrderList& order_list) { + + int order = order_map[root]; + int norder = order_map[node]; + + Node child = child_lists[root].first; + while (child != INVALID) { + int corder = order_map[child]; + if (corder > order && corder < norder) { + order = corder; + } + child = child_lists[child].next; + } + return order + order_list.size(); + } + + Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data, + EmbedArc& embed_arc, MergeRoots& merge_roots) { + Node wnode =_graph.target(node_data[order_map[node]].first); + while (!pertinent(wnode, embed_arc, merge_roots)) { + wnode = _graph.target(node_data[order_map[wnode]].first); + } + return wnode; + } + + + Node findExternal(Node node, int rorder, OrderMap& order_map, + ChildLists& child_lists, AncestorMap& ancestor_map, + LowMap& low_map, NodeData& node_data) { + Node wnode =_graph.target(node_data[order_map[node]].first); + while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) { + wnode = _graph.target(node_data[order_map[wnode]].first); + } + return wnode; + } + + void markCommonPath(Node node, int rorder, Node& wnode, Node& znode, + OrderList& order_list, OrderMap& order_map, + NodeData& node_data, ArcLists& arc_lists, + EmbedArc& embed_arc, MergeRoots& merge_roots, + ChildLists& child_lists, AncestorMap& ancestor_map, + LowMap& low_map) { + + Node cnode = node; + Node pred = INVALID; + + while (true) { + + bool pert = pertinent(cnode, embed_arc, merge_roots); + bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map); + + if (pert && ext) { + if (!merge_roots[cnode].empty()) { + int cn = merge_roots[cnode].back(); + + if (low_map[order_list[cn - order_list.size()]] < rorder) { + Arc arc = node_data[cn].first; + _kuratowski.set(arc, true); + + pred = cnode; + cnode = _graph.target(arc); + + continue; + } + } + wnode = znode = cnode; + return; + + } else if (pert) { + wnode = cnode; + + while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) { + Arc arc = node_data[order_map[cnode]].first; + + if (_graph.target(arc) == pred) { + arc = arc_lists[arc].next; + } + _kuratowski.set(arc, true); + + Node next = _graph.target(arc); + pred = cnode; cnode = next; + } + + znode = cnode; + return; + + } else if (ext) { + znode = cnode; + + while (!pertinent(cnode, embed_arc, merge_roots)) { + Arc arc = node_data[order_map[cnode]].first; + + if (_graph.target(arc) == pred) { + arc = arc_lists[arc].next; + } + _kuratowski.set(arc, true); + + Node next = _graph.target(arc); + pred = cnode; cnode = next; + } + + wnode = cnode; + return; + + } else { + Arc arc = node_data[order_map[cnode]].first; + + if (_graph.target(arc) == pred) { + arc = arc_lists[arc].next; + } + _kuratowski.set(arc, true); + + Node next = _graph.target(arc); + pred = cnode; cnode = next; + } + + } + + } + + void orientComponent(Node root, int rn, OrderMap& order_map, + PredMap& pred_map, NodeData& node_data, + ArcLists& arc_lists, FlipMap& flip_map, + TypeMap& type_map) { + node_data[order_map[root]].first = node_data[rn].first; + type_map[root] = 1; + + std::vector st, qu; + + st.push_back(root); + while (!st.empty()) { + Node node = st.back(); + st.pop_back(); + qu.push_back(node); + + Arc arc = node_data[order_map[node]].first; + + if (type_map[_graph.target(arc)] == 0) { + st.push_back(_graph.target(arc)); + type_map[_graph.target(arc)] = 1; + } + + Arc last = arc, pred = arc; + arc = arc_lists[arc].next; + while (arc != last) { + + if (type_map[_graph.target(arc)] == 0) { + st.push_back(_graph.target(arc)); + type_map[_graph.target(arc)] = 1; + } + + Arc next = arc_lists[arc].next != pred ? + arc_lists[arc].next : arc_lists[arc].prev; + pred = arc; arc = next; + } + + } + + type_map[root] = 2; + flip_map[root] = false; + + for (int i = 1; i < int(qu.size()); ++i) { + + Node node = qu[i]; + + while (type_map[node] != 2) { + st.push_back(node); + type_map[node] = 2; + node = _graph.source(pred_map[node]); + } + + bool flip = flip_map[node]; + + while (!st.empty()) { + node = st.back(); + st.pop_back(); + + flip_map[node] = flip != flip_map[node]; + flip = flip_map[node]; + + if (flip) { + Arc arc = node_data[order_map[node]].first; + std::swap(arc_lists[arc].prev, arc_lists[arc].next); + arc = arc_lists[arc].prev; + std::swap(arc_lists[arc].prev, arc_lists[arc].next); + node_data[order_map[node]].first = arc; + } + } + } + + for (int i = 0; i < int(qu.size()); ++i) { + + Arc arc = node_data[order_map[qu[i]]].first; + Arc last = arc, pred = arc; + + arc = arc_lists[arc].next; + while (arc != last) { + + if (arc_lists[arc].next == pred) { + std::swap(arc_lists[arc].next, arc_lists[arc].prev); + } + pred = arc; arc = arc_lists[arc].next; + } + + } + } + + void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode, + OrderMap& order_map, NodeData& node_data, + TypeMap& type_map) { + Node node = _graph.target(node_data[order_map[root]].first); + + while (node != ynode) { + type_map[node] = HIGHY; + node = _graph.target(node_data[order_map[node]].first); + } + + while (node != wnode) { + type_map[node] = LOWY; + node = _graph.target(node_data[order_map[node]].first); + } + + node = _graph.target(node_data[order_map[wnode]].first); + + while (node != xnode) { + type_map[node] = LOWX; + node = _graph.target(node_data[order_map[node]].first); + } + type_map[node] = LOWX; + + node = _graph.target(node_data[order_map[xnode]].first); + while (node != root) { + type_map[node] = HIGHX; + node = _graph.target(node_data[order_map[node]].first); + } + + type_map[wnode] = PERTINENT; + type_map[root] = ROOT; + } + + void findInternalPath(std::vector& ipath, + Node wnode, Node root, TypeMap& type_map, + OrderMap& order_map, NodeData& node_data, + ArcLists& arc_lists) { + std::vector st; + + Node node = wnode; + + while (node != root) { + Arc arc = arc_lists[node_data[order_map[node]].first].next; + st.push_back(arc); + node = _graph.target(arc); + } + + while (true) { + Arc arc = st.back(); + if (type_map[_graph.target(arc)] == LOWX || + type_map[_graph.target(arc)] == HIGHX) { + break; + } + if (type_map[_graph.target(arc)] == 2) { + type_map[_graph.target(arc)] = 3; + + arc = arc_lists[_graph.oppositeArc(arc)].next; + st.push_back(arc); + } else { + st.pop_back(); + arc = arc_lists[arc].next; + + while (_graph.oppositeArc(arc) == st.back()) { + arc = st.back(); + st.pop_back(); + arc = arc_lists[arc].next; + } + st.push_back(arc); + } + } + + for (int i = 0; i < int(st.size()); ++i) { + if (type_map[_graph.target(st[i])] != LOWY && + type_map[_graph.target(st[i])] != HIGHY) { + for (; i < int(st.size()); ++i) { + ipath.push_back(st[i]); + } + } + } + } + + void setInternalFlags(std::vector& ipath, TypeMap& type_map) { + for (int i = 1; i < int(ipath.size()); ++i) { + type_map[_graph.source(ipath[i])] = INTERNAL; + } + } + + void findPilePath(std::vector& ppath, + Node root, TypeMap& type_map, OrderMap& order_map, + NodeData& node_data, ArcLists& arc_lists) { + std::vector st; + + st.push_back(_graph.oppositeArc(node_data[order_map[root]].first)); + st.push_back(node_data[order_map[root]].first); + + while (st.size() > 1) { + Arc arc = st.back(); + if (type_map[_graph.target(arc)] == INTERNAL) { + break; + } + if (type_map[_graph.target(arc)] == 3) { + type_map[_graph.target(arc)] = 4; + + arc = arc_lists[_graph.oppositeArc(arc)].next; + st.push_back(arc); + } else { + st.pop_back(); + arc = arc_lists[arc].next; + + while (!st.empty() && _graph.oppositeArc(arc) == st.back()) { + arc = st.back(); + st.pop_back(); + arc = arc_lists[arc].next; + } + st.push_back(arc); + } + } + + for (int i = 1; i < int(st.size()); ++i) { + ppath.push_back(st[i]); + } + } + + + int markExternalPath(Node node, OrderMap& order_map, + ChildLists& child_lists, PredMap& pred_map, + AncestorMap& ancestor_map, LowMap& low_map) { + int lp = lowPoint(node, order_map, child_lists, + ancestor_map, low_map); + + if (ancestor_map[node] != lp) { + node = child_lists[node].first; + _kuratowski[pred_map[node]] = true; + + while (ancestor_map[node] != lp) { + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + Node tnode = _graph.target(e); + if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) { + node = tnode; + _kuratowski[e] = true; + break; + } + } + } + } + + for (OutArcIt e(_graph, node); e != INVALID; ++e) { + if (order_map[_graph.target(e)] == lp) { + _kuratowski[e] = true; + break; + } + } + + return lp; + } + + void markPertinentPath(Node node, OrderMap& order_map, + NodeData& node_data, ArcLists& arc_lists, + EmbedArc& embed_arc, MergeRoots& merge_roots) { + while (embed_arc[node] == INVALID) { + int n = merge_roots[node].front(); + Arc arc = node_data[n].first; + + _kuratowski.set(arc, true); + + Node pred = node; + node = _graph.target(arc); + while (!pertinent(node, embed_arc, merge_roots)) { + arc = node_data[order_map[node]].first; + if (_graph.target(arc) == pred) { + arc = arc_lists[arc].next; + } + _kuratowski.set(arc, true); + pred = node; + node = _graph.target(arc); + } + } + _kuratowski.set(embed_arc[node], true); + } + + void markPredPath(Node node, Node snode, PredMap& pred_map) { + while (node != snode) { + _kuratowski.set(pred_map[node], true); + node = _graph.source(pred_map[node]); + } + } + + void markFacePath(Node ynode, Node xnode, + OrderMap& order_map, NodeData& node_data) { + Arc arc = node_data[order_map[ynode]].first; + Node node = _graph.target(arc); + _kuratowski.set(arc, true); + + while (node != xnode) { + arc = node_data[order_map[node]].first; + _kuratowski.set(arc, true); + node = _graph.target(arc); + } + } + + void markInternalPath(std::vector& path) { + for (int i = 0; i < int(path.size()); ++i) { + _kuratowski.set(path[i], true); + } + } + + void markPilePath(std::vector& path) { + for (int i = 0; i < int(path.size()); ++i) { + _kuratowski.set(path[i], true); + } + } + + void isolateKuratowski(Arc arc, NodeData& node_data, + ArcLists& arc_lists, FlipMap& flip_map, + OrderMap& order_map, OrderList& order_list, + PredMap& pred_map, ChildLists& child_lists, + AncestorMap& ancestor_map, LowMap& low_map, + EmbedArc& embed_arc, MergeRoots& merge_roots) { + + Node root = _graph.source(arc); + Node enode = _graph.target(arc); + + int rorder = order_map[root]; + + TypeMap type_map(_graph, 0); + + int rn = findComponentRoot(root, enode, child_lists, + order_map, order_list); + + Node xnode = order_list[node_data[rn].next]; + Node ynode = order_list[node_data[rn].prev]; + + // Minor-A + { + while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) { + + if (!merge_roots[xnode].empty()) { + root = xnode; + rn = merge_roots[xnode].front(); + } else { + root = ynode; + rn = merge_roots[ynode].front(); + } + + xnode = order_list[node_data[rn].next]; + ynode = order_list[node_data[rn].prev]; + } + + if (root != _graph.source(arc)) { + orientComponent(root, rn, order_map, pred_map, + node_data, arc_lists, flip_map, type_map); + markFacePath(root, root, order_map, node_data); + int xlp = markExternalPath(xnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int ylp = markExternalPath(ynode, order_map, child_lists, + pred_map, ancestor_map, low_map); + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map); + Node lwnode = findPertinent(ynode, order_map, node_data, + embed_arc, merge_roots); + + markPertinentPath(lwnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + + return; + } + } + + orientComponent(root, rn, order_map, pred_map, + node_data, arc_lists, flip_map, type_map); + + Node wnode = findPertinent(ynode, order_map, node_data, + embed_arc, merge_roots); + setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map); + + + //Minor-B + if (!merge_roots[wnode].empty()) { + int cn = merge_roots[wnode].back(); + Node rep = order_list[cn - order_list.size()]; + if (low_map[rep] < rorder) { + markFacePath(root, root, order_map, node_data); + int xlp = markExternalPath(xnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int ylp = markExternalPath(ynode, order_map, child_lists, + pred_map, ancestor_map, low_map); + + Node lwnode, lznode; + markCommonPath(wnode, rorder, lwnode, lznode, order_list, + order_map, node_data, arc_lists, embed_arc, + merge_roots, child_lists, ancestor_map, low_map); + + markPertinentPath(lwnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + int zlp = markExternalPath(lznode, order_map, child_lists, + pred_map, ancestor_map, low_map); + + int minlp = xlp < ylp ? xlp : ylp; + if (zlp < minlp) minlp = zlp; + + int maxlp = xlp > ylp ? xlp : ylp; + if (zlp > maxlp) maxlp = zlp; + + markPredPath(order_list[maxlp], order_list[minlp], pred_map); + + return; + } + } + + Node pxnode, pynode; + std::vector ipath; + findInternalPath(ipath, wnode, root, type_map, order_map, + node_data, arc_lists); + setInternalFlags(ipath, type_map); + pynode = _graph.source(ipath.front()); + pxnode = _graph.target(ipath.back()); + + wnode = findPertinent(pynode, order_map, node_data, + embed_arc, merge_roots); + + // Minor-C + { + if (type_map[_graph.source(ipath.front())] == HIGHY) { + if (type_map[_graph.target(ipath.back())] == HIGHX) { + markFacePath(xnode, pxnode, order_map, node_data); + } + markFacePath(root, xnode, order_map, node_data); + markPertinentPath(wnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + markInternalPath(ipath); + int xlp = markExternalPath(xnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int ylp = markExternalPath(ynode, order_map, child_lists, + pred_map, ancestor_map, low_map); + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map); + return; + } + + if (type_map[_graph.target(ipath.back())] == HIGHX) { + markFacePath(ynode, root, order_map, node_data); + markPertinentPath(wnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + markInternalPath(ipath); + int xlp = markExternalPath(xnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int ylp = markExternalPath(ynode, order_map, child_lists, + pred_map, ancestor_map, low_map); + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map); + return; + } + } + + std::vector ppath; + findPilePath(ppath, root, type_map, order_map, node_data, arc_lists); + + // Minor-D + if (!ppath.empty()) { + markFacePath(ynode, xnode, order_map, node_data); + markPertinentPath(wnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + markPilePath(ppath); + markInternalPath(ipath); + int xlp = markExternalPath(xnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int ylp = markExternalPath(ynode, order_map, child_lists, + pred_map, ancestor_map, low_map); + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map); + return; + } + + // Minor-E* + { + + if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) { + Node znode = findExternal(pynode, rorder, order_map, + child_lists, ancestor_map, + low_map, node_data); + + if (type_map[znode] == LOWY) { + markFacePath(root, xnode, order_map, node_data); + markPertinentPath(wnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + markInternalPath(ipath); + int xlp = markExternalPath(xnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int zlp = markExternalPath(znode, order_map, child_lists, + pred_map, ancestor_map, low_map); + markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map); + } else { + markFacePath(ynode, root, order_map, node_data); + markPertinentPath(wnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + markInternalPath(ipath); + int ylp = markExternalPath(ynode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int zlp = markExternalPath(znode, order_map, child_lists, + pred_map, ancestor_map, low_map); + markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map); + } + return; + } + + int xlp = markExternalPath(xnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int ylp = markExternalPath(ynode, order_map, child_lists, + pred_map, ancestor_map, low_map); + int wlp = markExternalPath(wnode, order_map, child_lists, + pred_map, ancestor_map, low_map); + + if (wlp > xlp && wlp > ylp) { + markFacePath(root, root, order_map, node_data); + markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map); + return; + } + + markInternalPath(ipath); + markPertinentPath(wnode, order_map, node_data, arc_lists, + embed_arc, merge_roots); + + if (xlp > ylp && xlp > wlp) { + markFacePath(root, pynode, order_map, node_data); + markFacePath(wnode, xnode, order_map, node_data); + markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map); + return; + } + + if (ylp > xlp && ylp > wlp) { + markFacePath(pxnode, root, order_map, node_data); + markFacePath(ynode, wnode, order_map, node_data); + markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map); + return; + } + + if (pynode != ynode) { + markFacePath(pxnode, wnode, order_map, node_data); + + int minlp = xlp < ylp ? xlp : ylp; + if (wlp < minlp) minlp = wlp; + + int maxlp = xlp > ylp ? xlp : ylp; + if (wlp > maxlp) maxlp = wlp; + + markPredPath(order_list[maxlp], order_list[minlp], pred_map); + return; + } + + if (pxnode != xnode) { + markFacePath(wnode, pynode, order_map, node_data); + + int minlp = xlp < ylp ? xlp : ylp; + if (wlp < minlp) minlp = wlp; + + int maxlp = xlp > ylp ? xlp : ylp; + if (wlp > maxlp) maxlp = wlp; + + markPredPath(order_list[maxlp], order_list[minlp], pred_map); + return; + } + + markFacePath(root, root, order_map, node_data); + int minlp = xlp < ylp ? xlp : ylp; + if (wlp < minlp) minlp = wlp; + markPredPath(root, order_list[minlp], pred_map); + return; + } + + } + + }; + + namespace _planarity_bits { + + template + void makeConnected(Graph& graph, EmbeddingMap& embedding) { + DfsVisitor null_visitor; + DfsVisit > dfs(graph, null_visitor); + dfs.init(); + + typename Graph::Node u = INVALID; + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) { + if (!dfs.reached(n)) { + dfs.addSource(n); + dfs.start(); + if (u == INVALID) { + u = n; + } else { + typename Graph::Node v = n; + + typename Graph::Arc ue = typename Graph::OutArcIt(graph, u); + typename Graph::Arc ve = typename Graph::OutArcIt(graph, v); + + typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true); + + if (ue != INVALID) { + embedding[e] = embedding[ue]; + embedding[ue] = e; + } else { + embedding[e] = e; + } + + if (ve != INVALID) { + embedding[graph.oppositeArc(e)] = embedding[ve]; + embedding[ve] = graph.oppositeArc(e); + } else { + embedding[graph.oppositeArc(e)] = graph.oppositeArc(e); + } + } + } + } + } + + template + void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) { + typename Graph::template ArcMap processed(graph); + + std::vector arcs; + for (typename Graph::ArcIt e(graph); e != INVALID; ++e) { + arcs.push_back(e); + } + + IterableBoolMap visited(graph, false); + + for (int i = 0; i < int(arcs.size()); ++i) { + typename Graph::Arc pp = arcs[i]; + if (processed[pp]) continue; + + typename Graph::Arc e = embedding[graph.oppositeArc(pp)]; + processed[e] = true; + visited.set(graph.source(e), true); + + typename Graph::Arc p = e, l = e; + e = embedding[graph.oppositeArc(e)]; + + while (e != l) { + processed[e] = true; + + if (visited[graph.source(e)]) { + + typename Graph::Arc n = + graph.direct(graph.addEdge(graph.source(p), + graph.target(e)), true); + embedding[n] = p; + embedding[graph.oppositeArc(pp)] = n; + + embedding[graph.oppositeArc(n)] = + embedding[graph.oppositeArc(e)]; + embedding[graph.oppositeArc(e)] = + graph.oppositeArc(n); + + p = n; + e = embedding[graph.oppositeArc(n)]; + } else { + visited.set(graph.source(e), true); + pp = p; + p = e; + e = embedding[graph.oppositeArc(e)]; + } + } + visited.setAll(false); + } + } + + + template + void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) { + + typename Graph::template NodeMap degree(graph); + + for (typename Graph::NodeIt n(graph); n != INVALID; ++n) { + degree[n] = countIncEdges(graph, n); + } + + typename Graph::template ArcMap processed(graph); + IterableBoolMap visited(graph, false); + + std::vector arcs; + for (typename Graph::ArcIt e(graph); e != INVALID; ++e) { + arcs.push_back(e); + } + + for (int i = 0; i < int(arcs.size()); ++i) { + typename Graph::Arc e = arcs[i]; + + if (processed[e]) continue; + processed[e] = true; + + typename Graph::Arc mine = e; + int mind = degree[graph.source(e)]; + + int face_size = 1; + + typename Graph::Arc l = e; + e = embedding[graph.oppositeArc(e)]; + while (l != e) { + processed[e] = true; + + ++face_size; + + if (degree[graph.source(e)] < mind) { + mine = e; + mind = degree[graph.source(e)]; + } + + e = embedding[graph.oppositeArc(e)]; + } + + if (face_size < 4) { + continue; + } + + typename Graph::Node s = graph.source(mine); + for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) { + visited.set(graph.target(e), true); + } + + typename Graph::Arc oppe = INVALID; + + e = embedding[graph.oppositeArc(mine)]; + e = embedding[graph.oppositeArc(e)]; + while (graph.target(e) != s) { + if (visited[graph.source(e)]) { + oppe = e; + break; + } + e = embedding[graph.oppositeArc(e)]; + } + visited.setAll(false); + + if (oppe == INVALID) { + + e = embedding[graph.oppositeArc(mine)]; + typename Graph::Arc pn = mine, p = e; + + e = embedding[graph.oppositeArc(e)]; + while (graph.target(e) != s) { + typename Graph::Arc n = + graph.direct(graph.addEdge(s, graph.source(e)), true); + + embedding[n] = pn; + embedding[graph.oppositeArc(n)] = e; + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n); + + pn = n; + + p = e; + e = embedding[graph.oppositeArc(e)]; + } + + embedding[graph.oppositeArc(e)] = pn; + + } else { + + mine = embedding[graph.oppositeArc(mine)]; + s = graph.source(mine); + oppe = embedding[graph.oppositeArc(oppe)]; + typename Graph::Node t = graph.source(oppe); + + typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true); + embedding[ce] = mine; + embedding[graph.oppositeArc(ce)] = oppe; + + typename Graph::Arc pn = ce, p = oppe; + e = embedding[graph.oppositeArc(oppe)]; + while (graph.target(e) != s) { + typename Graph::Arc n = + graph.direct(graph.addEdge(s, graph.source(e)), true); + + embedding[n] = pn; + embedding[graph.oppositeArc(n)] = e; + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n); + + pn = n; + + p = e; + e = embedding[graph.oppositeArc(e)]; + + } + embedding[graph.oppositeArc(e)] = pn; + + pn = graph.oppositeArc(ce), p = mine; + e = embedding[graph.oppositeArc(mine)]; + while (graph.target(e) != t) { + typename Graph::Arc n = + graph.direct(graph.addEdge(t, graph.source(e)), true); + + embedding[n] = pn; + embedding[graph.oppositeArc(n)] = e; + embedding[graph.oppositeArc(p)] = graph.oppositeArc(n); + + pn = n; + + p = e; + e = embedding[graph.oppositeArc(e)]; + + } + embedding[graph.oppositeArc(e)] = pn; + } + } + } + + } + + /// \ingroup planar + /// + /// \brief Schnyder's planar drawing algorithm + /// + /// The planar drawing algorithm calculates positions for the nodes + /// in the plane. These coordinates satisfy that if the edges are + /// represented with straight lines, then they will not intersect + /// each other. + /// + /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid, + /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square. + /// The time complexity of the algorithm is O(n). + /// + /// \see PlanarEmbedding + template + class PlanarDrawing { + public: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + /// \brief The point type for storing coordinates + typedef dim2::Point Point; + /// \brief The map type for storing the coordinates of the nodes + typedef typename Graph::template NodeMap PointMap; + + + /// \brief Constructor + /// + /// Constructor + /// \pre The graph must be simple, i.e. it should not + /// contain parallel or loop arcs. + PlanarDrawing(const Graph& graph) + : _graph(graph), _point_map(graph) {} + + private: + + template + void drawing(const AuxGraph& graph, + const AuxEmbeddingMap& next, + PointMap& point_map) { + TEMPLATE_GRAPH_TYPEDEFS(AuxGraph); + + typename AuxGraph::template ArcMap prev(graph); + + for (NodeIt n(graph); n != INVALID; ++n) { + Arc e = OutArcIt(graph, n); + + Arc p = e, l = e; + + e = next[e]; + while (e != l) { + prev[e] = p; + p = e; + e = next[e]; + } + prev[e] = p; + } + + Node anode, bnode, cnode; + + { + Arc e = ArcIt(graph); + anode = graph.source(e); + bnode = graph.target(e); + cnode = graph.target(next[graph.oppositeArc(e)]); + } + + IterableBoolMap proper(graph, false); + typename AuxGraph::template NodeMap conn(graph, -1); + + conn[anode] = conn[bnode] = -2; + { + for (OutArcIt e(graph, anode); e != INVALID; ++e) { + Node m = graph.target(e); + if (conn[m] == -1) { + conn[m] = 1; + } + } + conn[cnode] = 2; + + for (OutArcIt e(graph, bnode); e != INVALID; ++e) { + Node m = graph.target(e); + if (conn[m] == -1) { + conn[m] = 1; + } else if (conn[m] != -2) { + conn[m] += 1; + Arc pe = graph.oppositeArc(e); + if (conn[graph.target(next[pe])] == -2) { + conn[m] -= 1; + } + if (conn[graph.target(prev[pe])] == -2) { + conn[m] -= 1; + } + + proper.set(m, conn[m] == 1); + } + } + } + + + typename AuxGraph::template ArcMap angle(graph, -1); + + while (proper.trueNum() != 0) { + Node n = typename IterableBoolMap::TrueIt(proper); + proper.set(n, false); + conn[n] = -2; + + for (OutArcIt e(graph, n); e != INVALID; ++e) { + Node m = graph.target(e); + if (conn[m] == -1) { + conn[m] = 1; + } else if (conn[m] != -2) { + conn[m] += 1; + Arc pe = graph.oppositeArc(e); + if (conn[graph.target(next[pe])] == -2) { + conn[m] -= 1; + } + if (conn[graph.target(prev[pe])] == -2) { + conn[m] -= 1; + } + + proper.set(m, conn[m] == 1); + } + } + + { + Arc e = OutArcIt(graph, n); + Arc p = e, l = e; + + e = next[e]; + while (e != l) { + + if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) { + Arc f = e; + angle[f] = 0; + f = next[graph.oppositeArc(f)]; + angle[f] = 1; + f = next[graph.oppositeArc(f)]; + angle[f] = 2; + } + + p = e; + e = next[e]; + } + + if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) { + Arc f = e; + angle[f] = 0; + f = next[graph.oppositeArc(f)]; + angle[f] = 1; + f = next[graph.oppositeArc(f)]; + angle[f] = 2; + } + } + } + + typename AuxGraph::template NodeMap apred(graph, INVALID); + typename AuxGraph::template NodeMap bpred(graph, INVALID); + typename AuxGraph::template NodeMap cpred(graph, INVALID); + + typename AuxGraph::template NodeMap apredid(graph, -1); + typename AuxGraph::template NodeMap bpredid(graph, -1); + typename AuxGraph::template NodeMap cpredid(graph, -1); + + for (ArcIt e(graph); e != INVALID; ++e) { + if (angle[e] == angle[next[e]]) { + switch (angle[e]) { + case 2: + apred[graph.target(e)] = graph.source(e); + apredid[graph.target(e)] = graph.id(graph.source(e)); + break; + case 1: + bpred[graph.target(e)] = graph.source(e); + bpredid[graph.target(e)] = graph.id(graph.source(e)); + break; + case 0: + cpred[graph.target(e)] = graph.source(e); + cpredid[graph.target(e)] = graph.id(graph.source(e)); + break; + } + } + } + + cpred[anode] = INVALID; + cpred[bnode] = INVALID; + + std::vector aorder, border, corder; + + { + typename AuxGraph::template NodeMap processed(graph, false); + std::vector st; + for (NodeIt n(graph); n != INVALID; ++n) { + if (!processed[n] && n != bnode && n != cnode) { + st.push_back(n); + processed[n] = true; + Node m = apred[n]; + while (m != INVALID && !processed[m]) { + st.push_back(m); + processed[m] = true; + m = apred[m]; + } + while (!st.empty()) { + aorder.push_back(st.back()); + st.pop_back(); + } + } + } + } + + { + typename AuxGraph::template NodeMap processed(graph, false); + std::vector st; + for (NodeIt n(graph); n != INVALID; ++n) { + if (!processed[n] && n != cnode && n != anode) { + st.push_back(n); + processed[n] = true; + Node m = bpred[n]; + while (m != INVALID && !processed[m]) { + st.push_back(m); + processed[m] = true; + m = bpred[m]; + } + while (!st.empty()) { + border.push_back(st.back()); + st.pop_back(); + } + } + } + } + + { + typename AuxGraph::template NodeMap processed(graph, false); + std::vector st; + for (NodeIt n(graph); n != INVALID; ++n) { + if (!processed[n] && n != anode && n != bnode) { + st.push_back(n); + processed[n] = true; + Node m = cpred[n]; + while (m != INVALID && !processed[m]) { + st.push_back(m); + processed[m] = true; + m = cpred[m]; + } + while (!st.empty()) { + corder.push_back(st.back()); + st.pop_back(); + } + } + } + } + + typename AuxGraph::template NodeMap atree(graph, 0); + for (int i = aorder.size() - 1; i >= 0; --i) { + Node n = aorder[i]; + atree[n] = 1; + for (OutArcIt e(graph, n); e != INVALID; ++e) { + if (apred[graph.target(e)] == n) { + atree[n] += atree[graph.target(e)]; + } + } + } + + typename AuxGraph::template NodeMap btree(graph, 0); + for (int i = border.size() - 1; i >= 0; --i) { + Node n = border[i]; + btree[n] = 1; + for (OutArcIt e(graph, n); e != INVALID; ++e) { + if (bpred[graph.target(e)] == n) { + btree[n] += btree[graph.target(e)]; + } + } + } + + typename AuxGraph::template NodeMap apath(graph, 0); + apath[bnode] = apath[cnode] = 1; + typename AuxGraph::template NodeMap apath_btree(graph, 0); + apath_btree[bnode] = btree[bnode]; + for (int i = 1; i < int(aorder.size()); ++i) { + Node n = aorder[i]; + apath[n] = apath[apred[n]] + 1; + apath_btree[n] = btree[n] + apath_btree[apred[n]]; + } + + typename AuxGraph::template NodeMap bpath_atree(graph, 0); + bpath_atree[anode] = atree[anode]; + for (int i = 1; i < int(border.size()); ++i) { + Node n = border[i]; + bpath_atree[n] = atree[n] + bpath_atree[bpred[n]]; + } + + typename AuxGraph::template NodeMap cpath(graph, 0); + cpath[anode] = cpath[bnode] = 1; + typename AuxGraph::template NodeMap cpath_atree(graph, 0); + cpath_atree[anode] = atree[anode]; + typename AuxGraph::template NodeMap cpath_btree(graph, 0); + cpath_btree[bnode] = btree[bnode]; + for (int i = 1; i < int(corder.size()); ++i) { + Node n = corder[i]; + cpath[n] = cpath[cpred[n]] + 1; + cpath_atree[n] = atree[n] + cpath_atree[cpred[n]]; + cpath_btree[n] = btree[n] + cpath_btree[cpred[n]]; + } + + typename AuxGraph::template NodeMap third(graph); + for (NodeIt n(graph); n != INVALID; ++n) { + point_map[n].x = + bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1; + point_map[n].y = + cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1; + } + + } + + public: + + /// \brief Calculate the node positions + /// + /// This function calculates the node positions on the plane. + /// \return \c true if the graph is planar. + bool run() { + PlanarEmbedding pe(_graph); + if (!pe.run()) return false; + + run(pe); + return true; + } + + /// \brief Calculate the node positions according to a + /// combinatorical embedding + /// + /// This function calculates the node positions on the plane. + /// The given \c embedding map should contain a valid combinatorical + /// embedding, i.e. a valid cyclic order of the arcs. + /// It can be computed using PlanarEmbedding. + template + void run(const EmbeddingMap& embedding) { + typedef SmartEdgeSet AuxGraph; + + if (3 * countNodes(_graph) - 6 == countEdges(_graph)) { + drawing(_graph, embedding, _point_map); + return; + } + + AuxGraph aux_graph(_graph); + typename AuxGraph::template ArcMap + aux_embedding(aux_graph); + + { + + typename Graph::template EdgeMap + ref(_graph); + + for (EdgeIt e(_graph); e != INVALID; ++e) { + ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e)); + } + + for (EdgeIt e(_graph); e != INVALID; ++e) { + Arc ee = embedding[_graph.direct(e, true)]; + aux_embedding[aux_graph.direct(ref[e], true)] = + aux_graph.direct(ref[ee], _graph.direction(ee)); + ee = embedding[_graph.direct(e, false)]; + aux_embedding[aux_graph.direct(ref[e], false)] = + aux_graph.direct(ref[ee], _graph.direction(ee)); + } + } + _planarity_bits::makeConnected(aux_graph, aux_embedding); + _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding); + _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding); + drawing(aux_graph, aux_embedding, _point_map); + } + + /// \brief The coordinate of the given node + /// + /// This function returns the coordinate of the given node. + Point operator[](const Node& node) const { + return _point_map[node]; + } + + /// \brief Return the grid embedding in a node map + /// + /// This function returns the grid embedding in a node map of + /// \c dim2::Point coordinates. + const PointMap& coords() const { + return _point_map; + } + + private: + + const Graph& _graph; + PointMap _point_map; + + }; + + namespace _planarity_bits { + + template + class KempeFilter { + public: + typedef typename ColorMap::Key Key; + typedef bool Value; + + KempeFilter(const ColorMap& color_map, + const typename ColorMap::Value& first, + const typename ColorMap::Value& second) + : _color_map(color_map), _first(first), _second(second) {} + + Value operator[](const Key& key) const { + return _color_map[key] == _first || _color_map[key] == _second; + } + + private: + const ColorMap& _color_map; + typename ColorMap::Value _first, _second; + }; + } + + /// \ingroup planar + /// + /// \brief Coloring planar graphs + /// + /// The graph coloring problem is the coloring of the graph nodes + /// so that there are no adjacent nodes with the same color. The + /// planar graphs can always be colored with four colors, which is + /// proved by Appel and Haken. Their proofs provide a quadratic + /// time algorithm for four coloring, but it could not be used to + /// implement an efficient algorithm. The five and six coloring can be + /// made in linear time, but in this class, the five coloring has + /// quadratic worst case time complexity. The two coloring (if + /// possible) is solvable with a graph search algorithm and it is + /// implemented in \ref bipartitePartitions() function in LEMON. To + /// decide whether a planar graph is three colorable is NP-complete. + /// + /// This class contains member functions for calculate colorings + /// with five and six colors. The six coloring algorithm is a simple + /// greedy coloring on the backward minimum outgoing order of nodes. + /// This order can be computed by selecting the node with least + /// outgoing arcs to unprocessed nodes in each phase. This order + /// guarantees that when a node is chosen for coloring it has at + /// most five already colored adjacents. The five coloring algorithm + /// use the same method, but if the greedy approach fails to color + /// with five colors, i.e. the node has five already different + /// colored neighbours, it swaps the colors in one of the connected + /// two colored sets with the Kempe recoloring method. + template + class PlanarColoring { + public: + + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + /// \brief The map type for storing color indices + typedef typename Graph::template NodeMap IndexMap; + /// \brief The map type for storing colors + /// + /// The map type for storing colors. + /// \see Palette, Color + typedef ComposeMap ColorMap; + + /// \brief Constructor + /// + /// Constructor. + /// \pre The graph must be simple, i.e. it should not + /// contain parallel or loop arcs. + PlanarColoring(const Graph& graph) + : _graph(graph), _color_map(graph), _palette(0) { + _palette.add(Color(1,0,0)); + _palette.add(Color(0,1,0)); + _palette.add(Color(0,0,1)); + _palette.add(Color(1,1,0)); + _palette.add(Color(1,0,1)); + _palette.add(Color(0,1,1)); + } + + /// \brief Return the node map of color indices + /// + /// This function returns the node map of color indices. The values are + /// in the range \c [0..4] or \c [0..5] according to the coloring method. + IndexMap colorIndexMap() const { + return _color_map; + } + + /// \brief Return the node map of colors + /// + /// This function returns the node map of colors. The values are among + /// five or six distinct \ref lemon::Color "colors". + ColorMap colorMap() const { + return composeMap(_palette, _color_map); + } + + /// \brief Return the color index of the node + /// + /// This function returns the color index of the given node. The value is + /// in the range \c [0..4] or \c [0..5] according to the coloring method. + int colorIndex(const Node& node) const { + return _color_map[node]; + } + + /// \brief Return the color of the node + /// + /// This function returns the color of the given node. The value is among + /// five or six distinct \ref lemon::Color "colors". + Color color(const Node& node) const { + return _palette[_color_map[node]]; + } + + + /// \brief Calculate a coloring with at most six colors + /// + /// This function calculates a coloring with at most six colors. The time + /// complexity of this variant is linear in the size of the graph. + /// \return \c true if the algorithm could color the graph with six colors. + /// If the algorithm fails, then the graph is not planar. + /// \note This function can return \c true if the graph is not + /// planar, but it can be colored with at most six colors. + bool runSixColoring() { + + typename Graph::template NodeMap heap_index(_graph, -1); + BucketHeap > heap(heap_index); + + for (NodeIt n(_graph); n != INVALID; ++n) { + _color_map[n] = -2; + heap.push(n, countOutArcs(_graph, n)); + } + + std::vector order; + + while (!heap.empty()) { + Node n = heap.top(); + heap.pop(); + _color_map[n] = -1; + order.push_back(n); + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node t = _graph.runningNode(e); + if (_color_map[t] == -2) { + heap.decrease(t, heap[t] - 1); + } + } + } + + for (int i = order.size() - 1; i >= 0; --i) { + std::vector forbidden(6, false); + for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) { + Node t = _graph.runningNode(e); + if (_color_map[t] != -1) { + forbidden[_color_map[t]] = true; + } + } + for (int k = 0; k < 6; ++k) { + if (!forbidden[k]) { + _color_map[order[i]] = k; + break; + } + } + if (_color_map[order[i]] == -1) { + return false; + } + } + return true; + } + + private: + + bool recolor(const Node& u, const Node& v) { + int ucolor = _color_map[u]; + int vcolor = _color_map[v]; + typedef _planarity_bits::KempeFilter KempeFilter; + KempeFilter filter(_color_map, ucolor, vcolor); + + typedef FilterNodes KempeGraph; + KempeGraph kempe_graph(_graph, filter); + + std::vector comp; + Bfs bfs(kempe_graph); + bfs.init(); + bfs.addSource(u); + while (!bfs.emptyQueue()) { + Node n = bfs.nextNode(); + if (n == v) return false; + comp.push_back(n); + bfs.processNextNode(); + } + + int scolor = ucolor + vcolor; + for (int i = 0; i < static_cast(comp.size()); ++i) { + _color_map[comp[i]] = scolor - _color_map[comp[i]]; + } + + return true; + } + + template + void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) { + std::vector nodes; + nodes.reserve(4); + + for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) { + Node t = _graph.target(e); + if (_color_map[t] != -1) { + nodes.push_back(t); + if (nodes.size() == 4) break; + } + } + + int color = _color_map[nodes[0]]; + if (recolor(nodes[0], nodes[2])) { + _color_map[node] = color; + } else { + color = _color_map[nodes[1]]; + recolor(nodes[1], nodes[3]); + _color_map[node] = color; + } + } + + public: + + /// \brief Calculate a coloring with at most five colors + /// + /// This function calculates a coloring with at most five + /// colors. The worst case time complexity of this variant is + /// quadratic in the size of the graph. + /// \param embedding This map should contain a valid combinatorical + /// embedding, i.e. a valid cyclic order of the arcs. + /// It can be computed using PlanarEmbedding. + template + void runFiveColoring(const EmbeddingMap& embedding) { + + typename Graph::template NodeMap heap_index(_graph, -1); + BucketHeap > heap(heap_index); + + for (NodeIt n(_graph); n != INVALID; ++n) { + _color_map[n] = -2; + heap.push(n, countOutArcs(_graph, n)); + } + + std::vector order; + + while (!heap.empty()) { + Node n = heap.top(); + heap.pop(); + _color_map[n] = -1; + order.push_back(n); + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node t = _graph.runningNode(e); + if (_color_map[t] == -2) { + heap.decrease(t, heap[t] - 1); + } + } + } + + for (int i = order.size() - 1; i >= 0; --i) { + std::vector forbidden(5, false); + for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) { + Node t = _graph.runningNode(e); + if (_color_map[t] != -1) { + forbidden[_color_map[t]] = true; + } + } + for (int k = 0; k < 5; ++k) { + if (!forbidden[k]) { + _color_map[order[i]] = k; + break; + } + } + if (_color_map[order[i]] == -1) { + kempeRecoloring(order[i], embedding); + } + } + } + + /// \brief Calculate a coloring with at most five colors + /// + /// This function calculates a coloring with at most five + /// colors. The worst case time complexity of this variant is + /// quadratic in the size of the graph. + /// \return \c true if the graph is planar. + bool runFiveColoring() { + PlanarEmbedding pe(_graph); + if (!pe.run()) return false; + + runFiveColoring(pe.embeddingMap()); + return true; + } + + private: + + const Graph& _graph; + IndexMap _color_map; + Palette _palette; + }; + +} + +#endif diff --git a/lemon/lemon/preflow.h b/lemon/lemon/preflow.h new file mode 100644 index 0000000..d2a0ed1 --- /dev/null +++ b/lemon/lemon/preflow.h @@ -0,0 +1,985 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_PREFLOW_H +#define LEMON_PREFLOW_H + +#include +#include + +/// \file +/// \ingroup max_flow +/// \brief Implementation of the preflow algorithm. + +namespace lemon { + + /// \brief Default traits class of Preflow class. + /// + /// Default traits class of Preflow class. + /// \tparam GR Digraph type. + /// \tparam CAP Capacity map type. + template + struct PreflowDefaultTraits { + + /// \brief The type of the digraph the algorithm runs on. + typedef GR Digraph; + + /// \brief The type of the map that stores the arc capacities. + /// + /// The type of the map that stores the arc capacities. + /// It must meet the \ref concepts::ReadMap "ReadMap" concept. + typedef CAP CapacityMap; + + /// \brief The type of the flow values. + typedef typename CapacityMap::Value Value; + + /// \brief The type of the map that stores the flow values. + /// + /// The type of the map that stores the flow values. + /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept. +#ifdef DOXYGEN + typedef GR::ArcMap FlowMap; +#else + typedef typename Digraph::template ArcMap FlowMap; +#endif + + /// \brief Instantiates a FlowMap. + /// + /// This function instantiates a \ref FlowMap. + /// \param digraph The digraph for which we would like to define + /// the flow map. + static FlowMap* createFlowMap(const Digraph& digraph) { + return new FlowMap(digraph); + } + + /// \brief The elevator type used by Preflow algorithm. + /// + /// The elevator type used by Preflow algorithm. + /// + /// \sa Elevator, LinkedElevator +#ifdef DOXYGEN + typedef lemon::Elevator Elevator; +#else + typedef lemon::Elevator Elevator; +#endif + + /// \brief Instantiates an Elevator. + /// + /// This function instantiates an \ref Elevator. + /// \param digraph The digraph for which we would like to define + /// the elevator. + /// \param max_level The maximum level of the elevator. + static Elevator* createElevator(const Digraph& digraph, int max_level) { + return new Elevator(digraph, max_level); + } + + /// \brief The tolerance used by the algorithm + /// + /// The tolerance used by the algorithm to handle inexact computation. + typedef lemon::Tolerance Tolerance; + + }; + + + /// \ingroup max_flow + /// + /// \brief %Preflow algorithm class. + /// + /// This class provides an implementation of Goldberg-Tarjan's \e preflow + /// \e push-relabel algorithm producing a \ref max_flow + /// "flow of maximum value" in a digraph \ref clrs01algorithms, + /// \ref amo93networkflows, \ref goldberg88newapproach. + /// The preflow algorithms are the fastest known maximum + /// flow algorithms. The current implementation uses a mixture of the + /// \e "highest label" and the \e "bound decrease" heuristics. + /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$. + /// + /// The algorithm consists of two phases. After the first phase + /// the maximum flow value and the minimum cut is obtained. The + /// second phase constructs a feasible maximum flow on each arc. + /// + /// \warning This implementation cannot handle infinite or very large + /// capacities (e.g. the maximum value of \c CAP::Value). + /// + /// \tparam GR The type of the digraph the algorithm runs on. + /// \tparam CAP The type of the capacity map. The default map + /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap". + /// \tparam TR The traits class that defines various types used by the + /// algorithm. By default, it is \ref PreflowDefaultTraits + /// "PreflowDefaultTraits". + /// In most cases, this parameter should not be set directly, + /// consider to use the named template parameters instead. +#ifdef DOXYGEN + template +#else + template , + typename TR = PreflowDefaultTraits > +#endif + class Preflow { + public: + + ///The \ref PreflowDefaultTraits "traits class" of the algorithm. + typedef TR Traits; + ///The type of the digraph the algorithm runs on. + typedef typename Traits::Digraph Digraph; + ///The type of the capacity map. + typedef typename Traits::CapacityMap CapacityMap; + ///The type of the flow values. + typedef typename Traits::Value Value; + + ///The type of the flow map. + typedef typename Traits::FlowMap FlowMap; + ///The type of the elevator. + typedef typename Traits::Elevator Elevator; + ///The type of the tolerance. + typedef typename Traits::Tolerance Tolerance; + + private: + + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + const Digraph& _graph; + const CapacityMap* _capacity; + + int _node_num; + + Node _source, _target; + + FlowMap* _flow; + bool _local_flow; + + Elevator* _level; + bool _local_level; + + typedef typename Digraph::template NodeMap ExcessMap; + ExcessMap* _excess; + + Tolerance _tolerance; + + bool _phase; + + + void createStructures() { + _node_num = countNodes(_graph); + + if (!_flow) { + _flow = Traits::createFlowMap(_graph); + _local_flow = true; + } + if (!_level) { + _level = Traits::createElevator(_graph, _node_num); + _local_level = true; + } + if (!_excess) { + _excess = new ExcessMap(_graph); + } + } + + void destroyStructures() { + if (_local_flow) { + delete _flow; + } + if (_local_level) { + delete _level; + } + if (_excess) { + delete _excess; + } + } + + public: + + typedef Preflow Create; + + ///\name Named Template Parameters + + ///@{ + + template + struct SetFlowMapTraits : public Traits { + typedef T FlowMap; + static FlowMap *createFlowMap(const Digraph&) { + LEMON_ASSERT(false, "FlowMap is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// FlowMap type + /// + /// \ref named-templ-param "Named parameter" for setting FlowMap + /// type. + template + struct SetFlowMap + : public Preflow > { + typedef Preflow > Create; + }; + + template + struct SetElevatorTraits : public Traits { + typedef T Elevator; + static Elevator *createElevator(const Digraph&, int) { + LEMON_ASSERT(false, "Elevator is not initialized"); + return 0; // ignore warnings + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// Elevator type + /// + /// \ref named-templ-param "Named parameter" for setting Elevator + /// type. If this named parameter is used, then an external + /// elevator object must be passed to the algorithm using the + /// \ref elevator(Elevator&) "elevator()" function before calling + /// \ref run() or \ref init(). + /// \sa SetStandardElevator + template + struct SetElevator + : public Preflow > { + typedef Preflow > Create; + }; + + template + struct SetStandardElevatorTraits : public Traits { + typedef T Elevator; + static Elevator *createElevator(const Digraph& digraph, int max_level) { + return new Elevator(digraph, max_level); + } + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// Elevator type with automatic allocation + /// + /// \ref named-templ-param "Named parameter" for setting Elevator + /// type with automatic allocation. + /// The Elevator should have standard constructor interface to be + /// able to automatically created by the algorithm (i.e. the + /// digraph and the maximum level should be passed to it). + /// However, an external elevator object could also be passed to the + /// algorithm with the \ref elevator(Elevator&) "elevator()" function + /// before calling \ref run() or \ref init(). + /// \sa SetElevator + template + struct SetStandardElevator + : public Preflow > { + typedef Preflow > Create; + }; + + /// @} + + protected: + + Preflow() {} + + public: + + + /// \brief The constructor of the class. + /// + /// The constructor of the class. + /// \param digraph The digraph the algorithm runs on. + /// \param capacity The capacity of the arcs. + /// \param source The source node. + /// \param target The target node. + Preflow(const Digraph& digraph, const CapacityMap& capacity, + Node source, Node target) + : _graph(digraph), _capacity(&capacity), + _node_num(0), _source(source), _target(target), + _flow(0), _local_flow(false), + _level(0), _local_level(false), + _excess(0), _tolerance(), _phase() {} + + /// \brief Destructor. + /// + /// Destructor. + ~Preflow() { + destroyStructures(); + } + + /// \brief Sets the capacity map. + /// + /// Sets the capacity map. + /// \return (*this) + Preflow& capacityMap(const CapacityMap& map) { + _capacity = ↦ + return *this; + } + + /// \brief Sets the flow map. + /// + /// Sets the flow map. + /// If you don't use this function before calling \ref run() or + /// \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated map, + /// of course. + /// \return (*this) + Preflow& flowMap(FlowMap& map) { + if (_local_flow) { + delete _flow; + _local_flow = false; + } + _flow = ↦ + return *this; + } + + /// \brief Sets the source node. + /// + /// Sets the source node. + /// \return (*this) + Preflow& source(const Node& node) { + _source = node; + return *this; + } + + /// \brief Sets the target node. + /// + /// Sets the target node. + /// \return (*this) + Preflow& target(const Node& node) { + _target = node; + return *this; + } + + /// \brief Sets the elevator used by algorithm. + /// + /// Sets the elevator used by algorithm. + /// If you don't use this function before calling \ref run() or + /// \ref init(), an instance will be allocated automatically. + /// The destructor deallocates this automatically allocated elevator, + /// of course. + /// \return (*this) + Preflow& elevator(Elevator& elevator) { + if (_local_level) { + delete _level; + _local_level = false; + } + _level = &elevator; + return *this; + } + + /// \brief Returns a const reference to the elevator. + /// + /// Returns a const reference to the elevator. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const Elevator& elevator() const { + return *_level; + } + + /// \brief Sets the tolerance used by the algorithm. + /// + /// Sets the tolerance object used by the algorithm. + /// \return (*this) + Preflow& tolerance(const Tolerance& tolerance) { + _tolerance = tolerance; + return *this; + } + + /// \brief Returns a const reference to the tolerance. + /// + /// Returns a const reference to the tolerance object used by + /// the algorithm. + const Tolerance& tolerance() const { + return _tolerance; + } + + /// \name Execution Control + /// The simplest way to execute the preflow algorithm is to use + /// \ref run() or \ref runMinCut().\n + /// If you need better control on the initial solution or the execution, + /// you have to call one of the \ref init() functions first, then + /// \ref startFirstPhase() and if you need it \ref startSecondPhase(). + + ///@{ + + /// \brief Initializes the internal data structures. + /// + /// Initializes the internal data structures and sets the initial + /// flow to zero on each arc. + void init() { + createStructures(); + + _phase = true; + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_excess)[n] = 0; + } + + for (ArcIt e(_graph); e != INVALID; ++e) { + _flow->set(e, 0); + } + + typename Digraph::template NodeMap reached(_graph, false); + + _level->initStart(); + _level->initAddItem(_target); + + std::vector queue; + reached[_source] = true; + + queue.push_back(_target); + reached[_target] = true; + while (!queue.empty()) { + _level->initNewLevel(); + std::vector nqueue; + for (int i = 0; i < int(queue.size()); ++i) { + Node n = queue[i]; + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node u = _graph.source(e); + if (!reached[u] && _tolerance.positive((*_capacity)[e])) { + reached[u] = true; + _level->initAddItem(u); + nqueue.push_back(u); + } + } + } + queue.swap(nqueue); + } + _level->initFinish(); + + for (OutArcIt e(_graph, _source); e != INVALID; ++e) { + if (_tolerance.positive((*_capacity)[e])) { + Node u = _graph.target(e); + if ((*_level)[u] == _level->maxLevel()) continue; + _flow->set(e, (*_capacity)[e]); + (*_excess)[u] += (*_capacity)[e]; + if (u != _target && !_level->active(u)) { + _level->activate(u); + } + } + } + } + + /// \brief Initializes the internal data structures using the + /// given flow map. + /// + /// Initializes the internal data structures and sets the initial + /// flow to the given \c flowMap. The \c flowMap should contain a + /// flow or at least a preflow, i.e. at each node excluding the + /// source node the incoming flow should greater or equal to the + /// outgoing flow. + /// \return \c false if the given \c flowMap is not a preflow. + template + bool init(const FlowMap& flowMap) { + createStructures(); + + for (ArcIt e(_graph); e != INVALID; ++e) { + _flow->set(e, flowMap[e]); + } + + for (NodeIt n(_graph); n != INVALID; ++n) { + Value excess = 0; + for (InArcIt e(_graph, n); e != INVALID; ++e) { + excess += (*_flow)[e]; + } + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + excess -= (*_flow)[e]; + } + if (excess < 0 && n != _source) return false; + (*_excess)[n] = excess; + } + + typename Digraph::template NodeMap reached(_graph, false); + + _level->initStart(); + _level->initAddItem(_target); + + std::vector queue; + reached[_source] = true; + + queue.push_back(_target); + reached[_target] = true; + while (!queue.empty()) { + _level->initNewLevel(); + std::vector nqueue; + for (int i = 0; i < int(queue.size()); ++i) { + Node n = queue[i]; + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node u = _graph.source(e); + if (!reached[u] && + _tolerance.positive((*_capacity)[e] - (*_flow)[e])) { + reached[u] = true; + _level->initAddItem(u); + nqueue.push_back(u); + } + } + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.target(e); + if (!reached[v] && _tolerance.positive((*_flow)[e])) { + reached[v] = true; + _level->initAddItem(v); + nqueue.push_back(v); + } + } + } + queue.swap(nqueue); + } + _level->initFinish(); + + for (OutArcIt e(_graph, _source); e != INVALID; ++e) { + Value rem = (*_capacity)[e] - (*_flow)[e]; + if (_tolerance.positive(rem)) { + Node u = _graph.target(e); + if ((*_level)[u] == _level->maxLevel()) continue; + _flow->set(e, (*_capacity)[e]); + (*_excess)[u] += rem; + } + } + for (InArcIt e(_graph, _source); e != INVALID; ++e) { + Value rem = (*_flow)[e]; + if (_tolerance.positive(rem)) { + Node v = _graph.source(e); + if ((*_level)[v] == _level->maxLevel()) continue; + _flow->set(e, 0); + (*_excess)[v] += rem; + } + } + for (NodeIt n(_graph); n != INVALID; ++n) + if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n])) + _level->activate(n); + + return true; + } + + /// \brief Starts the first phase of the preflow algorithm. + /// + /// The preflow algorithm consists of two phases, this method runs + /// the first phase. After the first phase the maximum flow value + /// and a minimum value cut can already be computed, although a + /// maximum flow is not yet obtained. So after calling this method + /// \ref flowValue() returns the value of a maximum flow and \ref + /// minCut() returns a minimum cut. + /// \pre One of the \ref init() functions must be called before + /// using this function. + void startFirstPhase() { + _phase = true; + + while (true) { + int num = _node_num; + + Node n = INVALID; + int level = -1; + + while (num > 0) { + n = _level->highestActive(); + if (n == INVALID) goto first_phase_done; + level = _level->highestActiveLevel(); + --num; + + Value excess = (*_excess)[n]; + int new_level = _level->maxLevel(); + + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Value rem = (*_capacity)[e] - (*_flow)[e]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.target(e); + if ((*_level)[v] < level) { + if (!_level->active(v) && v != _target) { + _level->activate(v); + } + if (!_tolerance.less(rem, excess)) { + _flow->set(e, (*_flow)[e] + excess); + (*_excess)[v] += excess; + excess = 0; + goto no_more_push_1; + } else { + excess -= rem; + (*_excess)[v] += rem; + _flow->set(e, (*_capacity)[e]); + } + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Value rem = (*_flow)[e]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.source(e); + if ((*_level)[v] < level) { + if (!_level->active(v) && v != _target) { + _level->activate(v); + } + if (!_tolerance.less(rem, excess)) { + _flow->set(e, (*_flow)[e] - excess); + (*_excess)[v] += excess; + excess = 0; + goto no_more_push_1; + } else { + excess -= rem; + (*_excess)[v] += rem; + _flow->set(e, 0); + } + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + no_more_push_1: + + (*_excess)[n] = excess; + + if (excess != 0) { + if (new_level + 1 < _level->maxLevel()) { + _level->liftHighestActive(new_level + 1); + } else { + _level->liftHighestActiveToTop(); + } + if (_level->emptyLevel(level)) { + _level->liftToTop(level); + } + } else { + _level->deactivate(n); + } + } + + num = _node_num * 20; + while (num > 0) { + while (level >= 0 && _level->activeFree(level)) { + --level; + } + if (level == -1) { + n = _level->highestActive(); + level = _level->highestActiveLevel(); + if (n == INVALID) goto first_phase_done; + } else { + n = _level->activeOn(level); + } + --num; + + Value excess = (*_excess)[n]; + int new_level = _level->maxLevel(); + + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Value rem = (*_capacity)[e] - (*_flow)[e]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.target(e); + if ((*_level)[v] < level) { + if (!_level->active(v) && v != _target) { + _level->activate(v); + } + if (!_tolerance.less(rem, excess)) { + _flow->set(e, (*_flow)[e] + excess); + (*_excess)[v] += excess; + excess = 0; + goto no_more_push_2; + } else { + excess -= rem; + (*_excess)[v] += rem; + _flow->set(e, (*_capacity)[e]); + } + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Value rem = (*_flow)[e]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.source(e); + if ((*_level)[v] < level) { + if (!_level->active(v) && v != _target) { + _level->activate(v); + } + if (!_tolerance.less(rem, excess)) { + _flow->set(e, (*_flow)[e] - excess); + (*_excess)[v] += excess; + excess = 0; + goto no_more_push_2; + } else { + excess -= rem; + (*_excess)[v] += rem; + _flow->set(e, 0); + } + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + no_more_push_2: + + (*_excess)[n] = excess; + + if (excess != 0) { + if (new_level + 1 < _level->maxLevel()) { + _level->liftActiveOn(level, new_level + 1); + } else { + _level->liftActiveToTop(level); + } + if (_level->emptyLevel(level)) { + _level->liftToTop(level); + } + } else { + _level->deactivate(n); + } + } + } + first_phase_done:; + } + + /// \brief Starts the second phase of the preflow algorithm. + /// + /// The preflow algorithm consists of two phases, this method runs + /// the second phase. After calling one of the \ref init() functions + /// and \ref startFirstPhase() and then \ref startSecondPhase(), + /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the + /// value of a maximum flow, \ref minCut() returns a minimum cut + /// \pre One of the \ref init() functions and \ref startFirstPhase() + /// must be called before using this function. + void startSecondPhase() { + _phase = false; + + typename Digraph::template NodeMap reached(_graph); + for (NodeIt n(_graph); n != INVALID; ++n) { + reached[n] = (*_level)[n] < _level->maxLevel(); + } + + _level->initStart(); + _level->initAddItem(_source); + + std::vector queue; + queue.push_back(_source); + reached[_source] = true; + + while (!queue.empty()) { + _level->initNewLevel(); + std::vector nqueue; + for (int i = 0; i < int(queue.size()); ++i) { + Node n = queue[i]; + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Node v = _graph.target(e); + if (!reached[v] && _tolerance.positive((*_flow)[e])) { + reached[v] = true; + _level->initAddItem(v); + nqueue.push_back(v); + } + } + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Node u = _graph.source(e); + if (!reached[u] && + _tolerance.positive((*_capacity)[e] - (*_flow)[e])) { + reached[u] = true; + _level->initAddItem(u); + nqueue.push_back(u); + } + } + } + queue.swap(nqueue); + } + _level->initFinish(); + + for (NodeIt n(_graph); n != INVALID; ++n) { + if (!reached[n]) { + _level->dirtyTopButOne(n); + } else if ((*_excess)[n] > 0 && _target != n) { + _level->activate(n); + } + } + + Node n; + while ((n = _level->highestActive()) != INVALID) { + Value excess = (*_excess)[n]; + int level = _level->highestActiveLevel(); + int new_level = _level->maxLevel(); + + for (OutArcIt e(_graph, n); e != INVALID; ++e) { + Value rem = (*_capacity)[e] - (*_flow)[e]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.target(e); + if ((*_level)[v] < level) { + if (!_level->active(v) && v != _source) { + _level->activate(v); + } + if (!_tolerance.less(rem, excess)) { + _flow->set(e, (*_flow)[e] + excess); + (*_excess)[v] += excess; + excess = 0; + goto no_more_push; + } else { + excess -= rem; + (*_excess)[v] += rem; + _flow->set(e, (*_capacity)[e]); + } + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + for (InArcIt e(_graph, n); e != INVALID; ++e) { + Value rem = (*_flow)[e]; + if (!_tolerance.positive(rem)) continue; + Node v = _graph.source(e); + if ((*_level)[v] < level) { + if (!_level->active(v) && v != _source) { + _level->activate(v); + } + if (!_tolerance.less(rem, excess)) { + _flow->set(e, (*_flow)[e] - excess); + (*_excess)[v] += excess; + excess = 0; + goto no_more_push; + } else { + excess -= rem; + (*_excess)[v] += rem; + _flow->set(e, 0); + } + } else if (new_level > (*_level)[v]) { + new_level = (*_level)[v]; + } + } + + no_more_push: + + (*_excess)[n] = excess; + + if (excess != 0) { + if (new_level + 1 < _level->maxLevel()) { + _level->liftHighestActive(new_level + 1); + } else { + // Calculation error + _level->liftHighestActiveToTop(); + } + if (_level->emptyLevel(level)) { + // Calculation error + _level->liftToTop(level); + } + } else { + _level->deactivate(n); + } + + } + } + + /// \brief Runs the preflow algorithm. + /// + /// Runs the preflow algorithm. + /// \note pf.run() is just a shortcut of the following code. + /// \code + /// pf.init(); + /// pf.startFirstPhase(); + /// pf.startSecondPhase(); + /// \endcode + void run() { + init(); + startFirstPhase(); + startSecondPhase(); + } + + /// \brief Runs the preflow algorithm to compute the minimum cut. + /// + /// Runs the preflow algorithm to compute the minimum cut. + /// \note pf.runMinCut() is just a shortcut of the following code. + /// \code + /// pf.init(); + /// pf.startFirstPhase(); + /// \endcode + void runMinCut() { + init(); + startFirstPhase(); + } + + /// @} + + /// \name Query Functions + /// The results of the preflow algorithm can be obtained using these + /// functions.\n + /// Either one of the \ref run() "run*()" functions or one of the + /// \ref startFirstPhase() "start*()" functions should be called + /// before using them. + + ///@{ + + /// \brief Returns the value of the maximum flow. + /// + /// Returns the value of the maximum flow by returning the excess + /// of the target node. This value equals to the value of + /// the maximum flow already after the first phase of the algorithm. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + Value flowValue() const { + return (*_excess)[_target]; + } + + /// \brief Returns the flow value on the given arc. + /// + /// Returns the flow value on the given arc. This method can + /// be called after the second phase of the algorithm. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + Value flow(const Arc& arc) const { + return (*_flow)[arc]; + } + + /// \brief Returns a const reference to the flow map. + /// + /// Returns a const reference to the arc map storing the found flow. + /// This method can be called after the second phase of the algorithm. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + const FlowMap& flowMap() const { + return *_flow; + } + + /// \brief Returns \c true when the node is on the source side of the + /// minimum cut. + /// + /// Returns true when the node is on the source side of the found + /// minimum cut. This method can be called both after running \ref + /// startFirstPhase() and \ref startSecondPhase(). + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + bool minCut(const Node& node) const { + return ((*_level)[node] == _level->maxLevel()) == _phase; + } + + /// \brief Gives back a minimum value cut. + /// + /// Sets \c cutMap to the characteristic vector of a minimum value + /// cut. \c cutMap should be a \ref concepts::WriteMap "writable" + /// node map with \c bool (or convertible) value type. + /// + /// This method can be called both after running \ref startFirstPhase() + /// and \ref startSecondPhase(). The result after the second phase + /// could be slightly different if inexact computation is used. + /// + /// \note This function calls \ref minCut() for each node, so it runs in + /// O(n) time. + /// + /// \pre Either \ref run() or \ref init() must be called before + /// using this function. + template + void minCutMap(CutMap& cutMap) const { + for (NodeIt n(_graph); n != INVALID; ++n) { + cutMap.set(n, minCut(n)); + } + } + + /// @} + }; +} + +#endif diff --git a/lemon/lemon/quad_heap.h b/lemon/lemon/quad_heap.h new file mode 100644 index 0000000..27c50fd --- /dev/null +++ b/lemon/lemon/quad_heap.h @@ -0,0 +1,343 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_QUAD_HEAP_H +#define LEMON_QUAD_HEAP_H + +///\ingroup heaps +///\file +///\brief Fourary (quaternary) heap implementation. + +#include +#include +#include + +namespace lemon { + + /// \ingroup heaps + /// + ///\brief Fourary (quaternary) heap data structure. + /// + /// This class implements the \e Fourary (\e quaternary) \e heap + /// data structure. + /// It fully conforms to the \ref concepts::Heap "heap concept". + /// + /// The fourary heap is a specialization of the \ref DHeap "D-ary heap" + /// for D=4. It is similar to the \ref BinHeap "binary heap", + /// but its nodes have at most four children, instead of two. + /// + /// \tparam PR Type of the priorities of the items. + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + /// \tparam CMP A functor class for comparing the priorities. + /// The default is \c std::less. + /// + ///\sa BinHeap + ///\sa DHeap +#ifdef DOXYGEN + template +#else + template > +#endif + class QuadHeap { + public: + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef PR Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + /// Type of the item-priority pairs. + typedef std::pair Pair; + /// Functor type for comparing the priorities. + typedef CMP Compare; + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + private: + std::vector _data; + Compare _comp; + ItemIntMap &_iim; + + public: + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + explicit QuadHeap(ItemIntMap &map) : _iim(map) {} + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param comp The function object used for comparing the priorities. + QuadHeap(ItemIntMap &map, const Compare &comp) + : _iim(map), _comp(comp) {} + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + void clear() { _data.clear(); } + + private: + static int parent(int i) { return (i-1)/4; } + static int firstChild(int i) { return 4*i+1; } + + bool less(const Pair &p1, const Pair &p2) const { + return _comp(p1.second, p2.second); + } + + void bubbleUp(int hole, Pair p) { + int par = parent(hole); + while( hole>0 && less(p,_data[par]) ) { + move(_data[par],hole); + hole = par; + par = parent(hole); + } + move(p, hole); + } + + void bubbleDown(int hole, Pair p, int length) { + if( length>1 ) { + int child = firstChild(hole); + while( child+30) bubbleDown(0, _data[n], n); + _data.pop_back(); + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. + void erase(const Item &i) { + int h = _iim[i]; + int n = _data.size()-1; + _iim.set(_data[h].first, POST_HEAP); + if( h=0) s=0; + return State(s); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) erase(i); + _iim[i] = st; + break; + case IN_HEAP: + break; + } + } + + /// \brief Replace an item in the heap. + /// + /// This function replaces item \c i with item \c j. + /// Item \c i must be in the heap, while \c j must be out of the heap. + /// After calling this method, item \c i will be out of the + /// heap and \c j will be in the heap with the same prioriority + /// as item \c i had before. + void replace(const Item& i, const Item& j) { + int idx = _iim[i]; + _iim.set(i, _iim[j]); + _iim.set(j, idx); + _data[idx].first = j; + } + + }; // class QuadHeap + +} // namespace lemon + +#endif // LEMON_FOURARY_HEAP_H diff --git a/lemon/lemon/radix_heap.h b/lemon/lemon/radix_heap.h new file mode 100644 index 0000000..8701ce7 --- /dev/null +++ b/lemon/lemon/radix_heap.h @@ -0,0 +1,438 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_RADIX_HEAP_H +#define LEMON_RADIX_HEAP_H + +///\ingroup heaps +///\file +///\brief Radix heap implementation. + +#include +#include + +namespace lemon { + + + /// \ingroup heaps + /// + /// \brief Radix heap data structure. + /// + /// This class implements the \e radix \e heap data structure. + /// It practically conforms to the \ref concepts::Heap "heap concept", + /// but it has some limitations due its special implementation. + /// The type of the priorities must be \c int and the priority of an + /// item cannot be decreased under the priority of the last removed item. + /// + /// \tparam IM A read-writable item map with \c int values, used + /// internally to handle the cross references. + template + class RadixHeap { + + public: + + /// Type of the item-int map. + typedef IM ItemIntMap; + /// Type of the priorities. + typedef int Prio; + /// Type of the items stored in the heap. + typedef typename ItemIntMap::Key Item; + + /// \brief Exception thrown by RadixHeap. + /// + /// This exception is thrown when an item is inserted into a + /// RadixHeap with a priority smaller than the last erased one. + /// \see RadixHeap + class PriorityUnderflowError : public Exception { + public: + virtual const char* what() const throw() { + return "lemon::RadixHeap::PriorityUnderflowError"; + } + }; + + /// \brief Type to represent the states of the items. + /// + /// Each item has a state associated to it. It can be "in heap", + /// "pre-heap" or "post-heap". The latter two are indifferent from the + /// heap's point of view, but may be useful to the user. + /// + /// The item-int map must be initialized in such way that it assigns + /// \c PRE_HEAP (-1) to any element to be put in the heap. + enum State { + IN_HEAP = 0, ///< = 0. + PRE_HEAP = -1, ///< = -1. + POST_HEAP = -2 ///< = -2. + }; + + private: + + struct RadixItem { + int prev, next, box; + Item item; + int prio; + RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {} + }; + + struct RadixBox { + int first; + int min, size; + RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {} + }; + + std::vector _data; + std::vector _boxes; + + ItemIntMap &_iim; + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// \param map A map that assigns \c int values to the items. + /// It is used internally to handle the cross references. + /// The assigned value must be \c PRE_HEAP (-1) for each item. + /// \param minimum The initial minimum value of the heap. + /// \param capacity The initial capacity of the heap. + RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0) + : _iim(map) + { + _boxes.push_back(RadixBox(minimum, 1)); + _boxes.push_back(RadixBox(minimum + 1, 1)); + while (lower(_boxes.size() - 1, capacity + minimum - 1)) { + extend(); + } + } + + /// \brief The number of items stored in the heap. + /// + /// This function returns the number of items stored in the heap. + int size() const { return _data.size(); } + + /// \brief Check if the heap is empty. + /// + /// This function returns \c true if the heap is empty. + bool empty() const { return _data.empty(); } + + /// \brief Make the heap empty. + /// + /// This functon makes the heap empty. + /// It does not change the cross reference map. If you want to reuse + /// a heap that is not surely empty, you should first clear it and + /// then you should set the cross reference map to \c PRE_HEAP + /// for each item. + /// \param minimum The minimum value of the heap. + /// \param capacity The capacity of the heap. + void clear(int minimum = 0, int capacity = 0) { + _data.clear(); _boxes.clear(); + _boxes.push_back(RadixBox(minimum, 1)); + _boxes.push_back(RadixBox(minimum + 1, 1)); + while (lower(_boxes.size() - 1, capacity + minimum - 1)) { + extend(); + } + } + + private: + + bool upper(int box, Prio pr) { + return pr < _boxes[box].min; + } + + bool lower(int box, Prio pr) { + return pr >= _boxes[box].min + _boxes[box].size; + } + + // Remove item from the box list + void remove(int index) { + if (_data[index].prev >= 0) { + _data[_data[index].prev].next = _data[index].next; + } else { + _boxes[_data[index].box].first = _data[index].next; + } + if (_data[index].next >= 0) { + _data[_data[index].next].prev = _data[index].prev; + } + } + + // Insert item into the box list + void insert(int box, int index) { + if (_boxes[box].first == -1) { + _boxes[box].first = index; + _data[index].next = _data[index].prev = -1; + } else { + _data[index].next = _boxes[box].first; + _data[_boxes[box].first].prev = index; + _data[index].prev = -1; + _boxes[box].first = index; + } + _data[index].box = box; + } + + // Add a new box to the box list + void extend() { + int min = _boxes.back().min + _boxes.back().size; + int bs = 2 * _boxes.back().size; + _boxes.push_back(RadixBox(min, bs)); + } + + // Move an item up into the proper box. + void bubbleUp(int index) { + if (!lower(_data[index].box, _data[index].prio)) return; + remove(index); + int box = findUp(_data[index].box, _data[index].prio); + insert(box, index); + } + + // Find up the proper box for the item with the given priority + int findUp(int start, int pr) { + while (lower(start, pr)) { + if (++start == int(_boxes.size())) { + extend(); + } + } + return start; + } + + // Move an item down into the proper box + void bubbleDown(int index) { + if (!upper(_data[index].box, _data[index].prio)) return; + remove(index); + int box = findDown(_data[index].box, _data[index].prio); + insert(box, index); + } + + // Find down the proper box for the item with the given priority + int findDown(int start, int pr) { + while (upper(start, pr)) { + if (--start < 0) throw PriorityUnderflowError(); + } + return start; + } + + // Find the first non-empty box + int findFirst() { + int first = 0; + while (_boxes[first].first == -1) ++first; + return first; + } + + // Gives back the minimum priority of the given box + int minValue(int box) { + int min = _data[_boxes[box].first].prio; + for (int k = _boxes[box].first; k != -1; k = _data[k].next) { + if (_data[k].prio < min) min = _data[k].prio; + } + return min; + } + + // Rearrange the items of the heap and make the first box non-empty + void moveDown() { + int box = findFirst(); + if (box == 0) return; + int min = minValue(box); + for (int i = 0; i <= box; ++i) { + _boxes[i].min = min; + min += _boxes[i].size; + } + int curr = _boxes[box].first, next; + while (curr != -1) { + next = _data[curr].next; + bubbleDown(curr); + curr = next; + } + } + + void relocateLast(int index) { + if (index != int(_data.size()) - 1) { + _data[index] = _data.back(); + if (_data[index].prev != -1) { + _data[_data[index].prev].next = index; + } else { + _boxes[_data[index].box].first = index; + } + if (_data[index].next != -1) { + _data[_data[index].next].prev = index; + } + _iim[_data[index].item] = index; + } + _data.pop_back(); + } + + public: + + /// \brief Insert an item into the heap with the given priority. + /// + /// This function inserts the given item into the heap with the + /// given priority. + /// \param i The item to insert. + /// \param p The priority of the item. + /// \pre \e i must not be stored in the heap. + /// \warning This method may throw an \c UnderFlowPriorityException. + void push(const Item &i, const Prio &p) { + int n = _data.size(); + _iim.set(i, n); + _data.push_back(RadixItem(i, p)); + while (lower(_boxes.size() - 1, p)) { + extend(); + } + int box = findDown(_boxes.size() - 1, p); + insert(box, n); + } + + /// \brief Return the item having minimum priority. + /// + /// This function returns the item having minimum priority. + /// \pre The heap must be non-empty. + Item top() const { + const_cast&>(*this).moveDown(); + return _data[_boxes[0].first].item; + } + + /// \brief The minimum priority. + /// + /// This function returns the minimum priority. + /// \pre The heap must be non-empty. + Prio prio() const { + const_cast&>(*this).moveDown(); + return _data[_boxes[0].first].prio; + } + + /// \brief Remove the item having minimum priority. + /// + /// This function removes the item having minimum priority. + /// \pre The heap must be non-empty. + void pop() { + moveDown(); + int index = _boxes[0].first; + _iim[_data[index].item] = POST_HEAP; + remove(index); + relocateLast(index); + } + + /// \brief Remove the given item from the heap. + /// + /// This function removes the given item from the heap if it is + /// already stored. + /// \param i The item to delete. + /// \pre \e i must be in the heap. + void erase(const Item &i) { + int index = _iim[i]; + _iim[i] = POST_HEAP; + remove(index); + relocateLast(index); + } + + /// \brief The priority of the given item. + /// + /// This function returns the priority of the given item. + /// \param i The item. + /// \pre \e i must be in the heap. + Prio operator[](const Item &i) const { + int idx = _iim[i]; + return _data[idx].prio; + } + + /// \brief Set the priority of an item or insert it, if it is + /// not stored in the heap. + /// + /// This method sets the priority of the given item if it is + /// already stored in the heap. Otherwise it inserts the given + /// item into the heap with the given priority. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be in the heap. + /// \warning This method may throw an \c UnderFlowPriorityException. + void set(const Item &i, const Prio &p) { + int idx = _iim[i]; + if( idx < 0 ) { + push(i, p); + } + else if( p >= _data[idx].prio ) { + _data[idx].prio = p; + bubbleUp(idx); + } else { + _data[idx].prio = p; + bubbleDown(idx); + } + } + + /// \brief Decrease the priority of an item to the given value. + /// + /// This function decreases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at least \e p. + /// \warning This method may throw an \c UnderFlowPriorityException. + void decrease(const Item &i, const Prio &p) { + int idx = _iim[i]; + _data[idx].prio = p; + bubbleDown(idx); + } + + /// \brief Increase the priority of an item to the given value. + /// + /// This function increases the priority of an item to the given value. + /// \param i The item. + /// \param p The priority. + /// \pre \e i must be stored in the heap with priority at most \e p. + void increase(const Item &i, const Prio &p) { + int idx = _iim[i]; + _data[idx].prio = p; + bubbleUp(idx); + } + + /// \brief Return the state of an item. + /// + /// This method returns \c PRE_HEAP if the given item has never + /// been in the heap, \c IN_HEAP if it is in the heap at the moment, + /// and \c POST_HEAP otherwise. + /// In the latter case it is possible that the item will get back + /// to the heap again. + /// \param i The item. + State state(const Item &i) const { + int s = _iim[i]; + if( s >= 0 ) s = 0; + return State(s); + } + + /// \brief Set the state of an item in the heap. + /// + /// This function sets the state of the given item in the heap. + /// It can be used to manually clear the heap when it is important + /// to achive better time complexity. + /// \param i The item. + /// \param st The state. It should not be \c IN_HEAP. + void state(const Item& i, State st) { + switch (st) { + case POST_HEAP: + case PRE_HEAP: + if (state(i) == IN_HEAP) { + erase(i); + } + _iim[i] = st; + break; + case IN_HEAP: + break; + } + } + + }; // class RadixHeap + +} // namespace lemon + +#endif // LEMON_RADIX_HEAP_H diff --git a/lemon/lemon/radix_sort.h b/lemon/lemon/radix_sort.h new file mode 100644 index 0000000..49a3e39 --- /dev/null +++ b/lemon/lemon/radix_sort.h @@ -0,0 +1,487 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef RADIX_SORT_H +#define RADIX_SORT_H + +/// \ingroup auxalg +/// \file +/// \brief Radix sort +/// +/// Linear time sorting algorithms + +#include +#include +#include +#include + +namespace lemon { + + namespace _radix_sort_bits { + + template + struct Identity { + const Value& operator()(const Value& val) { + return val; + } + }; + + + template + Iterator radixSortPartition(Iterator first, Iterator last, + Functor functor, Value mask) { + while (first != last && !(functor(*first) & mask)) { + ++first; + } + if (first == last) { + return first; + } + --last; + while (first != last && (functor(*last) & mask)) { + --last; + } + if (first == last) { + return first; + } + std::iter_swap(first, last); + ++first; + if (!(first < last)) { + return first; + } + while (true) { + while (!(functor(*first) & mask)) { + ++first; + } + --last; + while (functor(*last) & mask) { + --last; + } + if (!(first < last)) { + return first; + } + std::iter_swap(first, last); + ++first; + } + } + + template + Iterator radixSortSignPartition(Iterator first, Iterator last, + Functor functor) { + while (first != last && functor(*first) < 0) { + ++first; + } + if (first == last) { + return first; + } + --last; + while (first != last && functor(*last) >= 0) { + --last; + } + if (first == last) { + return first; + } + std::iter_swap(first, last); + ++first; + if (!(first < last)) { + return first; + } + while (true) { + while (functor(*first) < 0) { + ++first; + } + --last; + while (functor(*last) >= 0) { + --last; + } + if (!(first < last)) { + return first; + } + std::iter_swap(first, last); + ++first; + } + } + + template + void radixIntroSort(Iterator first, Iterator last, + Functor functor, Value mask) { + while (mask != 0 && last - first > 1) { + Iterator cut = radixSortPartition(first, last, functor, mask); + mask >>= 1; + radixIntroSort(first, cut, functor, mask); + first = cut; + } + } + + template + void radixSignedSort(Iterator first, Iterator last, Functor functor) { + + Iterator cut = radixSortSignPartition(first, last, functor); + + Value mask; + int max_digit; + Iterator it; + + mask = ~0; max_digit = 0; + for (it = first; it != cut; ++it) { + while ((mask & functor(*it)) != mask) { + ++max_digit; + mask <<= 1; + } + } + radixIntroSort(first, cut, functor, 1 << max_digit); + + mask = 0; max_digit = 0; + for (it = cut; it != last; ++it) { + while ((mask | functor(*it)) != mask) { + ++max_digit; + mask <<= 1; mask |= 1; + } + } + radixIntroSort(cut, last, functor, 1 << max_digit); + } + + template + void radixUnsignedSort(Iterator first, Iterator last, Functor functor) { + + Value mask = 0; + int max_digit = 0; + + Iterator it; + for (it = first; it != last; ++it) { + while ((mask | functor(*it)) != mask) { + ++max_digit; + mask <<= 1; mask |= 1; + } + } + radixIntroSort(first, last, functor, 1 << max_digit); + } + + + template ::is_signed > + struct RadixSortSelector { + template + static void sort(Iterator first, Iterator last, Functor functor) { + radixSignedSort(first, last, functor); + } + }; + + template + struct RadixSortSelector { + template + static void sort(Iterator first, Iterator last, Functor functor) { + radixUnsignedSort(first, last, functor); + } + }; + + } + + /// \ingroup auxalg + /// + /// \brief Sorts the STL compatible range into ascending order. + /// + /// The \c radixSort sorts an STL compatible range into ascending + /// order. The radix sort algorithm can sort items which are mapped + /// to integers with an adaptable unary function \c functor and the + /// order will be ascending according to these mapped values. + /// + /// It is also possible to use a normal function instead + /// of the functor object. If the functor is not given it will use + /// the identity function instead. + /// + /// This is a special quick sort algorithm where the pivot + /// values to split the items are choosen to be 2k + /// for each \c k. + /// Therefore, the time complexity of the algorithm is O(log(c)*n) and + /// it uses O(log(c)) additional space, where \c c is the maximal value + /// and \c n is the number of the items in the container. + /// + /// \param first The begin of the given range. + /// \param last The end of the given range. + /// \param functor An adaptible unary function or a normal function + /// which maps the items to any integer type which can be either + /// signed or unsigned. + /// + /// \sa stableRadixSort() + template + void radixSort(Iterator first, Iterator last, Functor functor) { + using namespace _radix_sort_bits; + typedef typename Functor::result_type Value; + RadixSortSelector::sort(first, last, functor); + } + + template + void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) { + using namespace _radix_sort_bits; + RadixSortSelector::sort(first, last, functor); + } + + template + void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) { + using namespace _radix_sort_bits; + RadixSortSelector::sort(first, last, functor); + } + + template + void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) { + using namespace _radix_sort_bits; + RadixSortSelector::sort(first, last, functor); + } + + template + void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) { + using namespace _radix_sort_bits; + RadixSortSelector::sort(first, last, functor); + } + + template + void radixSort(Iterator first, Iterator last) { + using namespace _radix_sort_bits; + typedef typename std::iterator_traits::value_type Value; + RadixSortSelector::sort(first, last, Identity()); + } + + namespace _radix_sort_bits { + + template + unsigned char valueByte(Value value, int byte) { + return value >> (std::numeric_limits::digits * byte); + } + + template + void stableRadixIntroSort(Key *first, Key *last, Key *target, + int byte, Functor functor) { + const int size = + unsigned(std::numeric_limits::max()) + 1; + std::vector counter(size); + for (int i = 0; i < size; ++i) { + counter[i] = 0; + } + Key *it = first; + while (first != last) { + ++counter[valueByte(functor(*first), byte)]; + ++first; + } + int prev, num = 0; + for (int i = 0; i < size; ++i) { + prev = num; + num += counter[i]; + counter[i] = prev; + } + while (it != last) { + target[counter[valueByte(functor(*it), byte)]++] = *it; + ++it; + } + } + + template + void signedStableRadixIntroSort(Key *first, Key *last, Key *target, + int byte, Functor functor) { + const int size = + unsigned(std::numeric_limits::max()) + 1; + std::vector counter(size); + for (int i = 0; i < size; ++i) { + counter[i] = 0; + } + Key *it = first; + while (first != last) { + counter[valueByte(functor(*first), byte)]++; + ++first; + } + int prev, num = 0; + for (int i = size / 2; i < size; ++i) { + prev = num; + num += counter[i]; + counter[i] = prev; + } + for (int i = 0; i < size / 2; ++i) { + prev = num; + num += counter[i]; + counter[i] = prev; + } + while (it != last) { + target[counter[valueByte(functor(*it), byte)]++] = *it; + ++it; + } + } + + + template + void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) { + if (first == last) return; + typedef typename std::iterator_traits::value_type Key; + typedef std::allocator Allocator; + Allocator allocator; + + int length = std::distance(first, last); + Key* buffer = allocator.allocate(2 * length); + try { + bool dir = true; + std::copy(first, last, buffer); + for (int i = 0; i < int(sizeof(Value)) - 1; ++i) { + if (dir) { + stableRadixIntroSort(buffer, buffer + length, buffer + length, + i, functor); + } else { + stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer, + i, functor); + } + dir = !dir; + } + if (dir) { + signedStableRadixIntroSort(buffer, buffer + length, buffer + length, + sizeof(Value) - 1, functor); + std::copy(buffer + length, buffer + 2 * length, first); + } else { + signedStableRadixIntroSort(buffer + length, buffer + 2 * length, + buffer, sizeof(Value) - 1, functor); + std::copy(buffer, buffer + length, first); + } + } catch (...) { + allocator.deallocate(buffer, 2 * length); + throw; + } + allocator.deallocate(buffer, 2 * length); + } + + template + void stableRadixUnsignedSort(Iterator first, Iterator last, + Functor functor) { + if (first == last) return; + typedef typename std::iterator_traits::value_type Key; + typedef std::allocator Allocator; + Allocator allocator; + + int length = std::distance(first, last); + Key *buffer = allocator.allocate(2 * length); + try { + bool dir = true; + std::copy(first, last, buffer); + for (int i = 0; i < int(sizeof(Value)); ++i) { + if (dir) { + stableRadixIntroSort(buffer, buffer + length, + buffer + length, i, functor); + } else { + stableRadixIntroSort(buffer + length, buffer + 2 * length, + buffer, i, functor); + } + dir = !dir; + } + if (dir) { + std::copy(buffer, buffer + length, first); + } else { + std::copy(buffer + length, buffer + 2 * length, first); + } + } catch (...) { + allocator.deallocate(buffer, 2 * length); + throw; + } + allocator.deallocate(buffer, 2 * length); + } + + + + template ::is_signed > + struct StableRadixSortSelector { + template + static void sort(Iterator first, Iterator last, Functor functor) { + stableRadixSignedSort(first, last, functor); + } + }; + + template + struct StableRadixSortSelector { + template + static void sort(Iterator first, Iterator last, Functor functor) { + stableRadixUnsignedSort(first, last, functor); + } + }; + + } + + /// \ingroup auxalg + /// + /// \brief Sorts the STL compatible range into ascending order in a stable + /// way. + /// + /// This function sorts an STL compatible range into ascending + /// order according to an integer mapping in the same as radixSort() does. + /// + /// This sorting algorithm is stable, i.e. the order of two equal + /// elements remains the same after the sorting. + /// + /// This sort algorithm use a radix forward sort on the + /// bytes of the integer number. The algorithm sorts the items + /// byte-by-byte. First, it counts how many times a byte value occurs + /// in the container, then it copies the corresponding items to + /// another container in asceding order in O(n) time. + /// + /// The time complexity of the algorithm is O(log(c)*n) and + /// it uses O(n) additional space, where \c c is the + /// maximal value and \c n is the number of the items in the + /// container. + /// + + /// \param first The begin of the given range. + /// \param last The end of the given range. + /// \param functor An adaptible unary function or a normal function + /// which maps the items to any integer type which can be either + /// signed or unsigned. + /// \sa radixSort() + template + void stableRadixSort(Iterator first, Iterator last, Functor functor) { + using namespace _radix_sort_bits; + typedef typename Functor::result_type Value; + StableRadixSortSelector::sort(first, last, functor); + } + + template + void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) { + using namespace _radix_sort_bits; + StableRadixSortSelector::sort(first, last, functor); + } + + template + void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) { + using namespace _radix_sort_bits; + StableRadixSortSelector::sort(first, last, functor); + } + + template + void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) { + using namespace _radix_sort_bits; + StableRadixSortSelector::sort(first, last, functor); + } + + template + void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) { + using namespace _radix_sort_bits; + StableRadixSortSelector::sort(first, last, functor); + } + + template + void stableRadixSort(Iterator first, Iterator last) { + using namespace _radix_sort_bits; + typedef typename std::iterator_traits::value_type Value; + StableRadixSortSelector::sort(first, last, Identity()); + } + +} + +#endif diff --git a/lemon/lemon/random.cc b/lemon/lemon/random.cc new file mode 100644 index 0000000..0295121 --- /dev/null +++ b/lemon/lemon/random.cc @@ -0,0 +1,29 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\file +///\brief Instantiation of the Random class. + +#include + +namespace lemon { + /// \brief Global random number generator instance + /// + /// A global Mersenne Twister random number generator instance. + Random rnd; +} diff --git a/lemon/lemon/random.h b/lemon/lemon/random.h new file mode 100644 index 0000000..8de74ed --- /dev/null +++ b/lemon/lemon/random.h @@ -0,0 +1,1005 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/* + * This file contains the reimplemented version of the Mersenne Twister + * Generator of Matsumoto and Nishimura. + * + * See the appropriate copyright notice below. + * + * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Any feedback is very welcome. + * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) + */ + +#ifndef LEMON_RANDOM_H +#define LEMON_RANDOM_H + +#include +#include +#include +#include +#include + +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#else +#include +#endif + +///\ingroup misc +///\file +///\brief Mersenne Twister random number generator + +namespace lemon { + + namespace _random_bits { + + template ::digits> + struct RandomTraits {}; + + template + struct RandomTraits<_Word, 32> { + + typedef _Word Word; + static const int bits = 32; + + static const int length = 624; + static const int shift = 397; + + static const Word mul = 0x6c078965u; + static const Word arrayInit = 0x012BD6AAu; + static const Word arrayMul1 = 0x0019660Du; + static const Word arrayMul2 = 0x5D588B65u; + + static const Word mask = 0x9908B0DFu; + static const Word loMask = (1u << 31) - 1; + static const Word hiMask = ~loMask; + + + static Word tempering(Word rnd) { + rnd ^= (rnd >> 11); + rnd ^= (rnd << 7) & 0x9D2C5680u; + rnd ^= (rnd << 15) & 0xEFC60000u; + rnd ^= (rnd >> 18); + return rnd; + } + + }; + + template + struct RandomTraits<_Word, 64> { + + typedef _Word Word; + static const int bits = 64; + + static const int length = 312; + static const int shift = 156; + + static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du); + static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu); + static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u); + static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu); + + static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u); + static const Word loMask = (Word(1u) << 31) - 1; + static const Word hiMask = ~loMask; + + static Word tempering(Word rnd) { + rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u)); + rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u)); + rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u)); + rnd ^= (rnd >> 43); + return rnd; + } + + }; + + template + class RandomCore { + public: + + typedef _Word Word; + + private: + + static const int bits = RandomTraits::bits; + + static const int length = RandomTraits::length; + static const int shift = RandomTraits::shift; + + public: + + void initState() { + static const Word seedArray[4] = { + 0x12345u, 0x23456u, 0x34567u, 0x45678u + }; + + initState(seedArray, seedArray + 4); + } + + void initState(Word seed) { + + static const Word mul = RandomTraits::mul; + + current = state; + + Word *curr = state + length - 1; + curr[0] = seed; --curr; + for (int i = 1; i < length; ++i) { + curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i); + --curr; + } + } + + template + void initState(Iterator begin, Iterator end) { + + static const Word init = RandomTraits::arrayInit; + static const Word mul1 = RandomTraits::arrayMul1; + static const Word mul2 = RandomTraits::arrayMul2; + + + Word *curr = state + length - 1; --curr; + Iterator it = begin; int cnt = 0; + int num; + + initState(init); + + num = length > end - begin ? length : end - begin; + while (num--) { + curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1)) + + *it + cnt; + ++it; ++cnt; + if (it == end) { + it = begin; cnt = 0; + } + if (curr == state) { + curr = state + length - 1; curr[0] = state[0]; + } + --curr; + } + + num = length - 1; cnt = length - (curr - state) - 1; + while (num--) { + curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2)) + - cnt; + --curr; ++cnt; + if (curr == state) { + curr = state + length - 1; curr[0] = state[0]; --curr; + cnt = 1; + } + } + + state[length - 1] = Word(1) << (bits - 1); + } + + void copyState(const RandomCore& other) { + std::copy(other.state, other.state + length, state); + current = state + (other.current - other.state); + } + + Word operator()() { + if (current == state) fillState(); + --current; + Word rnd = *current; + return RandomTraits::tempering(rnd); + } + + private: + + + void fillState() { + static const Word mask[2] = { 0x0ul, RandomTraits::mask }; + static const Word loMask = RandomTraits::loMask; + static const Word hiMask = RandomTraits::hiMask; + + current = state + length; + + register Word *curr = state + length - 1; + register long num; + + num = length - shift; + while (num--) { + curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^ + curr[- shift] ^ mask[curr[-1] & 1ul]; + --curr; + } + num = shift - 1; + while (num--) { + curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^ + curr[length - shift] ^ mask[curr[-1] & 1ul]; + --curr; + } + state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^ + curr[length - shift] ^ mask[curr[length - 1] & 1ul]; + + } + + + Word *current; + Word state[length]; + + }; + + + template ::digits + 1) / 2> + struct Masker { + static Result mask(const Result& result) { + return Masker:: + mask(static_cast(result | (result >> shift))); + } + }; + + template + struct Masker { + static Result mask(const Result& result) { + return static_cast(result | (result >> 1)); + } + }; + + template ::digits, int shift = 0, + bool last = rest <= std::numeric_limits::digits> + struct IntConversion { + static const int bits = std::numeric_limits::digits; + + static Result convert(RandomCore& rnd) { + return static_cast(rnd() >> (bits - rest)) << shift; + } + + }; + + template + struct IntConversion { + static const int bits = std::numeric_limits::digits; + + static Result convert(RandomCore& rnd) { + return (static_cast(rnd()) << shift) | + IntConversion::convert(rnd); + } + }; + + + template ::digits < + std::numeric_limits::digits) > + struct Mapping { + static Result map(RandomCore& rnd, const Result& bound) { + Word max = Word(bound - 1); + Result mask = Masker::mask(bound - 1); + Result num; + do { + num = IntConversion::convert(rnd) & mask; + } while (num > max); + return num; + } + }; + + template + struct Mapping { + static Result map(RandomCore& rnd, const Result& bound) { + Word max = Word(bound - 1); + Word mask = Masker::digits + 1) / 2> + ::mask(max); + Word num; + do { + num = rnd() & mask; + } while (num > max); + return num; + } + }; + + template + struct ShiftMultiplier { + static const Result multiplier() { + Result res = ShiftMultiplier::multiplier(); + res *= res; + if ((exp & 1) == 1) res *= static_cast(0.5); + return res; + } + }; + + template + struct ShiftMultiplier { + static const Result multiplier() { + return static_cast(1.0); + } + }; + + template + struct ShiftMultiplier { + static const Result multiplier() { + return static_cast(1.0/1048576.0); + } + }; + + template + struct ShiftMultiplier { + static const Result multiplier() { + return static_cast(1.0/4294967296.0); + } + }; + + template + struct ShiftMultiplier { + static const Result multiplier() { + return static_cast(1.0/9007199254740992.0); + } + }; + + template + struct ShiftMultiplier { + static const Result multiplier() { + return static_cast(1.0/18446744073709551616.0); + } + }; + + template + struct Shifting { + static Result shift(const Result& result) { + return result * ShiftMultiplier::multiplier(); + } + }; + + template ::digits, int shift = 0, + bool last = rest <= std::numeric_limits::digits> + struct RealConversion{ + static const int bits = std::numeric_limits::digits; + + static Result convert(RandomCore& rnd) { + return Shifting:: + shift(static_cast(rnd() >> (bits - rest))); + } + }; + + template + struct RealConversion { + static const int bits = std::numeric_limits::digits; + + static Result convert(RandomCore& rnd) { + return Shifting:: + shift(static_cast(rnd())) + + RealConversion:: + convert(rnd); + } + }; + + template + struct Initializer { + + template + static void init(RandomCore& rnd, Iterator begin, Iterator end) { + std::vector ws; + for (Iterator it = begin; it != end; ++it) { + ws.push_back(Word(*it)); + } + rnd.initState(ws.begin(), ws.end()); + } + + static void init(RandomCore& rnd, Result seed) { + rnd.initState(seed); + } + }; + + template + struct BoolConversion { + static bool convert(RandomCore& rnd) { + return (rnd() & 1) == 1; + } + }; + + template + struct BoolProducer { + Word buffer; + int num; + + BoolProducer() : num(0) {} + + bool convert(RandomCore& rnd) { + if (num == 0) { + buffer = rnd(); + num = RandomTraits::bits; + } + bool r = (buffer & 1); + buffer >>= 1; + --num; + return r; + } + }; + + } + + /// \ingroup misc + /// + /// \brief Mersenne Twister random number generator + /// + /// The Mersenne Twister is a twisted generalized feedback + /// shift-register generator of Matsumoto and Nishimura. The period + /// of this generator is \f$ 2^{19937} - 1 \f$ and it is + /// equi-distributed in 623 dimensions for 32-bit numbers. The time + /// performance of this generator is comparable to the commonly used + /// generators. + /// + /// This implementation is specialized for both 32-bit and 64-bit + /// architectures. The generators differ sligthly in the + /// initialization and generation phase so they produce two + /// completly different sequences. + /// + /// The generator gives back random numbers of serveral types. To + /// get a random number from a range of a floating point type you + /// can use one form of the \c operator() or the \c real() member + /// function. If you want to get random number from the {0, 1, ..., + /// n-1} integer range use the \c operator[] or the \c integer() + /// method. And to get random number from the whole range of an + /// integer type you can use the argumentless \c integer() or \c + /// uinteger() functions. After all you can get random bool with + /// equal chance of true and false or given probability of true + /// result with the \c boolean() member functions. + /// + ///\code + /// // The commented code is identical to the other + /// double a = rnd(); // [0.0, 1.0) + /// // double a = rnd.real(); // [0.0, 1.0) + /// double b = rnd(100.0); // [0.0, 100.0) + /// // double b = rnd.real(100.0); // [0.0, 100.0) + /// double c = rnd(1.0, 2.0); // [1.0, 2.0) + /// // double c = rnd.real(1.0, 2.0); // [1.0, 2.0) + /// int d = rnd[100000]; // 0..99999 + /// // int d = rnd.integer(100000); // 0..99999 + /// int e = rnd[6] + 1; // 1..6 + /// // int e = rnd.integer(1, 1 + 6); // 1..6 + /// int b = rnd.uinteger(); // 0 .. 2^31 - 1 + /// int c = rnd.integer(); // - 2^31 .. 2^31 - 1 + /// bool g = rnd.boolean(); // P(g = true) = 0.5 + /// bool h = rnd.boolean(0.8); // P(h = true) = 0.8 + ///\endcode + /// + /// LEMON provides a global instance of the random number + /// generator which name is \ref lemon::rnd "rnd". Usually it is a + /// good programming convenience to use this global generator to get + /// random numbers. + class Random { + private: + + // Architecture word + typedef unsigned long Word; + + _random_bits::RandomCore core; + _random_bits::BoolProducer bool_producer; + + + public: + + ///\name Initialization + /// + /// @{ + + /// \brief Default constructor + /// + /// Constructor with constant seeding. + Random() { core.initState(); } + + /// \brief Constructor with seed + /// + /// Constructor with seed. The current number type will be converted + /// to the architecture word type. + template + Random(Number seed) { + _random_bits::Initializer::init(core, seed); + } + + /// \brief Constructor with array seeding + /// + /// Constructor with array seeding. The given range should contain + /// any number type and the numbers will be converted to the + /// architecture word type. + template + Random(Iterator begin, Iterator end) { + typedef typename std::iterator_traits::value_type Number; + _random_bits::Initializer::init(core, begin, end); + } + + /// \brief Copy constructor + /// + /// Copy constructor. The generated sequence will be identical to + /// the other sequence. It can be used to save the current state + /// of the generator and later use it to generate the same + /// sequence. + Random(const Random& other) { + core.copyState(other.core); + } + + /// \brief Assign operator + /// + /// Assign operator. The generated sequence will be identical to + /// the other sequence. It can be used to save the current state + /// of the generator and later use it to generate the same + /// sequence. + Random& operator=(const Random& other) { + if (&other != this) { + core.copyState(other.core); + } + return *this; + } + + /// \brief Seeding random sequence + /// + /// Seeding the random sequence. The current number type will be + /// converted to the architecture word type. + template + void seed(Number seed) { + _random_bits::Initializer::init(core, seed); + } + + /// \brief Seeding random sequence + /// + /// Seeding the random sequence. The given range should contain + /// any number type and the numbers will be converted to the + /// architecture word type. + template + void seed(Iterator begin, Iterator end) { + typedef typename std::iterator_traits::value_type Number; + _random_bits::Initializer::init(core, begin, end); + } + + /// \brief Seeding from file or from process id and time + /// + /// By default, this function calls the \c seedFromFile() member + /// function with the /dev/urandom file. If it does not success, + /// it uses the \c seedFromTime(). + /// \return Currently always \c true. + bool seed() { +#ifndef WIN32 + if (seedFromFile("/dev/urandom", 0)) return true; +#endif + if (seedFromTime()) return true; + return false; + } + + /// \brief Seeding from file + /// + /// Seeding the random sequence from file. The linux kernel has two + /// devices, /dev/random and /dev/urandom which + /// could give good seed values for pseudo random generators (The + /// difference between two devices is that the random may + /// block the reading operation while the kernel can give good + /// source of randomness, while the urandom does not + /// block the input, but it could give back bytes with worse + /// entropy). + /// \param file The source file + /// \param offset The offset, from the file read. + /// \return \c true when the seeding successes. +#ifndef WIN32 + bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0) +#else + bool seedFromFile(const std::string& file = "", int offset = 0) +#endif + { + std::ifstream rs(file.c_str()); + const int size = 4; + Word buf[size]; + if (offset != 0 && !rs.seekg(offset)) return false; + if (!rs.read(reinterpret_cast(buf), sizeof(buf))) return false; + seed(buf, buf + size); + return true; + } + + /// \brief Seding from process id and time + /// + /// Seding from process id and time. This function uses the + /// current process id and the current time for initialize the + /// random sequence. + /// \return Currently always \c true. + bool seedFromTime() { +#ifndef WIN32 + timeval tv; + gettimeofday(&tv, 0); + seed(getpid() + tv.tv_sec + tv.tv_usec); +#else + seed(bits::getWinRndSeed()); +#endif + return true; + } + + /// @} + + ///\name Uniform Distributions + /// + /// @{ + + /// \brief Returns a random real number from the range [0, 1) + /// + /// It returns a random real number from the range [0, 1). The + /// default Number type is \c double. + template + Number real() { + return _random_bits::RealConversion::convert(core); + } + + double real() { + return real(); + } + + /// \brief Returns a random real number from the range [0, 1) + /// + /// It returns a random double from the range [0, 1). + double operator()() { + return real(); + } + + /// \brief Returns a random real number from the range [0, b) + /// + /// It returns a random real number from the range [0, b). + double operator()(double b) { + return real() * b; + } + + /// \brief Returns a random real number from the range [a, b) + /// + /// It returns a random real number from the range [a, b). + double operator()(double a, double b) { + return real() * (b - a) + a; + } + + /// \brief Returns a random integer from a range + /// + /// It returns a random integer from the range {0, 1, ..., b - 1}. + template + Number integer(Number b) { + return _random_bits::Mapping::map(core, b); + } + + /// \brief Returns a random integer from a range + /// + /// It returns a random integer from the range {a, a + 1, ..., b - 1}. + template + Number integer(Number a, Number b) { + return _random_bits::Mapping::map(core, b - a) + a; + } + + /// \brief Returns a random integer from a range + /// + /// It returns a random integer from the range {0, 1, ..., b - 1}. + template + Number operator[](Number b) { + return _random_bits::Mapping::map(core, b); + } + + /// \brief Returns a random non-negative integer + /// + /// It returns a random non-negative integer uniformly from the + /// whole range of the current \c Number type. The default result + /// type of this function is unsigned int. + template + Number uinteger() { + return _random_bits::IntConversion::convert(core); + } + + unsigned int uinteger() { + return uinteger(); + } + + /// \brief Returns a random integer + /// + /// It returns a random integer uniformly from the whole range of + /// the current \c Number type. The default result type of this + /// function is \c int. + template + Number integer() { + static const int nb = std::numeric_limits::digits + + (std::numeric_limits::is_signed ? 1 : 0); + return _random_bits::IntConversion::convert(core); + } + + int integer() { + return integer(); + } + + /// \brief Returns a random bool + /// + /// It returns a random bool. The generator holds a buffer for + /// random bits. Every time when it become empty the generator makes + /// a new random word and fill the buffer up. + bool boolean() { + return bool_producer.convert(core); + } + + /// @} + + ///\name Non-uniform Distributions + /// + ///@{ + + /// \brief Returns a random bool with given probability of true result. + /// + /// It returns a random bool with given probability of true result. + bool boolean(double p) { + return operator()() < p; + } + + /// Standard normal (Gauss) distribution + + /// Standard normal (Gauss) distribution. + /// \note The Cartesian form of the Box-Muller + /// transformation is used to generate a random normal distribution. + double gauss() + { + double V1,V2,S; + do { + V1=2*real()-1; + V2=2*real()-1; + S=V1*V1+V2*V2; + } while(S>=1); + return std::sqrt(-2*std::log(S)/S)*V1; + } + /// Normal (Gauss) distribution with given mean and standard deviation + + /// Normal (Gauss) distribution with given mean and standard deviation. + /// \sa gauss() + double gauss(double mean,double std_dev) + { + return gauss()*std_dev+mean; + } + + /// Lognormal distribution + + /// Lognormal distribution. The parameters are the mean and the standard + /// deviation of exp(X). + /// + double lognormal(double n_mean,double n_std_dev) + { + return std::exp(gauss(n_mean,n_std_dev)); + } + /// Lognormal distribution + + /// Lognormal distribution. The parameter is an std::pair of + /// the mean and the standard deviation of exp(X). + /// + double lognormal(const std::pair ¶ms) + { + return std::exp(gauss(params.first,params.second)); + } + /// Compute the lognormal parameters from mean and standard deviation + + /// This function computes the lognormal parameters from mean and + /// standard deviation. The return value can direcly be passed to + /// lognormal(). + std::pair lognormalParamsFromMD(double mean, + double std_dev) + { + double fr=std_dev/mean; + fr*=fr; + double lg=std::log(1+fr); + return std::pair(std::log(mean)-lg/2.0,std::sqrt(lg)); + } + /// Lognormal distribution with given mean and standard deviation + + /// Lognormal distribution with given mean and standard deviation. + /// + double lognormalMD(double mean,double std_dev) + { + return lognormal(lognormalParamsFromMD(mean,std_dev)); + } + + /// Exponential distribution with given mean + + /// This function generates an exponential distribution random number + /// with mean 1/lambda. + /// + double exponential(double lambda=1.0) + { + return -std::log(1.0-real())/lambda; + } + + /// Gamma distribution with given integer shape + + /// This function generates a gamma distribution random number. + /// + ///\param k shape parameter (k>0 integer) + double gamma(int k) + { + double s = 0; + for(int i=0;i()); + return s; + } + + /// Gamma distribution with given shape and scale parameter + + /// This function generates a gamma distribution random number. + /// + ///\param k shape parameter (k>0) + ///\param theta scale parameter + /// + double gamma(double k,double theta=1.0) + { + double xi,nu; + const double delta = k-std::floor(k); + const double v0=E/(E-delta); + do { + double V0=1.0-real(); + double V1=1.0-real(); + double V2=1.0-real(); + if(V2<=v0) + { + xi=std::pow(V1,1.0/delta); + nu=V0*std::pow(xi,delta-1.0); + } + else + { + xi=1.0-std::log(V1); + nu=V0*std::exp(-xi); + } + } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi)); + return theta*(xi+gamma(int(std::floor(k)))); + } + + /// Weibull distribution + + /// This function generates a Weibull distribution random number. + /// + ///\param k shape parameter (k>0) + ///\param lambda scale parameter (lambda>0) + /// + double weibull(double k,double lambda) + { + return lambda*pow(-std::log(1.0-real()),1.0/k); + } + + /// Pareto distribution + + /// This function generates a Pareto distribution random number. + /// + ///\param k shape parameter (k>0) + ///\param x_min location parameter (x_min>0) + /// + double pareto(double k,double x_min) + { + return exponential(gamma(k,1.0/x_min))+x_min; + } + + /// Poisson distribution + + /// This function generates a Poisson distribution random number with + /// parameter \c lambda. + /// + /// The probability mass function of this distribusion is + /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f] + /// \note The algorithm is taken from the book of Donald E. Knuth titled + /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the + /// return value. + + int poisson(double lambda) + { + const double l = std::exp(-lambda); + int k=0; + double p = 1.0; + do { + k++; + p*=real(); + } while (p>=l); + return k-1; + } + + ///@} + + ///\name Two Dimensional Distributions + /// + ///@{ + + /// Uniform distribution on the full unit circle + + /// Uniform distribution on the full unit circle. + /// + dim2::Point disc() + { + double V1,V2; + do { + V1=2*real()-1; + V2=2*real()-1; + + } while(V1*V1+V2*V2>=1); + return dim2::Point(V1,V2); + } + /// A kind of two dimensional normal (Gauss) distribution + + /// This function provides a turning symmetric two-dimensional distribution. + /// Both coordinates are of standard normal distribution, but they are not + /// independent. + /// + /// \note The coordinates are the two random variables provided by + /// the Box-Muller method. + dim2::Point gauss2() + { + double V1,V2,S; + do { + V1=2*real()-1; + V2=2*real()-1; + S=V1*V1+V2*V2; + } while(S>=1); + double W=std::sqrt(-2*std::log(S)/S); + return dim2::Point(W*V1,W*V2); + } + /// A kind of two dimensional exponential distribution + + /// This function provides a turning symmetric two-dimensional distribution. + /// The x-coordinate is of conditionally exponential distribution + /// with the condition that x is positive and y=0. If x is negative and + /// y=0 then, -x is of exponential distribution. The same is true for the + /// y-coordinate. + dim2::Point exponential2() + { + double V1,V2,S; + do { + V1=2*real()-1; + V2=2*real()-1; + S=V1*V1+V2*V2; + } while(S>=1); + double W=-std::log(S)/S; + return dim2::Point(W*V1,W*V2); + } + + ///@} + }; + + + extern Random rnd; + +} + +#endif diff --git a/lemon/lemon/smart_graph.h b/lemon/lemon/smart_graph.h new file mode 100644 index 0000000..4cd0f49 --- /dev/null +++ b/lemon/lemon/smart_graph.h @@ -0,0 +1,817 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_SMART_GRAPH_H +#define LEMON_SMART_GRAPH_H + +///\ingroup graphs +///\file +///\brief SmartDigraph and SmartGraph classes. + +#include + +#include +#include +#include + +namespace lemon { + + class SmartDigraph; + + class SmartDigraphBase { + protected: + + struct NodeT + { + int first_in, first_out; + NodeT() {} + }; + struct ArcT + { + int target, source, next_in, next_out; + ArcT() {} + }; + + std::vector nodes; + std::vector arcs; + + public: + + typedef SmartDigraphBase Digraph; + + class Node; + class Arc; + + public: + + SmartDigraphBase() : nodes(), arcs() { } + SmartDigraphBase(const SmartDigraphBase &_g) + : nodes(_g.nodes), arcs(_g.arcs) { } + + typedef True NodeNumTag; + typedef True ArcNumTag; + + int nodeNum() const { return nodes.size(); } + int arcNum() const { return arcs.size(); } + + int maxNodeId() const { return nodes.size()-1; } + int maxArcId() const { return arcs.size()-1; } + + Node addNode() { + int n = nodes.size(); + nodes.push_back(NodeT()); + nodes[n].first_in = -1; + nodes[n].first_out = -1; + return Node(n); + } + + Arc addArc(Node u, Node v) { + int n = arcs.size(); + arcs.push_back(ArcT()); + arcs[n].source = u._id; + arcs[n].target = v._id; + arcs[n].next_out = nodes[u._id].first_out; + arcs[n].next_in = nodes[v._id].first_in; + nodes[u._id].first_out = nodes[v._id].first_in = n; + + return Arc(n); + } + + void clear() { + arcs.clear(); + nodes.clear(); + } + + Node source(Arc a) const { return Node(arcs[a._id].source); } + Node target(Arc a) const { return Node(arcs[a._id].target); } + + static int id(Node v) { return v._id; } + static int id(Arc a) { return a._id; } + + static Node nodeFromId(int id) { return Node(id);} + static Arc arcFromId(int id) { return Arc(id);} + + bool valid(Node n) const { + return n._id >= 0 && n._id < static_cast(nodes.size()); + } + bool valid(Arc a) const { + return a._id >= 0 && a._id < static_cast(arcs.size()); + } + + class Node { + friend class SmartDigraphBase; + friend class SmartDigraph; + + protected: + int _id; + explicit Node(int id) : _id(id) {} + public: + Node() {} + Node (Invalid) : _id(-1) {} + bool operator==(const Node i) const {return _id == i._id;} + bool operator!=(const Node i) const {return _id != i._id;} + bool operator<(const Node i) const {return _id < i._id;} + }; + + + class Arc { + friend class SmartDigraphBase; + friend class SmartDigraph; + + protected: + int _id; + explicit Arc(int id) : _id(id) {} + public: + Arc() { } + Arc (Invalid) : _id(-1) {} + bool operator==(const Arc i) const {return _id == i._id;} + bool operator!=(const Arc i) const {return _id != i._id;} + bool operator<(const Arc i) const {return _id < i._id;} + }; + + void first(Node& node) const { + node._id = nodes.size() - 1; + } + + static void next(Node& node) { + --node._id; + } + + void first(Arc& arc) const { + arc._id = arcs.size() - 1; + } + + static void next(Arc& arc) { + --arc._id; + } + + void firstOut(Arc& arc, const Node& node) const { + arc._id = nodes[node._id].first_out; + } + + void nextOut(Arc& arc) const { + arc._id = arcs[arc._id].next_out; + } + + void firstIn(Arc& arc, const Node& node) const { + arc._id = nodes[node._id].first_in; + } + + void nextIn(Arc& arc) const { + arc._id = arcs[arc._id].next_in; + } + + }; + + typedef DigraphExtender ExtendedSmartDigraphBase; + + ///\ingroup graphs + /// + ///\brief A smart directed graph class. + /// + ///\ref SmartDigraph is a simple and fast digraph implementation. + ///It is also quite memory efficient but at the price + ///that it does not support node and arc deletion + ///(except for the Snapshot feature). + /// + ///This type fully conforms to the \ref concepts::Digraph "Digraph concept" + ///and it also provides some additional functionalities. + ///Most of its member functions and nested classes are documented + ///only in the concept class. + /// + ///This class provides constant time counting for nodes and arcs. + /// + ///\sa concepts::Digraph + ///\sa SmartGraph + class SmartDigraph : public ExtendedSmartDigraphBase { + typedef ExtendedSmartDigraphBase Parent; + + private: + /// Digraphs are \e not copy constructible. Use DigraphCopy instead. + SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {}; + /// \brief Assignment of a digraph to another one is \e not allowed. + /// Use DigraphCopy instead. + void operator=(const SmartDigraph &) {} + + public: + + /// Constructor + + /// Constructor. + /// + SmartDigraph() {}; + + ///Add a new node to the digraph. + + ///This function adds a new node to the digraph. + ///\return The new node. + Node addNode() { return Parent::addNode(); } + + ///Add a new arc to the digraph. + + ///This function adds a new arc to the digraph with source node \c s + ///and target node \c t. + ///\return The new arc. + Arc addArc(Node s, Node t) { + return Parent::addArc(s, t); + } + + /// \brief Node validity check + /// + /// This function gives back \c true if the given node is valid, + /// i.e. it is a real node of the digraph. + /// + /// \warning A removed node (using Snapshot) could become valid again + /// if new nodes are added to the digraph. + bool valid(Node n) const { return Parent::valid(n); } + + /// \brief Arc validity check + /// + /// This function gives back \c true if the given arc is valid, + /// i.e. it is a real arc of the digraph. + /// + /// \warning A removed arc (using Snapshot) could become valid again + /// if new arcs are added to the graph. + bool valid(Arc a) const { return Parent::valid(a); } + + ///Split a node. + + ///This function splits the given node. First, a new node is added + ///to the digraph, then the source of each outgoing arc of node \c n + ///is moved to this new node. + ///If the second parameter \c connect is \c true (this is the default + ///value), then a new arc from node \c n to the newly created node + ///is also added. + ///\return The newly created node. + /// + ///\note All iterators remain valid. + /// + ///\warning This functionality cannot be used together with the Snapshot + ///feature. + Node split(Node n, bool connect = true) + { + Node b = addNode(); + nodes[b._id].first_out=nodes[n._id].first_out; + nodes[n._id].first_out=-1; + for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) { + arcs[i].source=b._id; + } + if(connect) addArc(n,b); + return b; + } + + ///Clear the digraph. + + ///This function erases all nodes and arcs from the digraph. + /// + void clear() { + Parent::clear(); + } + + /// Reserve memory for nodes. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the digraph you want to build will + /// be large (e.g. it will contain millions of nodes and/or arcs), + /// then it is worth reserving space for this amount before starting + /// to build the digraph. + /// \sa reserveArc() + void reserveNode(int n) { nodes.reserve(n); }; + + /// Reserve memory for arcs. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the digraph you want to build will + /// be large (e.g. it will contain millions of nodes and/or arcs), + /// then it is worth reserving space for this amount before starting + /// to build the digraph. + /// \sa reserveNode() + void reserveArc(int m) { arcs.reserve(m); }; + + public: + + class Snapshot; + + protected: + + void restoreSnapshot(const Snapshot &s) + { + while(s.arc_numnodes.size(); + arc_num=_graph->arcs.size(); + } + + ///Make a snapshot. + + ///This function makes a snapshot of the given digraph. + ///It can be called more than once. In case of a repeated + ///call, the previous snapshot gets lost. + void save(SmartDigraph &gr) { + _graph=&gr; + node_num=_graph->nodes.size(); + arc_num=_graph->arcs.size(); + } + + ///Undo the changes until a snapshot. + + ///This function undos the changes until the last snapshot + ///created by save() or Snapshot(SmartDigraph&). + void restore() + { + _graph->restoreSnapshot(*this); + } + }; + }; + + + class SmartGraphBase { + + protected: + + struct NodeT { + int first_out; + }; + + struct ArcT { + int target; + int next_out; + }; + + std::vector nodes; + std::vector arcs; + + int first_free_arc; + + public: + + typedef SmartGraphBase Graph; + + class Node; + class Arc; + class Edge; + + class Node { + friend class SmartGraphBase; + protected: + + int _id; + explicit Node(int id) { _id = id;} + + public: + Node() {} + Node (Invalid) { _id = -1; } + bool operator==(const Node& node) const {return _id == node._id;} + bool operator!=(const Node& node) const {return _id != node._id;} + bool operator<(const Node& node) const {return _id < node._id;} + }; + + class Edge { + friend class SmartGraphBase; + protected: + + int _id; + explicit Edge(int id) { _id = id;} + + public: + Edge() {} + Edge (Invalid) { _id = -1; } + bool operator==(const Edge& arc) const {return _id == arc._id;} + bool operator!=(const Edge& arc) const {return _id != arc._id;} + bool operator<(const Edge& arc) const {return _id < arc._id;} + }; + + class Arc { + friend class SmartGraphBase; + protected: + + int _id; + explicit Arc(int id) { _id = id;} + + public: + operator Edge() const { + return _id != -1 ? edgeFromId(_id / 2) : INVALID; + } + + Arc() {} + Arc (Invalid) { _id = -1; } + bool operator==(const Arc& arc) const {return _id == arc._id;} + bool operator!=(const Arc& arc) const {return _id != arc._id;} + bool operator<(const Arc& arc) const {return _id < arc._id;} + }; + + + + SmartGraphBase() + : nodes(), arcs() {} + + typedef True NodeNumTag; + typedef True EdgeNumTag; + typedef True ArcNumTag; + + int nodeNum() const { return nodes.size(); } + int edgeNum() const { return arcs.size() / 2; } + int arcNum() const { return arcs.size(); } + + int maxNodeId() const { return nodes.size()-1; } + int maxEdgeId() const { return arcs.size() / 2 - 1; } + int maxArcId() const { return arcs.size()-1; } + + Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); } + Node target(Arc e) const { return Node(arcs[e._id].target); } + + Node u(Edge e) const { return Node(arcs[2 * e._id].target); } + Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); } + + static bool direction(Arc e) { + return (e._id & 1) == 1; + } + + static Arc direct(Edge e, bool d) { + return Arc(e._id * 2 + (d ? 1 : 0)); + } + + void first(Node& node) const { + node._id = nodes.size() - 1; + } + + static void next(Node& node) { + --node._id; + } + + void first(Arc& arc) const { + arc._id = arcs.size() - 1; + } + + static void next(Arc& arc) { + --arc._id; + } + + void first(Edge& arc) const { + arc._id = arcs.size() / 2 - 1; + } + + static void next(Edge& arc) { + --arc._id; + } + + void firstOut(Arc &arc, const Node& v) const { + arc._id = nodes[v._id].first_out; + } + void nextOut(Arc &arc) const { + arc._id = arcs[arc._id].next_out; + } + + void firstIn(Arc &arc, const Node& v) const { + arc._id = ((nodes[v._id].first_out) ^ 1); + if (arc._id == -2) arc._id = -1; + } + void nextIn(Arc &arc) const { + arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1); + if (arc._id == -2) arc._id = -1; + } + + void firstInc(Edge &arc, bool& d, const Node& v) const { + int de = nodes[v._id].first_out; + if (de != -1) { + arc._id = de / 2; + d = ((de & 1) == 1); + } else { + arc._id = -1; + d = true; + } + } + void nextInc(Edge &arc, bool& d) const { + int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out); + if (de != -1) { + arc._id = de / 2; + d = ((de & 1) == 1); + } else { + arc._id = -1; + d = true; + } + } + + static int id(Node v) { return v._id; } + static int id(Arc e) { return e._id; } + static int id(Edge e) { return e._id; } + + static Node nodeFromId(int id) { return Node(id);} + static Arc arcFromId(int id) { return Arc(id);} + static Edge edgeFromId(int id) { return Edge(id);} + + bool valid(Node n) const { + return n._id >= 0 && n._id < static_cast(nodes.size()); + } + bool valid(Arc a) const { + return a._id >= 0 && a._id < static_cast(arcs.size()); + } + bool valid(Edge e) const { + return e._id >= 0 && 2 * e._id < static_cast(arcs.size()); + } + + Node addNode() { + int n = nodes.size(); + nodes.push_back(NodeT()); + nodes[n].first_out = -1; + + return Node(n); + } + + Edge addEdge(Node u, Node v) { + int n = arcs.size(); + arcs.push_back(ArcT()); + arcs.push_back(ArcT()); + + arcs[n].target = u._id; + arcs[n | 1].target = v._id; + + arcs[n].next_out = nodes[v._id].first_out; + nodes[v._id].first_out = n; + + arcs[n | 1].next_out = nodes[u._id].first_out; + nodes[u._id].first_out = (n | 1); + + return Edge(n / 2); + } + + void clear() { + arcs.clear(); + nodes.clear(); + } + + }; + + typedef GraphExtender ExtendedSmartGraphBase; + + /// \ingroup graphs + /// + /// \brief A smart undirected graph class. + /// + /// \ref SmartGraph is a simple and fast graph implementation. + /// It is also quite memory efficient but at the price + /// that it does not support node and edge deletion + /// (except for the Snapshot feature). + /// + /// This type fully conforms to the \ref concepts::Graph "Graph concept" + /// and it also provides some additional functionalities. + /// Most of its member functions and nested classes are documented + /// only in the concept class. + /// + /// This class provides constant time counting for nodes, edges and arcs. + /// + /// \sa concepts::Graph + /// \sa SmartDigraph + class SmartGraph : public ExtendedSmartGraphBase { + typedef ExtendedSmartGraphBase Parent; + + private: + /// Graphs are \e not copy constructible. Use GraphCopy instead. + SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {}; + /// \brief Assignment of a graph to another one is \e not allowed. + /// Use GraphCopy instead. + void operator=(const SmartGraph &) {} + + public: + + /// Constructor + + /// Constructor. + /// + SmartGraph() {} + + /// \brief Add a new node to the graph. + /// + /// This function adds a new node to the graph. + /// \return The new node. + Node addNode() { return Parent::addNode(); } + + /// \brief Add a new edge to the graph. + /// + /// This function adds a new edge to the graph between nodes + /// \c u and \c v with inherent orientation from node \c u to + /// node \c v. + /// \return The new edge. + Edge addEdge(Node u, Node v) { + return Parent::addEdge(u, v); + } + + /// \brief Node validity check + /// + /// This function gives back \c true if the given node is valid, + /// i.e. it is a real node of the graph. + /// + /// \warning A removed node (using Snapshot) could become valid again + /// if new nodes are added to the graph. + bool valid(Node n) const { return Parent::valid(n); } + + /// \brief Edge validity check + /// + /// This function gives back \c true if the given edge is valid, + /// i.e. it is a real edge of the graph. + /// + /// \warning A removed edge (using Snapshot) could become valid again + /// if new edges are added to the graph. + bool valid(Edge e) const { return Parent::valid(e); } + + /// \brief Arc validity check + /// + /// This function gives back \c true if the given arc is valid, + /// i.e. it is a real arc of the graph. + /// + /// \warning A removed arc (using Snapshot) could become valid again + /// if new edges are added to the graph. + bool valid(Arc a) const { return Parent::valid(a); } + + ///Clear the graph. + + ///This function erases all nodes and arcs from the graph. + /// + void clear() { + Parent::clear(); + } + + /// Reserve memory for nodes. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the graph you want to build will + /// be large (e.g. it will contain millions of nodes and/or edges), + /// then it is worth reserving space for this amount before starting + /// to build the graph. + /// \sa reserveEdge() + void reserveNode(int n) { nodes.reserve(n); }; + + /// Reserve memory for edges. + + /// Using this function, it is possible to avoid superfluous memory + /// allocation: if you know that the graph you want to build will + /// be large (e.g. it will contain millions of nodes and/or edges), + /// then it is worth reserving space for this amount before starting + /// to build the graph. + /// \sa reserveNode() + void reserveEdge(int m) { arcs.reserve(2 * m); }; + + public: + + class Snapshot; + + protected: + + void saveSnapshot(Snapshot &s) + { + s._graph = this; + s.node_num = nodes.size(); + s.arc_num = arcs.size(); + } + + void restoreSnapshot(const Snapshot &s) + { + while(s.arc_num dir; + dir.push_back(arcFromId(n)); + dir.push_back(arcFromId(n-1)); + Parent::notifier(Arc()).erase(dir); + nodes[arcs[n-1].target].first_out=arcs[n].next_out; + nodes[arcs[n].target].first_out=arcs[n-1].next_out; + arcs.pop_back(); + arcs.pop_back(); + } + while(s.node_numrestoreSnapshot(*this); + } + }; + }; + +} //namespace lemon + + +#endif //LEMON_SMART_GRAPH_H diff --git a/lemon/lemon/soplex.cc b/lemon/lemon/soplex.cc new file mode 100644 index 0000000..af9d35e --- /dev/null +++ b/lemon/lemon/soplex.cc @@ -0,0 +1,465 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include + + +///\file +///\brief Implementation of the LEMON-SOPLEX lp solver interface. +namespace lemon { + + SoplexLp::SoplexLp() { + soplex = new soplex::SoPlex; + messageLevel(MESSAGE_NOTHING); + } + + SoplexLp::~SoplexLp() { + delete soplex; + } + + SoplexLp::SoplexLp(const SoplexLp& lp) { + rows = lp.rows; + cols = lp.cols; + + soplex = new soplex::SoPlex; + (*static_cast(soplex)) = *(lp.soplex); + + _col_names = lp._col_names; + _col_names_ref = lp._col_names_ref; + + _row_names = lp._row_names; + _row_names_ref = lp._row_names_ref; + + messageLevel(MESSAGE_NOTHING); + } + + void SoplexLp::_clear_temporals() { + _primal_values.clear(); + _dual_values.clear(); + } + + SoplexLp* SoplexLp::newSolver() const { + SoplexLp* newlp = new SoplexLp(); + return newlp; + } + + SoplexLp* SoplexLp::cloneSolver() const { + SoplexLp* newlp = new SoplexLp(*this); + return newlp; + } + + const char* SoplexLp::_solverName() const { return "SoplexLp"; } + + int SoplexLp::_addCol() { + soplex::LPCol c; + c.setLower(-soplex::infinity); + c.setUpper(soplex::infinity); + soplex->addCol(c); + + _col_names.push_back(std::string()); + + return soplex->nCols() - 1; + } + + int SoplexLp::_addRow() { + soplex::LPRow r; + r.setLhs(-soplex::infinity); + r.setRhs(soplex::infinity); + soplex->addRow(r); + + _row_names.push_back(std::string()); + + return soplex->nRows() - 1; + } + + int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) { + soplex::DSVector v; + for (ExprIterator it = b; it != e; ++it) { + v.add(it->first, it->second); + } + soplex::LPRow r(l, v, u); + soplex->addRow(r); + + _row_names.push_back(std::string()); + + return soplex->nRows() - 1; + } + + + void SoplexLp::_eraseCol(int i) { + soplex->removeCol(i); + _col_names_ref.erase(_col_names[i]); + _col_names[i] = _col_names.back(); + _col_names_ref[_col_names.back()] = i; + _col_names.pop_back(); + } + + void SoplexLp::_eraseRow(int i) { + soplex->removeRow(i); + _row_names_ref.erase(_row_names[i]); + _row_names[i] = _row_names.back(); + _row_names_ref[_row_names.back()] = i; + _row_names.pop_back(); + } + + void SoplexLp::_eraseColId(int i) { + cols.eraseIndex(i); + cols.relocateIndex(i, cols.maxIndex()); + } + void SoplexLp::_eraseRowId(int i) { + rows.eraseIndex(i); + rows.relocateIndex(i, rows.maxIndex()); + } + + void SoplexLp::_getColName(int c, std::string &name) const { + name = _col_names[c]; + } + + void SoplexLp::_setColName(int c, const std::string &name) { + _col_names_ref.erase(_col_names[c]); + _col_names[c] = name; + if (!name.empty()) { + _col_names_ref.insert(std::make_pair(name, c)); + } + } + + int SoplexLp::_colByName(const std::string& name) const { + std::map::const_iterator it = + _col_names_ref.find(name); + if (it != _col_names_ref.end()) { + return it->second; + } else { + return -1; + } + } + + void SoplexLp::_getRowName(int r, std::string &name) const { + name = _row_names[r]; + } + + void SoplexLp::_setRowName(int r, const std::string &name) { + _row_names_ref.erase(_row_names[r]); + _row_names[r] = name; + if (!name.empty()) { + _row_names_ref.insert(std::make_pair(name, r)); + } + } + + int SoplexLp::_rowByName(const std::string& name) const { + std::map::const_iterator it = + _row_names_ref.find(name); + if (it != _row_names_ref.end()) { + return it->second; + } else { + return -1; + } + } + + + void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) { + for (int j = 0; j < soplex->nCols(); ++j) { + soplex->changeElement(i, j, 0.0); + } + for(ExprIterator it = b; it != e; ++it) { + soplex->changeElement(i, it->first, it->second); + } + } + + void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const { + const soplex::SVector& vec = soplex->rowVector(i); + for (int k = 0; k < vec.size(); ++k) { + *b = std::make_pair(vec.index(k), vec.value(k)); + ++b; + } + } + + void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) { + for (int i = 0; i < soplex->nRows(); ++i) { + soplex->changeElement(i, j, 0.0); + } + for(ExprIterator it = b; it != e; ++it) { + soplex->changeElement(it->first, j, it->second); + } + } + + void SoplexLp::_getColCoeffs(int i, InsertIterator b) const { + const soplex::SVector& vec = soplex->colVector(i); + for (int k = 0; k < vec.size(); ++k) { + *b = std::make_pair(vec.index(k), vec.value(k)); + ++b; + } + } + + void SoplexLp::_setCoeff(int i, int j, Value value) { + soplex->changeElement(i, j, value); + } + + SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const { + return soplex->rowVector(i)[j]; + } + + void SoplexLp::_setColLowerBound(int i, Value value) { + LEMON_ASSERT(value != INF, "Invalid bound"); + soplex->changeLower(i, value != -INF ? value : -soplex::infinity); + } + + SoplexLp::Value SoplexLp::_getColLowerBound(int i) const { + double value = soplex->lower(i); + return value != -soplex::infinity ? value : -INF; + } + + void SoplexLp::_setColUpperBound(int i, Value value) { + LEMON_ASSERT(value != -INF, "Invalid bound"); + soplex->changeUpper(i, value != INF ? value : soplex::infinity); + } + + SoplexLp::Value SoplexLp::_getColUpperBound(int i) const { + double value = soplex->upper(i); + return value != soplex::infinity ? value : INF; + } + + void SoplexLp::_setRowLowerBound(int i, Value lb) { + LEMON_ASSERT(lb != INF, "Invalid bound"); + soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i)); + } + + SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const { + double res = soplex->lhs(i); + return res == -soplex::infinity ? -INF : res; + } + + void SoplexLp::_setRowUpperBound(int i, Value ub) { + LEMON_ASSERT(ub != -INF, "Invalid bound"); + soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity); + } + + SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const { + double res = soplex->rhs(i); + return res == soplex::infinity ? INF : res; + } + + void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) { + for (int j = 0; j < soplex->nCols(); ++j) { + soplex->changeObj(j, 0.0); + } + for (ExprIterator it = b; it != e; ++it) { + soplex->changeObj(it->first, it->second); + } + } + + void SoplexLp::_getObjCoeffs(InsertIterator b) const { + for (int j = 0; j < soplex->nCols(); ++j) { + Value coef = soplex->obj(j); + if (coef != 0.0) { + *b = std::make_pair(j, coef); + ++b; + } + } + } + + void SoplexLp::_setObjCoeff(int i, Value obj_coef) { + soplex->changeObj(i, obj_coef); + } + + SoplexLp::Value SoplexLp::_getObjCoeff(int i) const { + return soplex->obj(i); + } + + SoplexLp::SolveExitStatus SoplexLp::_solve() { + + _clear_temporals(); + + _applyMessageLevel(); + + soplex::SPxSolver::Status status = soplex->solve(); + + switch (status) { + case soplex::SPxSolver::OPTIMAL: + case soplex::SPxSolver::INFEASIBLE: + case soplex::SPxSolver::UNBOUNDED: + return SOLVED; + default: + return UNSOLVED; + } + } + + SoplexLp::Value SoplexLp::_getPrimal(int i) const { + if (_primal_values.empty()) { + _primal_values.resize(soplex->nCols()); + soplex::Vector pv(_primal_values.size(), &_primal_values.front()); + soplex->getPrimal(pv); + } + return _primal_values[i]; + } + + SoplexLp::Value SoplexLp::_getDual(int i) const { + if (_dual_values.empty()) { + _dual_values.resize(soplex->nRows()); + soplex::Vector dv(_dual_values.size(), &_dual_values.front()); + soplex->getDual(dv); + } + return _dual_values[i]; + } + + SoplexLp::Value SoplexLp::_getPrimalValue() const { + return soplex->objValue(); + } + + SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const { + switch (soplex->getBasisColStatus(i)) { + case soplex::SPxSolver::BASIC: + return BASIC; + case soplex::SPxSolver::ON_UPPER: + return UPPER; + case soplex::SPxSolver::ON_LOWER: + return LOWER; + case soplex::SPxSolver::FIXED: + return FIXED; + case soplex::SPxSolver::ZERO: + return FREE; + default: + LEMON_ASSERT(false, "Wrong column status"); + return VarStatus(); + } + } + + SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const { + switch (soplex->getBasisRowStatus(i)) { + case soplex::SPxSolver::BASIC: + return BASIC; + case soplex::SPxSolver::ON_UPPER: + return UPPER; + case soplex::SPxSolver::ON_LOWER: + return LOWER; + case soplex::SPxSolver::FIXED: + return FIXED; + case soplex::SPxSolver::ZERO: + return FREE; + default: + LEMON_ASSERT(false, "Wrong row status"); + return VarStatus(); + } + } + + SoplexLp::Value SoplexLp::_getPrimalRay(int i) const { + if (_primal_ray.empty()) { + _primal_ray.resize(soplex->nCols()); + soplex::Vector pv(_primal_ray.size(), &_primal_ray.front()); + soplex->getDualfarkas(pv); + } + return _primal_ray[i]; + } + + SoplexLp::Value SoplexLp::_getDualRay(int i) const { + if (_dual_ray.empty()) { + _dual_ray.resize(soplex->nRows()); + soplex::Vector dv(_dual_ray.size(), &_dual_ray.front()); + soplex->getDualfarkas(dv); + } + return _dual_ray[i]; + } + + SoplexLp::ProblemType SoplexLp::_getPrimalType() const { + switch (soplex->status()) { + case soplex::SPxSolver::OPTIMAL: + return OPTIMAL; + case soplex::SPxSolver::UNBOUNDED: + return UNBOUNDED; + case soplex::SPxSolver::INFEASIBLE: + return INFEASIBLE; + default: + return UNDEFINED; + } + } + + SoplexLp::ProblemType SoplexLp::_getDualType() const { + switch (soplex->status()) { + case soplex::SPxSolver::OPTIMAL: + return OPTIMAL; + case soplex::SPxSolver::UNBOUNDED: + return UNBOUNDED; + case soplex::SPxSolver::INFEASIBLE: + return INFEASIBLE; + default: + return UNDEFINED; + } + } + + void SoplexLp::_setSense(Sense sense) { + switch (sense) { + case MIN: + soplex->changeSense(soplex::SPxSolver::MINIMIZE); + break; + case MAX: + soplex->changeSense(soplex::SPxSolver::MAXIMIZE); + } + } + + SoplexLp::Sense SoplexLp::_getSense() const { + switch (soplex->spxSense()) { + case soplex::SPxSolver::MAXIMIZE: + return MAX; + case soplex::SPxSolver::MINIMIZE: + return MIN; + default: + LEMON_ASSERT(false, "Wrong sense."); + return SoplexLp::Sense(); + } + } + + void SoplexLp::_clear() { + soplex->clear(); + _col_names.clear(); + _col_names_ref.clear(); + _row_names.clear(); + _row_names_ref.clear(); + cols.clear(); + rows.clear(); + _clear_temporals(); + } + + void SoplexLp::_messageLevel(MessageLevel level) { + switch (level) { + case MESSAGE_NOTHING: + _message_level = -1; + break; + case MESSAGE_ERROR: + _message_level = soplex::SPxOut::ERROR; + break; + case MESSAGE_WARNING: + _message_level = soplex::SPxOut::WARNING; + break; + case MESSAGE_NORMAL: + _message_level = soplex::SPxOut::INFO2; + break; + case MESSAGE_VERBOSE: + _message_level = soplex::SPxOut::DEBUG; + break; + } + } + + void SoplexLp::_applyMessageLevel() { + soplex::Param::setVerbose(_message_level); + } + +} //namespace lemon + diff --git a/lemon/lemon/soplex.h b/lemon/lemon/soplex.h new file mode 100644 index 0000000..7ed3d39 --- /dev/null +++ b/lemon/lemon/soplex.h @@ -0,0 +1,158 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_SOPLEX_H +#define LEMON_SOPLEX_H + +///\file +///\brief Header of the LEMON-SOPLEX lp solver interface. + +#include +#include + +#include + +// Forward declaration +namespace soplex { + class SoPlex; +} + +namespace lemon { + + /// \ingroup lp_group + /// + /// \brief Interface for the SOPLEX solver + /// + /// This class implements an interface for the SoPlex LP solver. + /// The SoPlex library is an object oriented lp solver library + /// developed at the Konrad-Zuse-Zentrum für Informationstechnik + /// Berlin (ZIB). You can find detailed information about it at the + /// http://soplex.zib.de address. + class SoplexLp : public LpSolver { + private: + + soplex::SoPlex* soplex; + + std::vector _col_names; + std::map _col_names_ref; + + std::vector _row_names; + std::map _row_names_ref; + + private: + + // these values cannot be retrieved element by element + mutable std::vector _primal_values; + mutable std::vector _dual_values; + + mutable std::vector _primal_ray; + mutable std::vector _dual_ray; + + void _clear_temporals(); + + public: + + /// \e + SoplexLp(); + /// \e + SoplexLp(const SoplexLp&); + /// \e + ~SoplexLp(); + /// \e + virtual SoplexLp* newSolver() const; + /// \e + virtual SoplexLp* cloneSolver() const; + + protected: + + virtual const char* _solverName() const; + + virtual int _addCol(); + virtual int _addRow(); + virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u); + + virtual void _eraseCol(int i); + virtual void _eraseRow(int i); + + virtual void _eraseColId(int i); + virtual void _eraseRowId(int i); + + virtual void _getColName(int col, std::string& name) const; + virtual void _setColName(int col, const std::string& name); + virtual int _colByName(const std::string& name) const; + + virtual void _getRowName(int row, std::string& name) const; + virtual void _setRowName(int row, const std::string& name); + virtual int _rowByName(const std::string& name) const; + + virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getRowCoeffs(int i, InsertIterator b) const; + + virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e); + virtual void _getColCoeffs(int i, InsertIterator b) const; + + virtual void _setCoeff(int row, int col, Value value); + virtual Value _getCoeff(int row, int col) const; + + virtual void _setColLowerBound(int i, Value value); + virtual Value _getColLowerBound(int i) const; + virtual void _setColUpperBound(int i, Value value); + virtual Value _getColUpperBound(int i) const; + + virtual void _setRowLowerBound(int i, Value value); + virtual Value _getRowLowerBound(int i) const; + virtual void _setRowUpperBound(int i, Value value); + virtual Value _getRowUpperBound(int i) const; + + virtual void _setObjCoeffs(ExprIterator b, ExprIterator e); + virtual void _getObjCoeffs(InsertIterator b) const; + + virtual void _setObjCoeff(int i, Value obj_coef); + virtual Value _getObjCoeff(int i) const; + + virtual void _setSense(Sense sense); + virtual Sense _getSense() const; + + virtual SolveExitStatus _solve(); + virtual Value _getPrimal(int i) const; + virtual Value _getDual(int i) const; + + virtual Value _getPrimalValue() const; + + virtual Value _getPrimalRay(int i) const; + virtual Value _getDualRay(int i) const; + + virtual VarStatus _getColStatus(int i) const; + virtual VarStatus _getRowStatus(int i) const; + + virtual ProblemType _getPrimalType() const; + virtual ProblemType _getDualType() const; + + virtual void _clear(); + + void _messageLevel(MessageLevel m); + void _applyMessageLevel(); + + int _message_level; + + }; + +} //END OF NAMESPACE LEMON + +#endif //LEMON_SOPLEX_H + diff --git a/lemon/lemon/stamp-h2 b/lemon/lemon/stamp-h2 new file mode 100644 index 0000000..e3c8317 --- /dev/null +++ b/lemon/lemon/stamp-h2 @@ -0,0 +1 @@ +timestamp for lemon/config.h diff --git a/lemon/lemon/static_graph.h b/lemon/lemon/static_graph.h new file mode 100644 index 0000000..1f04e40 --- /dev/null +++ b/lemon/lemon/static_graph.h @@ -0,0 +1,476 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_STATIC_GRAPH_H +#define LEMON_STATIC_GRAPH_H + +///\ingroup graphs +///\file +///\brief StaticDigraph class. + +#include +#include + +namespace lemon { + + class StaticDigraphBase { + public: + + StaticDigraphBase() + : built(false), node_num(0), arc_num(0), + node_first_out(NULL), node_first_in(NULL), + arc_source(NULL), arc_target(NULL), + arc_next_in(NULL), arc_next_out(NULL) {} + + ~StaticDigraphBase() { + if (built) { + delete[] node_first_out; + delete[] node_first_in; + delete[] arc_source; + delete[] arc_target; + delete[] arc_next_out; + delete[] arc_next_in; + } + } + + class Node { + friend class StaticDigraphBase; + protected: + int id; + Node(int _id) : id(_id) {} + public: + Node() {} + Node (Invalid) : id(-1) {} + bool operator==(const Node& node) const { return id == node.id; } + bool operator!=(const Node& node) const { return id != node.id; } + bool operator<(const Node& node) const { return id < node.id; } + }; + + class Arc { + friend class StaticDigraphBase; + protected: + int id; + Arc(int _id) : id(_id) {} + public: + Arc() { } + Arc (Invalid) : id(-1) {} + bool operator==(const Arc& arc) const { return id == arc.id; } + bool operator!=(const Arc& arc) const { return id != arc.id; } + bool operator<(const Arc& arc) const { return id < arc.id; } + }; + + Node source(const Arc& e) const { return Node(arc_source[e.id]); } + Node target(const Arc& e) const { return Node(arc_target[e.id]); } + + void first(Node& n) const { n.id = node_num - 1; } + static void next(Node& n) { --n.id; } + + void first(Arc& e) const { e.id = arc_num - 1; } + static void next(Arc& e) { --e.id; } + + void firstOut(Arc& e, const Node& n) const { + e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? + node_first_out[n.id] : -1; + } + void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; } + + void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; } + void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; } + + static int id(const Node& n) { return n.id; } + static Node nodeFromId(int id) { return Node(id); } + int maxNodeId() const { return node_num - 1; } + + static int id(const Arc& e) { return e.id; } + static Arc arcFromId(int id) { return Arc(id); } + int maxArcId() const { return arc_num - 1; } + + typedef True NodeNumTag; + typedef True ArcNumTag; + + int nodeNum() const { return node_num; } + int arcNum() const { return arc_num; } + + private: + + template + class ArcLess { + public: + typedef typename Digraph::Arc Arc; + + ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) + : digraph(_graph), nodeRef(_nodeRef) {} + + bool operator()(const Arc& left, const Arc& right) const { + return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)]; + } + private: + const Digraph& digraph; + const NodeRefMap& nodeRef; + }; + + public: + + typedef True BuildTag; + + void clear() { + if (built) { + delete[] node_first_out; + delete[] node_first_in; + delete[] arc_source; + delete[] arc_target; + delete[] arc_next_out; + delete[] arc_next_in; + } + built = false; + node_num = 0; + arc_num = 0; + } + + template + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { + typedef typename Digraph::Node GNode; + typedef typename Digraph::Arc GArc; + + built = true; + + node_num = countNodes(digraph); + arc_num = countArcs(digraph); + + node_first_out = new int[node_num + 1]; + node_first_in = new int[node_num]; + + arc_source = new int[arc_num]; + arc_target = new int[arc_num]; + arc_next_out = new int[arc_num]; + arc_next_in = new int[arc_num]; + + int node_index = 0; + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) { + nodeRef[n] = Node(node_index); + node_first_in[node_index] = -1; + ++node_index; + } + + ArcLess arcLess(digraph, nodeRef); + + int arc_index = 0; + for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) { + int source = nodeRef[n].id; + std::vector arcs; + for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) { + arcs.push_back(e); + } + if (!arcs.empty()) { + node_first_out[source] = arc_index; + std::sort(arcs.begin(), arcs.end(), arcLess); + for (typename std::vector::iterator it = arcs.begin(); + it != arcs.end(); ++it) { + int target = nodeRef[digraph.target(*it)].id; + arcRef[*it] = Arc(arc_index); + arc_source[arc_index] = source; + arc_target[arc_index] = target; + arc_next_in[arc_index] = node_first_in[target]; + node_first_in[target] = arc_index; + arc_next_out[arc_index] = arc_index + 1; + ++arc_index; + } + arc_next_out[arc_index - 1] = -1; + } else { + node_first_out[source] = arc_index; + } + } + node_first_out[node_num] = arc_num; + } + + template + void build(int n, ArcListIterator first, ArcListIterator last) { + built = true; + + node_num = n; + arc_num = std::distance(first, last); + + node_first_out = new int[node_num + 1]; + node_first_in = new int[node_num]; + + arc_source = new int[arc_num]; + arc_target = new int[arc_num]; + arc_next_out = new int[arc_num]; + arc_next_in = new int[arc_num]; + + for (int i = 0; i != node_num; ++i) { + node_first_in[i] = -1; + } + + int arc_index = 0; + for (int i = 0; i != node_num; ++i) { + node_first_out[i] = arc_index; + for ( ; first != last && (*first).first == i; ++first) { + int j = (*first).second; + LEMON_ASSERT(j >= 0 && j < node_num, + "Wrong arc list for StaticDigraph::build()"); + arc_source[arc_index] = i; + arc_target[arc_index] = j; + arc_next_in[arc_index] = node_first_in[j]; + node_first_in[j] = arc_index; + arc_next_out[arc_index] = arc_index + 1; + ++arc_index; + } + if (arc_index > node_first_out[i]) + arc_next_out[arc_index - 1] = -1; + } + LEMON_ASSERT(first == last, + "Wrong arc list for StaticDigraph::build()"); + node_first_out[node_num] = arc_num; + } + + protected: + + void fastFirstOut(Arc& e, const Node& n) const { + e.id = node_first_out[n.id]; + } + + static void fastNextOut(Arc& e) { + ++e.id; + } + void fastLastOut(Arc& e, const Node& n) const { + e.id = node_first_out[n.id + 1]; + } + + protected: + bool built; + int node_num; + int arc_num; + int *node_first_out; + int *node_first_in; + int *arc_source; + int *arc_target; + int *arc_next_in; + int *arc_next_out; + }; + + typedef DigraphExtender ExtendedStaticDigraphBase; + + + /// \ingroup graphs + /// + /// \brief A static directed graph class. + /// + /// \ref StaticDigraph is a highly efficient digraph implementation, + /// but it is fully static. + /// It stores only two \c int values for each node and only four \c int + /// values for each arc. Moreover it provides faster item iteration than + /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt + /// iterators, since its arcs are stored in an appropriate order. + /// However it only provides build() and clear() functions and does not + /// support any other modification of the digraph. + /// + /// Since this digraph structure is completely static, its nodes and arcs + /// can be indexed with integers from the ranges [0..nodeNum()-1] + /// and [0..arcNum()-1], respectively. + /// The index of an item is the same as its ID, it can be obtained + /// using the corresponding \ref index() or \ref concepts::Digraph::id() + /// "id()" function. A node or arc with a certain index can be obtained + /// using node() or arc(). + /// + /// This type fully conforms to the \ref concepts::Digraph "Digraph concept". + /// Most of its member functions and nested classes are documented + /// only in the concept class. + /// + /// This class provides constant time counting for nodes and arcs. + /// + /// \sa concepts::Digraph + class StaticDigraph : public ExtendedStaticDigraphBase { + public: + + typedef ExtendedStaticDigraphBase Parent; + + public: + + /// \brief Constructor + /// + /// Default constructor. + StaticDigraph() : Parent() {} + + /// \brief The node with the given index. + /// + /// This function returns the node with the given index. + /// \sa index() + static Node node(int ix) { return Parent::nodeFromId(ix); } + + /// \brief The arc with the given index. + /// + /// This function returns the arc with the given index. + /// \sa index() + static Arc arc(int ix) { return Parent::arcFromId(ix); } + + /// \brief The index of the given node. + /// + /// This function returns the index of the the given node. + /// \sa node() + static int index(Node node) { return Parent::id(node); } + + /// \brief The index of the given arc. + /// + /// This function returns the index of the the given arc. + /// \sa arc() + static int index(Arc arc) { return Parent::id(arc); } + + /// \brief Number of nodes. + /// + /// This function returns the number of nodes. + int nodeNum() const { return node_num; } + + /// \brief Number of arcs. + /// + /// This function returns the number of arcs. + int arcNum() const { return arc_num; } + + /// \brief Build the digraph copying another digraph. + /// + /// This function builds the digraph copying another digraph of any + /// kind. It can be called more than once, but in such case, the whole + /// structure and all maps will be cleared and rebuilt. + /// + /// This method also makes possible to copy a digraph to a StaticDigraph + /// structure using \ref DigraphCopy. + /// + /// \param digraph An existing digraph to be copied. + /// \param nodeRef The node references will be copied into this map. + /// Its key type must be \c Digraph::Node and its value type must be + /// \c StaticDigraph::Node. + /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" + /// concept. + /// \param arcRef The arc references will be copied into this map. + /// Its key type must be \c Digraph::Arc and its value type must be + /// \c StaticDigraph::Arc. + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept. + /// + /// \note If you do not need the arc references, then you could use + /// \ref NullMap for the last parameter. However the node references + /// are required by the function itself, thus they must be readable + /// from the map. + template + void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) { + if (built) Parent::clear(); + Parent::build(digraph, nodeRef, arcRef); + } + + /// \brief Build the digraph from an arc list. + /// + /// This function builds the digraph from the given arc list. + /// It can be called more than once, but in such case, the whole + /// structure and all maps will be cleared and rebuilt. + /// + /// The list of the arcs must be given in the range [begin, end) + /// specified by STL compatible itartors whose \c value_type must be + /// std::pair. + /// Each arc must be specified by a pair of integer indices + /// from the range [0..n-1]. The pairs must be in a + /// non-decreasing order with respect to their first values. + /// If the k-th pair in the list is (i,j), then + /// arc(k-1) will connect node(i) to node(j). + /// + /// \param n The number of nodes. + /// \param begin An iterator pointing to the beginning of the arc list. + /// \param end An iterator pointing to the end of the arc list. + /// + /// For example, a simple digraph can be constructed like this. + /// \code + /// std::vector > arcs; + /// arcs.push_back(std::make_pair(0,1)); + /// arcs.push_back(std::make_pair(0,2)); + /// arcs.push_back(std::make_pair(1,3)); + /// arcs.push_back(std::make_pair(1,2)); + /// arcs.push_back(std::make_pair(3,0)); + /// StaticDigraph gr; + /// gr.build(4, arcs.begin(), arcs.end()); + /// \endcode + template + void build(int n, ArcListIterator begin, ArcListIterator end) { + if (built) Parent::clear(); + StaticDigraphBase::build(n, begin, end); + notifier(Node()).build(); + notifier(Arc()).build(); + } + + /// \brief Clear the digraph. + /// + /// This function erases all nodes and arcs from the digraph. + void clear() { + Parent::clear(); + } + + protected: + + using Parent::fastFirstOut; + using Parent::fastNextOut; + using Parent::fastLastOut; + + public: + + class OutArcIt : public Arc { + public: + + OutArcIt() { } + + OutArcIt(Invalid i) : Arc(i) { } + + OutArcIt(const StaticDigraph& digraph, const Node& node) { + digraph.fastFirstOut(*this, node); + digraph.fastLastOut(last, node); + if (last == *this) *this = INVALID; + } + + OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) { + if (arc != INVALID) { + digraph.fastLastOut(last, digraph.source(arc)); + } + } + + OutArcIt& operator++() { + StaticDigraph::fastNextOut(*this); + if (last == *this) *this = INVALID; + return *this; + } + + private: + Arc last; + }; + + Node baseNode(const OutArcIt &arc) const { + return Parent::source(static_cast(arc)); + } + + Node runningNode(const OutArcIt &arc) const { + return Parent::target(static_cast(arc)); + } + + Node baseNode(const InArcIt &arc) const { + return Parent::target(static_cast(arc)); + } + + Node runningNode(const InArcIt &arc) const { + return Parent::source(static_cast(arc)); + } + + }; + +} + +#endif diff --git a/lemon/lemon/suurballe.h b/lemon/lemon/suurballe.h new file mode 100644 index 0000000..ba34875 --- /dev/null +++ b/lemon/lemon/suurballe.h @@ -0,0 +1,776 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_SUURBALLE_H +#define LEMON_SUURBALLE_H + +///\ingroup shortest_path +///\file +///\brief An algorithm for finding arc-disjoint paths between two +/// nodes having minimum total length. + +#include +#include +#include +#include +#include +#include +#include + +namespace lemon { + + /// \brief Default traits class of Suurballe algorithm. + /// + /// Default traits class of Suurballe algorithm. + /// \tparam GR The digraph type the algorithm runs on. + /// \tparam LEN The type of the length map. + /// The default value is GR::ArcMap. +#ifdef DOXYGEN + template +#else + template < typename GR, + typename LEN = typename GR::template ArcMap > +#endif + struct SuurballeDefaultTraits + { + /// The type of the digraph. + typedef GR Digraph; + /// The type of the length map. + typedef LEN LengthMap; + /// The type of the lengths. + typedef typename LEN::Value Length; + /// The type of the flow map. + typedef typename GR::template ArcMap FlowMap; + /// The type of the potential map. + typedef typename GR::template NodeMap PotentialMap; + + /// \brief The path type + /// + /// The type used for storing the found arc-disjoint paths. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addBack() function. + typedef lemon::Path Path; + + /// The cross reference type used for the heap. + typedef typename GR::template NodeMap HeapCrossRef; + + /// \brief The heap type used for internal Dijkstra computations. + /// + /// The type of the heap used for internal Dijkstra computations. + /// It must conform to the \ref lemon::concepts::Heap "Heap" concept + /// and its priority type must be \c Length. + typedef BinHeap Heap; + }; + + /// \addtogroup shortest_path + /// @{ + + /// \brief Algorithm for finding arc-disjoint paths between two nodes + /// having minimum total length. + /// + /// \ref lemon::Suurballe "Suurballe" implements an algorithm for + /// finding arc-disjoint paths having minimum total length (cost) + /// from a given source node to a given target node in a digraph. + /// + /// Note that this problem is a special case of the \ref min_cost_flow + /// "minimum cost flow problem". This implementation is actually an + /// efficient specialized version of the \ref CapacityScaling + /// "successive shortest path" algorithm directly for this problem. + /// Therefore this class provides query functions for flow values and + /// node potentials (the dual solution) just like the minimum cost flow + /// algorithms. + /// + /// \tparam GR The digraph type the algorithm runs on. + /// \tparam LEN The type of the length map. + /// The default value is GR::ArcMap. + /// + /// \warning Length values should be \e non-negative. + /// + /// \note For finding \e node-disjoint paths, this algorithm can be used + /// along with the \ref SplitNodes adaptor. +#ifdef DOXYGEN + template +#else + template < typename GR, + typename LEN = typename GR::template ArcMap, + typename TR = SuurballeDefaultTraits > +#endif + class Suurballe + { + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + typedef ConstMap ConstArcMap; + typedef typename GR::template NodeMap PredMap; + + public: + + /// The type of the digraph. + typedef typename TR::Digraph Digraph; + /// The type of the length map. + typedef typename TR::LengthMap LengthMap; + /// The type of the lengths. + typedef typename TR::Length Length; + + /// The type of the flow map. + typedef typename TR::FlowMap FlowMap; + /// The type of the potential map. + typedef typename TR::PotentialMap PotentialMap; + /// The type of the path structures. + typedef typename TR::Path Path; + /// The cross reference type used for the heap. + typedef typename TR::HeapCrossRef HeapCrossRef; + /// The heap type used for internal Dijkstra computations. + typedef typename TR::Heap Heap; + + /// The \ref SuurballeDefaultTraits "traits class" of the algorithm. + typedef TR Traits; + + private: + + // ResidualDijkstra is a special implementation of the + // Dijkstra algorithm for finding shortest paths in the + // residual network with respect to the reduced arc lengths + // and modifying the node potentials according to the + // distance of the nodes. + class ResidualDijkstra + { + private: + + const Digraph &_graph; + const LengthMap &_length; + const FlowMap &_flow; + PotentialMap &_pi; + PredMap &_pred; + Node _s; + Node _t; + + PotentialMap _dist; + std::vector _proc_nodes; + + public: + + // Constructor + ResidualDijkstra(Suurballe &srb) : + _graph(srb._graph), _length(srb._length), + _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred), + _s(srb._s), _t(srb._t), _dist(_graph) {} + + // Run the algorithm and return true if a path is found + // from the source node to the target node. + bool run(int cnt) { + return cnt == 0 ? startFirst() : start(); + } + + private: + + // Execute the algorithm for the first time (the flow and potential + // functions have to be identically zero). + bool startFirst() { + HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP); + Heap heap(heap_cross_ref); + heap.push(_s, 0); + _pred[_s] = INVALID; + _proc_nodes.clear(); + + // Process nodes + while (!heap.empty() && heap.top() != _t) { + Node u = heap.top(), v; + Length d = heap.prio(), dn; + _dist[u] = heap.prio(); + _proc_nodes.push_back(u); + heap.pop(); + + // Traverse outgoing arcs + for (OutArcIt e(_graph, u); e != INVALID; ++e) { + v = _graph.target(e); + switch(heap.state(v)) { + case Heap::PRE_HEAP: + heap.push(v, d + _length[e]); + _pred[v] = e; + break; + case Heap::IN_HEAP: + dn = d + _length[e]; + if (dn < heap[v]) { + heap.decrease(v, dn); + _pred[v] = e; + } + break; + case Heap::POST_HEAP: + break; + } + } + } + if (heap.empty()) return false; + + // Update potentials of processed nodes + Length t_dist = heap.prio(); + for (int i = 0; i < int(_proc_nodes.size()); ++i) + _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist; + return true; + } + + // Execute the algorithm. + bool start() { + HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP); + Heap heap(heap_cross_ref); + heap.push(_s, 0); + _pred[_s] = INVALID; + _proc_nodes.clear(); + + // Process nodes + while (!heap.empty() && heap.top() != _t) { + Node u = heap.top(), v; + Length d = heap.prio() + _pi[u], dn; + _dist[u] = heap.prio(); + _proc_nodes.push_back(u); + heap.pop(); + + // Traverse outgoing arcs + for (OutArcIt e(_graph, u); e != INVALID; ++e) { + if (_flow[e] == 0) { + v = _graph.target(e); + switch(heap.state(v)) { + case Heap::PRE_HEAP: + heap.push(v, d + _length[e] - _pi[v]); + _pred[v] = e; + break; + case Heap::IN_HEAP: + dn = d + _length[e] - _pi[v]; + if (dn < heap[v]) { + heap.decrease(v, dn); + _pred[v] = e; + } + break; + case Heap::POST_HEAP: + break; + } + } + } + + // Traverse incoming arcs + for (InArcIt e(_graph, u); e != INVALID; ++e) { + if (_flow[e] == 1) { + v = _graph.source(e); + switch(heap.state(v)) { + case Heap::PRE_HEAP: + heap.push(v, d - _length[e] - _pi[v]); + _pred[v] = e; + break; + case Heap::IN_HEAP: + dn = d - _length[e] - _pi[v]; + if (dn < heap[v]) { + heap.decrease(v, dn); + _pred[v] = e; + } + break; + case Heap::POST_HEAP: + break; + } + } + } + } + if (heap.empty()) return false; + + // Update potentials of processed nodes + Length t_dist = heap.prio(); + for (int i = 0; i < int(_proc_nodes.size()); ++i) + _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist; + return true; + } + + }; //class ResidualDijkstra + + public: + + /// \name Named Template Parameters + /// @{ + + template + struct SetFlowMapTraits : public Traits { + typedef T FlowMap; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c FlowMap type. + /// + /// \ref named-templ-param "Named parameter" for setting + /// \c FlowMap type. + template + struct SetFlowMap + : public Suurballe > { + typedef Suurballe > Create; + }; + + template + struct SetPotentialMapTraits : public Traits { + typedef T PotentialMap; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c PotentialMap type. + /// + /// \ref named-templ-param "Named parameter" for setting + /// \c PotentialMap type. + template + struct SetPotentialMap + : public Suurballe > { + typedef Suurballe > Create; + }; + + template + struct SetPathTraits : public Traits { + typedef T Path; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c %Path type. + /// + /// \ref named-templ-param "Named parameter" for setting \c %Path type. + /// It must conform to the \ref lemon::concepts::Path "Path" concept + /// and it must have an \c addBack() function. + template + struct SetPath + : public Suurballe > { + typedef Suurballe > Create; + }; + + template + struct SetHeapTraits : public Traits { + typedef H Heap; + typedef CR HeapCrossRef; + }; + + /// \brief \ref named-templ-param "Named parameter" for setting + /// \c Heap and \c HeapCrossRef types. + /// + /// \ref named-templ-param "Named parameter" for setting \c Heap + /// and \c HeapCrossRef types with automatic allocation. + /// They will be used for internal Dijkstra computations. + /// The heap type must conform to the \ref lemon::concepts::Heap "Heap" + /// concept and its priority type must be \c Length. + template > + struct SetHeap + : public Suurballe > { + typedef Suurballe > Create; + }; + + /// @} + + private: + + // The digraph the algorithm runs on + const Digraph &_graph; + // The length map + const LengthMap &_length; + + // Arc map of the current flow + FlowMap *_flow; + bool _local_flow; + // Node map of the current potentials + PotentialMap *_potential; + bool _local_potential; + + // The source node + Node _s; + // The target node + Node _t; + + // Container to store the found paths + std::vector _paths; + int _path_num; + + // The pred arc map + PredMap _pred; + + // Data for full init + PotentialMap *_init_dist; + PredMap *_init_pred; + bool _full_init; + + protected: + + Suurballe() {} + + public: + + /// \brief Constructor. + /// + /// Constructor. + /// + /// \param graph The digraph the algorithm runs on. + /// \param length The length (cost) values of the arcs. + Suurballe( const Digraph &graph, + const LengthMap &length ) : + _graph(graph), _length(length), _flow(0), _local_flow(false), + _potential(0), _local_potential(false), _pred(graph), + _init_dist(0), _init_pred(0) + {} + + /// Destructor. + ~Suurballe() { + if (_local_flow) delete _flow; + if (_local_potential) delete _potential; + delete _init_dist; + delete _init_pred; + } + + /// \brief Set the flow map. + /// + /// This function sets the flow map. + /// If it is not used before calling \ref run() or \ref init(), + /// an instance will be allocated automatically. The destructor + /// deallocates this automatically allocated map, of course. + /// + /// The found flow contains only 0 and 1 values, since it is the + /// union of the found arc-disjoint paths. + /// + /// \return (*this) + Suurballe& flowMap(FlowMap &map) { + if (_local_flow) { + delete _flow; + _local_flow = false; + } + _flow = ↦ + return *this; + } + + /// \brief Set the potential map. + /// + /// This function sets the potential map. + /// If it is not used before calling \ref run() or \ref init(), + /// an instance will be allocated automatically. The destructor + /// deallocates this automatically allocated map, of course. + /// + /// The node potentials provide the dual solution of the underlying + /// \ref min_cost_flow "minimum cost flow problem". + /// + /// \return (*this) + Suurballe& potentialMap(PotentialMap &map) { + if (_local_potential) { + delete _potential; + _local_potential = false; + } + _potential = ↦ + return *this; + } + + /// \name Execution Control + /// The simplest way to execute the algorithm is to call the run() + /// function.\n + /// If you need to execute the algorithm many times using the same + /// source node, then you may call fullInit() once and start() + /// for each target node.\n + /// If you only need the flow that is the union of the found + /// arc-disjoint paths, then you may call findFlow() instead of + /// start(). + + /// @{ + + /// \brief Run the algorithm. + /// + /// This function runs the algorithm. + /// + /// \param s The source node. + /// \param t The target node. + /// \param k The number of paths to be found. + /// + /// \return \c k if there are at least \c k arc-disjoint paths from + /// \c s to \c t in the digraph. Otherwise it returns the number of + /// arc-disjoint paths found. + /// + /// \note Apart from the return value, s.run(s, t, k) is + /// just a shortcut of the following code. + /// \code + /// s.init(s); + /// s.start(t, k); + /// \endcode + int run(const Node& s, const Node& t, int k = 2) { + init(s); + start(t, k); + return _path_num; + } + + /// \brief Initialize the algorithm. + /// + /// This function initializes the algorithm with the given source node. + /// + /// \param s The source node. + void init(const Node& s) { + _s = s; + + // Initialize maps + if (!_flow) { + _flow = new FlowMap(_graph); + _local_flow = true; + } + if (!_potential) { + _potential = new PotentialMap(_graph); + _local_potential = true; + } + _full_init = false; + } + + /// \brief Initialize the algorithm and perform Dijkstra. + /// + /// This function initializes the algorithm and performs a full + /// Dijkstra search from the given source node. It makes consecutive + /// executions of \ref start() "start(t, k)" faster, since they + /// have to perform %Dijkstra only k-1 times. + /// + /// This initialization is usually worth using instead of \ref init() + /// if the algorithm is executed many times using the same source node. + /// + /// \param s The source node. + void fullInit(const Node& s) { + // Initialize maps + init(s); + if (!_init_dist) { + _init_dist = new PotentialMap(_graph); + } + if (!_init_pred) { + _init_pred = new PredMap(_graph); + } + + // Run a full Dijkstra + typename Dijkstra + ::template SetStandardHeap + ::template SetDistMap + ::template SetPredMap + ::Create dijk(_graph, _length); + dijk.distMap(*_init_dist).predMap(*_init_pred); + dijk.run(s); + + _full_init = true; + } + + /// \brief Execute the algorithm. + /// + /// This function executes the algorithm. + /// + /// \param t The target node. + /// \param k The number of paths to be found. + /// + /// \return \c k if there are at least \c k arc-disjoint paths from + /// \c s to \c t in the digraph. Otherwise it returns the number of + /// arc-disjoint paths found. + /// + /// \note Apart from the return value, s.start(t, k) is + /// just a shortcut of the following code. + /// \code + /// s.findFlow(t, k); + /// s.findPaths(); + /// \endcode + int start(const Node& t, int k = 2) { + findFlow(t, k); + findPaths(); + return _path_num; + } + + /// \brief Execute the algorithm to find an optimal flow. + /// + /// This function executes the successive shortest path algorithm to + /// find a minimum cost flow, which is the union of \c k (or less) + /// arc-disjoint paths. + /// + /// \param t The target node. + /// \param k The number of paths to be found. + /// + /// \return \c k if there are at least \c k arc-disjoint paths from + /// the source node to the given node \c t in the digraph. + /// Otherwise it returns the number of arc-disjoint paths found. + /// + /// \pre \ref init() must be called before using this function. + int findFlow(const Node& t, int k = 2) { + _t = t; + ResidualDijkstra dijkstra(*this); + + // Initialization + for (ArcIt e(_graph); e != INVALID; ++e) { + (*_flow)[e] = 0; + } + if (_full_init) { + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_potential)[n] = (*_init_dist)[n]; + } + Node u = _t; + Arc e; + while ((e = (*_init_pred)[u]) != INVALID) { + (*_flow)[e] = 1; + u = _graph.source(e); + } + _path_num = 1; + } else { + for (NodeIt n(_graph); n != INVALID; ++n) { + (*_potential)[n] = 0; + } + _path_num = 0; + } + + // Find shortest paths + while (_path_num < k) { + // Run Dijkstra + if (!dijkstra.run(_path_num)) break; + ++_path_num; + + // Set the flow along the found shortest path + Node u = _t; + Arc e; + while ((e = _pred[u]) != INVALID) { + if (u == _graph.target(e)) { + (*_flow)[e] = 1; + u = _graph.source(e); + } else { + (*_flow)[e] = 0; + u = _graph.target(e); + } + } + } + return _path_num; + } + + /// \brief Compute the paths from the flow. + /// + /// This function computes arc-disjoint paths from the found minimum + /// cost flow, which is the union of them. + /// + /// \pre \ref init() and \ref findFlow() must be called before using + /// this function. + void findPaths() { + FlowMap res_flow(_graph); + for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a]; + + _paths.clear(); + _paths.resize(_path_num); + for (int i = 0; i < _path_num; ++i) { + Node n = _s; + while (n != _t) { + OutArcIt e(_graph, n); + for ( ; res_flow[e] == 0; ++e) ; + n = _graph.target(e); + _paths[i].addBack(e); + res_flow[e] = 0; + } + } + } + + /// @} + + /// \name Query Functions + /// The results of the algorithm can be obtained using these + /// functions. + /// \n The algorithm should be executed before using them. + + /// @{ + + /// \brief Return the total length of the found paths. + /// + /// This function returns the total length of the found paths, i.e. + /// the total cost of the found flow. + /// The complexity of the function is O(e). + /// + /// \pre \ref run() or \ref findFlow() must be called before using + /// this function. + Length totalLength() const { + Length c = 0; + for (ArcIt e(_graph); e != INVALID; ++e) + c += (*_flow)[e] * _length[e]; + return c; + } + + /// \brief Return the flow value on the given arc. + /// + /// This function returns the flow value on the given arc. + /// It is \c 1 if the arc is involved in one of the found arc-disjoint + /// paths, otherwise it is \c 0. + /// + /// \pre \ref run() or \ref findFlow() must be called before using + /// this function. + int flow(const Arc& arc) const { + return (*_flow)[arc]; + } + + /// \brief Return a const reference to an arc map storing the + /// found flow. + /// + /// This function returns a const reference to an arc map storing + /// the flow that is the union of the found arc-disjoint paths. + /// + /// \pre \ref run() or \ref findFlow() must be called before using + /// this function. + const FlowMap& flowMap() const { + return *_flow; + } + + /// \brief Return the potential of the given node. + /// + /// This function returns the potential of the given node. + /// The node potentials provide the dual solution of the + /// underlying \ref min_cost_flow "minimum cost flow problem". + /// + /// \pre \ref run() or \ref findFlow() must be called before using + /// this function. + Length potential(const Node& node) const { + return (*_potential)[node]; + } + + /// \brief Return a const reference to a node map storing the + /// found potentials (the dual solution). + /// + /// This function returns a const reference to a node map storing + /// the found potentials that provide the dual solution of the + /// underlying \ref min_cost_flow "minimum cost flow problem". + /// + /// \pre \ref run() or \ref findFlow() must be called before using + /// this function. + const PotentialMap& potentialMap() const { + return *_potential; + } + + /// \brief Return the number of the found paths. + /// + /// This function returns the number of the found paths. + /// + /// \pre \ref run() or \ref findFlow() must be called before using + /// this function. + int pathNum() const { + return _path_num; + } + + /// \brief Return a const reference to the specified path. + /// + /// This function returns a const reference to the specified path. + /// + /// \param i The function returns the i-th path. + /// \c i must be between \c 0 and %pathNum()-1. + /// + /// \pre \ref run() or \ref findPaths() must be called before using + /// this function. + const Path& path(int i) const { + return _paths[i]; + } + + /// @} + + }; //class Suurballe + + ///@} + +} //namespace lemon + +#endif //LEMON_SUURBALLE_H diff --git a/lemon/lemon/time_measure.h b/lemon/lemon/time_measure.h new file mode 100644 index 0000000..d8ca90c --- /dev/null +++ b/lemon/lemon/time_measure.h @@ -0,0 +1,552 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_TIME_MEASURE_H +#define LEMON_TIME_MEASURE_H + +///\ingroup timecount +///\file +///\brief Tools for measuring cpu usage + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif + +#include +#include +#include + +namespace lemon { + + /// \addtogroup timecount + /// @{ + + /// A class to store (cpu)time instances. + + /// This class stores five time values. + /// - a real time + /// - a user cpu time + /// - a system cpu time + /// - a user cpu time of children + /// - a system cpu time of children + /// + /// TimeStamp's can be added to or substracted from each other and + /// they can be pushed to a stream. + /// + /// In most cases, perhaps the \ref Timer or the \ref TimeReport + /// class is what you want to use instead. + + class TimeStamp + { + double utime; + double stime; + double cutime; + double cstime; + double rtime; + + void _reset() { + utime = stime = cutime = cstime = rtime = 0; + } + + public: + + ///Read the current time values of the process + void stamp() + { +#ifndef WIN32 + timeval tv; + gettimeofday(&tv, 0); + rtime=tv.tv_sec+double(tv.tv_usec)/1e6; + + tms ts; + double tck=sysconf(_SC_CLK_TCK); + times(&ts); + utime=ts.tms_utime/tck; + stime=ts.tms_stime/tck; + cutime=ts.tms_cutime/tck; + cstime=ts.tms_cstime/tck; +#else + bits::getWinProcTimes(rtime, utime, stime, cutime, cstime); +#endif + } + + /// Constructor initializing with zero + TimeStamp() + { _reset(); } + ///Constructor initializing with the current time values of the process + TimeStamp(void *) { stamp();} + + ///Set every time value to zero + TimeStamp &reset() {_reset();return *this;} + + ///\e + TimeStamp &operator+=(const TimeStamp &b) + { + utime+=b.utime; + stime+=b.stime; + cutime+=b.cutime; + cstime+=b.cstime; + rtime+=b.rtime; + return *this; + } + ///\e + TimeStamp operator+(const TimeStamp &b) const + { + TimeStamp t(*this); + return t+=b; + } + ///\e + TimeStamp &operator-=(const TimeStamp &b) + { + utime-=b.utime; + stime-=b.stime; + cutime-=b.cutime; + cstime-=b.cstime; + rtime-=b.rtime; + return *this; + } + ///\e + TimeStamp operator-(const TimeStamp &b) const + { + TimeStamp t(*this); + return t-=b; + } + ///\e + TimeStamp &operator*=(double b) + { + utime*=b; + stime*=b; + cutime*=b; + cstime*=b; + rtime*=b; + return *this; + } + ///\e + TimeStamp operator*(double b) const + { + TimeStamp t(*this); + return t*=b; + } + friend TimeStamp operator*(double b,const TimeStamp &t); + ///\e + TimeStamp &operator/=(double b) + { + utime/=b; + stime/=b; + cutime/=b; + cstime/=b; + rtime/=b; + return *this; + } + ///\e + TimeStamp operator/(double b) const + { + TimeStamp t(*this); + return t/=b; + } + ///The time ellapsed since the last call of stamp() + TimeStamp ellapsed() const + { + TimeStamp t(NULL); + return t-*this; + } + + friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t); + + ///Gives back the user time of the process + double userTime() const + { + return utime; + } + ///Gives back the system time of the process + double systemTime() const + { + return stime; + } + ///Gives back the user time of the process' children + + ///\note On WIN32 platform this value is not calculated. + /// + double cUserTime() const + { + return cutime; + } + ///Gives back the user time of the process' children + + ///\note On WIN32 platform this value is not calculated. + /// + double cSystemTime() const + { + return cstime; + } + ///Gives back the real time + double realTime() const {return rtime;} + }; + + inline TimeStamp operator*(double b,const TimeStamp &t) + { + return t*b; + } + + ///Prints the time counters + + ///Prints the time counters in the following form: + /// + /// u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs + /// + /// where the values are the + /// \li \c u: user cpu time, + /// \li \c s: system cpu time, + /// \li \c cu: user cpu time of children, + /// \li \c cs: system cpu time of children, + /// \li \c real: real time. + /// \relates TimeStamp + /// \note On WIN32 platform the cummulative values are not + /// calculated. + inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t) + { + os << "u: " << t.userTime() << + "s, s: " << t.systemTime() << + "s, cu: " << t.cUserTime() << + "s, cs: " << t.cSystemTime() << + "s, real: " << t.realTime() << "s"; + return os; + } + + ///Class for measuring the cpu time and real time usage of the process + + ///Class for measuring the cpu time and real time usage of the process. + ///It is quite easy-to-use, here is a short example. + ///\code + /// #include + /// #include + /// + /// int main() + /// { + /// + /// ... + /// + /// Timer t; + /// doSomething(); + /// std::cout << t << '\n'; + /// t.restart(); + /// doSomethingElse(); + /// std::cout << t << '\n'; + /// + /// ... + /// + /// } + ///\endcode + /// + ///The \ref Timer can also be \ref stop() "stopped" and + ///\ref start() "started" again, so it is possible to compute collected + ///running times. + /// + ///\warning Depending on the operation system and its actual configuration + ///the time counters have a certain (10ms on a typical Linux system) + ///granularity. + ///Therefore this tool is not appropriate to measure very short times. + ///Also, if you start and stop the timer very frequently, it could lead to + ///distorted results. + /// + ///\note If you want to measure the running time of the execution of a certain + ///function, consider the usage of \ref TimeReport instead. + /// + ///\sa TimeReport + class Timer + { + int _running; //Timer is running iff _running>0; (_running>=0 always holds) + TimeStamp start_time; //This is the relativ start-time if the timer + //is _running, the collected _running time otherwise. + + void _reset() {if(_running) start_time.stamp(); else start_time.reset();} + + public: + ///Constructor. + + ///\param run indicates whether or not the timer starts immediately. + /// + Timer(bool run=true) :_running(run) {_reset();} + + ///\name Control the State of the Timer + ///Basically a Timer can be either running or stopped, + ///but it provides a bit finer control on the execution. + ///The \ref lemon::Timer "Timer" also counts the number of + ///\ref lemon::Timer::start() "start()" executions, and it stops + ///only after the same amount (or more) \ref lemon::Timer::stop() + ///"stop()"s. This can be useful e.g. to compute the running time + ///of recursive functions. + + ///@{ + + ///Reset and stop the time counters + + ///This function resets and stops the time counters + ///\sa restart() + void reset() + { + _running=0; + _reset(); + } + + ///Start the time counters + + ///This function starts the time counters. + /// + ///If the timer is started more than ones, it will remain running + ///until the same amount of \ref stop() is called. + ///\sa stop() + void start() + { + if(_running) _running++; + else { + _running=1; + TimeStamp t; + t.stamp(); + start_time=t-start_time; + } + } + + + ///Stop the time counters + + ///This function stops the time counters. If start() was executed more than + ///once, then the same number of stop() execution is necessary the really + ///stop the timer. + /// + ///\sa halt() + ///\sa start() + ///\sa restart() + ///\sa reset() + + void stop() + { + if(_running && !--_running) { + TimeStamp t; + t.stamp(); + start_time=t-start_time; + } + } + + ///Halt (i.e stop immediately) the time counters + + ///This function stops immediately the time counters, i.e. t.halt() + ///is a faster + ///equivalent of the following. + ///\code + /// while(t.running()) t.stop() + ///\endcode + /// + /// + ///\sa stop() + ///\sa restart() + ///\sa reset() + + void halt() + { + if(_running) { + _running=0; + TimeStamp t; + t.stamp(); + start_time=t-start_time; + } + } + + ///Returns the running state of the timer + + ///This function returns the number of stop() exections that is + ///necessary to really stop the timer. + ///For example, the timer + ///is running if and only if the return value is \c true + ///(i.e. greater than + ///zero). + int running() { return _running; } + + + ///Restart the time counters + + ///This function is a shorthand for + ///a reset() and a start() calls. + /// + void restart() + { + reset(); + start(); + } + + ///@} + + ///\name Query Functions for the Ellapsed Time + + ///@{ + + ///Gives back the ellapsed user time of the process + double userTime() const + { + return operator TimeStamp().userTime(); + } + ///Gives back the ellapsed system time of the process + double systemTime() const + { + return operator TimeStamp().systemTime(); + } + ///Gives back the ellapsed user time of the process' children + + ///\note On WIN32 platform this value is not calculated. + /// + double cUserTime() const + { + return operator TimeStamp().cUserTime(); + } + ///Gives back the ellapsed user time of the process' children + + ///\note On WIN32 platform this value is not calculated. + /// + double cSystemTime() const + { + return operator TimeStamp().cSystemTime(); + } + ///Gives back the ellapsed real time + double realTime() const + { + return operator TimeStamp().realTime(); + } + ///Computes the ellapsed time + + ///This conversion computes the ellapsed time, therefore you can print + ///the ellapsed time like this. + ///\code + /// Timer t; + /// doSomething(); + /// std::cout << t << '\n'; + ///\endcode + operator TimeStamp () const + { + TimeStamp t; + t.stamp(); + return _running?t-start_time:start_time; + } + + + ///@} + }; + + ///Same as Timer but prints a report on destruction. + + ///Same as \ref Timer but prints a report on destruction. + ///This example shows its usage. + ///\code + /// void myAlg(ListGraph &g,int n) + /// { + /// TimeReport tr("Running time of myAlg: "); + /// ... //Here comes the algorithm + /// } + ///\endcode + /// + ///\sa Timer + ///\sa NoTimeReport + class TimeReport : public Timer + { + std::string _title; + std::ostream &_os; + public: + ///Constructor + + ///Constructor. + ///\param title This text will be printed before the ellapsed time. + ///\param os The stream to print the report to. + ///\param run Sets whether the timer should start immediately. + TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) + : Timer(run), _title(title), _os(os){} + ///Destructor that prints the ellapsed time + ~TimeReport() + { + _os << _title << *this << std::endl; + } + }; + + ///'Do nothing' version of TimeReport + + ///\sa TimeReport + /// + class NoTimeReport + { + public: + ///\e + NoTimeReport(std::string,std::ostream &,bool) {} + ///\e + NoTimeReport(std::string,std::ostream &) {} + ///\e + NoTimeReport(std::string) {} + ///\e Do nothing. + ~NoTimeReport() {} + + operator TimeStamp () const { return TimeStamp(); } + void reset() {} + void start() {} + void stop() {} + void halt() {} + int running() { return 0; } + void restart() {} + double userTime() const { return 0; } + double systemTime() const { return 0; } + double cUserTime() const { return 0; } + double cSystemTime() const { return 0; } + double realTime() const { return 0; } + }; + + ///Tool to measure the running time more exactly. + + ///This function calls \c f several times and returns the average + ///running time. The number of the executions will be choosen in such a way + ///that the full real running time will be roughly between \c min_time + ///and 2*min_time. + ///\param f the function object to be measured. + ///\param min_time the minimum total running time. + ///\retval num if it is not \c NULL, then the actual + /// number of execution of \c f will be written into *num. + ///\retval full_time if it is not \c NULL, then the actual + /// total running time will be written into *full_time. + ///\return The average running time of \c f. + + template + TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL, + TimeStamp *full_time=NULL) + { + TimeStamp full; + unsigned int total=0; + Timer t; + for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) { + for(;total may offer additional tuning parameters. + /// + ///\sa Tolerance + ///\sa Tolerance + ///\sa Tolerance + + template + class Tolerance + { + public: + typedef T Value; + + ///\name Comparisons + ///The concept is that these bool functions return \c true only if + ///the related comparisons hold even if some numerical error appeared + ///during the computations. + + ///@{ + + ///Returns \c true if \c a is \e surely strictly less than \c b + static bool less(Value a,Value b) {return a(0) < a;} + ///Returns \c true if \c a is \e surely negative + static bool negative(Value a) {return a < static_cast(0);} + ///Returns \c true if \c a is \e surely non-zero + static bool nonZero(Value a) {return a != static_cast(0);} + + ///@} + + ///Returns the zero value. + static Value zero() {return static_cast(0);} + + // static bool finite(Value a) {} + // static Value big() {} + // static Value negativeBig() {} + }; + + + ///Float specialization of Tolerance. + + ///Float specialization of Tolerance. + ///\sa Tolerance + ///\relates Tolerance + template<> + class Tolerance + { + static float def_epsilon; + float _epsilon; + public: + ///\e + typedef float Value; + + ///Constructor setting the epsilon tolerance to the default value. + Tolerance() : _epsilon(def_epsilon) {} + ///Constructor setting the epsilon tolerance to the given value. + Tolerance(float e) : _epsilon(e) {} + + ///Returns the epsilon value. + Value epsilon() const {return _epsilon;} + ///Sets the epsilon value. + void epsilon(Value e) {_epsilon=e;} + + ///Returns the default epsilon value. + static Value defaultEpsilon() {return def_epsilon;} + ///Sets the default epsilon value. + static void defaultEpsilon(Value e) {def_epsilon=e;} + + ///\name Comparisons + ///See \ref lemon::Tolerance "Tolerance" for more details. + + ///@{ + + ///Returns \c true if \c a is \e surely strictly less than \c b + bool less(Value a,Value b) const {return a+_epsilona; } + ///Returns \c true if \c a is \e surely non-zero + bool nonZero(Value a) const { return positive(a)||negative(a); } + + ///@} + + ///Returns zero + static Value zero() {return 0;} + }; + + ///Double specialization of Tolerance. + + ///Double specialization of Tolerance. + ///\sa Tolerance + ///\relates Tolerance + template<> + class Tolerance + { + static double def_epsilon; + double _epsilon; + public: + ///\e + typedef double Value; + + ///Constructor setting the epsilon tolerance to the default value. + Tolerance() : _epsilon(def_epsilon) {} + ///Constructor setting the epsilon tolerance to the given value. + Tolerance(double e) : _epsilon(e) {} + + ///Returns the epsilon value. + Value epsilon() const {return _epsilon;} + ///Sets the epsilon value. + void epsilon(Value e) {_epsilon=e;} + + ///Returns the default epsilon value. + static Value defaultEpsilon() {return def_epsilon;} + ///Sets the default epsilon value. + static void defaultEpsilon(Value e) {def_epsilon=e;} + + ///\name Comparisons + ///See \ref lemon::Tolerance "Tolerance" for more details. + + ///@{ + + ///Returns \c true if \c a is \e surely strictly less than \c b + bool less(Value a,Value b) const {return a+_epsilona; } + ///Returns \c true if \c a is \e surely non-zero + bool nonZero(Value a) const { return positive(a)||negative(a); } + + ///@} + + ///Returns zero + static Value zero() {return 0;} + }; + + ///Long double specialization of Tolerance. + + ///Long double specialization of Tolerance. + ///\sa Tolerance + ///\relates Tolerance + template<> + class Tolerance + { + static long double def_epsilon; + long double _epsilon; + public: + ///\e + typedef long double Value; + + ///Constructor setting the epsilon tolerance to the default value. + Tolerance() : _epsilon(def_epsilon) {} + ///Constructor setting the epsilon tolerance to the given value. + Tolerance(long double e) : _epsilon(e) {} + + ///Returns the epsilon value. + Value epsilon() const {return _epsilon;} + ///Sets the epsilon value. + void epsilon(Value e) {_epsilon=e;} + + ///Returns the default epsilon value. + static Value defaultEpsilon() {return def_epsilon;} + ///Sets the default epsilon value. + static void defaultEpsilon(Value e) {def_epsilon=e;} + + ///\name Comparisons + ///See \ref lemon::Tolerance "Tolerance" for more details. + + ///@{ + + ///Returns \c true if \c a is \e surely strictly less than \c b + bool less(Value a,Value b) const {return a+_epsilona; } + ///Returns \c true if \c a is \e surely non-zero + bool nonZero(Value a) const { return positive(a)||negative(a); } + + ///@} + + ///Returns zero + static Value zero() {return 0;} + }; + + /// @} + +} //namespace lemon + +#endif //LEMON_TOLERANCE_H diff --git a/lemon/lemon/unionfind.h b/lemon/lemon/unionfind.h new file mode 100644 index 0000000..adacbc0 --- /dev/null +++ b/lemon/lemon/unionfind.h @@ -0,0 +1,1824 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_UNION_FIND_H +#define LEMON_UNION_FIND_H + +//!\ingroup auxdat +//!\file +//!\brief Union-Find data structures. +//! + +#include +#include +#include +#include +#include + +#include + +namespace lemon { + + /// \ingroup auxdat + /// + /// \brief A \e Union-Find data structure implementation + /// + /// The class implements the \e Union-Find data structure. + /// The union operation uses rank heuristic, while + /// the find operation uses path compression. + /// This is a very simple but efficient implementation, providing + /// only four methods: join (union), find, insert and size. + /// For more features, see the \ref UnionFindEnum class. + /// + /// It is primarily used in Kruskal algorithm for finding minimal + /// cost spanning tree in a graph. + /// \sa kruskal() + /// + /// \pre You need to add all the elements by the \ref insert() + /// method. + template + class UnionFind { + public: + + ///\e + typedef IM ItemIntMap; + ///\e + typedef typename ItemIntMap::Key Item; + + private: + // If the items vector stores negative value for an item then + // that item is root item and it has -items[it] component size. + // Else the items[it] contains the index of the parent. + std::vector items; + ItemIntMap& index; + + bool rep(int idx) const { + return items[idx] < 0; + } + + int repIndex(int idx) const { + int k = idx; + while (!rep(k)) { + k = items[k] ; + } + while (idx != k) { + int next = items[idx]; + const_cast(items[idx]) = k; + idx = next; + } + return k; + } + + public: + + /// \brief Constructor + /// + /// Constructor of the UnionFind class. You should give an item to + /// integer map which will be used from the data structure. If you + /// modify directly this map that may cause segmentation fault, + /// invalid data structure, or infinite loop when you use again + /// the union-find. + UnionFind(ItemIntMap& m) : index(m) {} + + /// \brief Returns the index of the element's component. + /// + /// The method returns the index of the element's component. + /// This is an integer between zero and the number of inserted elements. + /// + int find(const Item& a) { + return repIndex(index[a]); + } + + /// \brief Clears the union-find data structure + /// + /// Erase each item from the data structure. + void clear() { + items.clear(); + } + + /// \brief Inserts a new element into the structure. + /// + /// This method inserts a new element into the data structure. + /// + /// The method returns the index of the new component. + int insert(const Item& a) { + int n = items.size(); + items.push_back(-1); + index.set(a,n); + return n; + } + + /// \brief Joining the components of element \e a and element \e b. + /// + /// This is the \e union operation of the Union-Find structure. + /// Joins the component of element \e a and component of + /// element \e b. If \e a and \e b are in the same component then + /// it returns false otherwise it returns true. + bool join(const Item& a, const Item& b) { + int ka = repIndex(index[a]); + int kb = repIndex(index[b]); + + if ( ka == kb ) + return false; + + if (items[ka] < items[kb]) { + items[ka] += items[kb]; + items[kb] = ka; + } else { + items[kb] += items[ka]; + items[ka] = kb; + } + return true; + } + + /// \brief Returns the size of the component of element \e a. + /// + /// Returns the size of the component of element \e a. + int size(const Item& a) { + int k = repIndex(index[a]); + return - items[k]; + } + + }; + + /// \ingroup auxdat + /// + /// \brief A \e Union-Find data structure implementation which + /// is able to enumerate the components. + /// + /// The class implements a \e Union-Find data structure + /// which is able to enumerate the components and the items in + /// a component. If you don't need this feature then perhaps it's + /// better to use the \ref UnionFind class which is more efficient. + /// + /// The union operation uses rank heuristic, while + /// the find operation uses path compression. + /// + /// \pre You need to add all the elements by the \ref insert() + /// method. + /// + template + class UnionFindEnum { + public: + + ///\e + typedef IM ItemIntMap; + ///\e + typedef typename ItemIntMap::Key Item; + + private: + + ItemIntMap& index; + + // If the parent stores negative value for an item then that item + // is root item and it has ~(items[it].parent) component id. Else + // the items[it].parent contains the index of the parent. + // + // The \c next and \c prev provides the double-linked + // cyclic list of one component's items. + struct ItemT { + int parent; + Item item; + + int next, prev; + }; + + std::vector items; + int firstFreeItem; + + struct ClassT { + int size; + int firstItem; + int next, prev; + }; + + std::vector classes; + int firstClass, firstFreeClass; + + int newClass() { + if (firstFreeClass == -1) { + int cdx = classes.size(); + classes.push_back(ClassT()); + return cdx; + } else { + int cdx = firstFreeClass; + firstFreeClass = classes[firstFreeClass].next; + return cdx; + } + } + + int newItem() { + if (firstFreeItem == -1) { + int idx = items.size(); + items.push_back(ItemT()); + return idx; + } else { + int idx = firstFreeItem; + firstFreeItem = items[firstFreeItem].next; + return idx; + } + } + + + bool rep(int idx) const { + return items[idx].parent < 0; + } + + int repIndex(int idx) const { + int k = idx; + while (!rep(k)) { + k = items[k].parent; + } + while (idx != k) { + int next = items[idx].parent; + const_cast(items[idx].parent) = k; + idx = next; + } + return k; + } + + int classIndex(int idx) const { + return ~(items[repIndex(idx)].parent); + } + + void singletonItem(int idx) { + items[idx].next = idx; + items[idx].prev = idx; + } + + void laceItem(int idx, int rdx) { + items[idx].prev = rdx; + items[idx].next = items[rdx].next; + items[items[rdx].next].prev = idx; + items[rdx].next = idx; + } + + void unlaceItem(int idx) { + items[items[idx].prev].next = items[idx].next; + items[items[idx].next].prev = items[idx].prev; + + items[idx].next = firstFreeItem; + firstFreeItem = idx; + } + + void spliceItems(int ak, int bk) { + items[items[ak].prev].next = bk; + items[items[bk].prev].next = ak; + int tmp = items[ak].prev; + items[ak].prev = items[bk].prev; + items[bk].prev = tmp; + + } + + void laceClass(int cls) { + if (firstClass != -1) { + classes[firstClass].prev = cls; + } + classes[cls].next = firstClass; + classes[cls].prev = -1; + firstClass = cls; + } + + void unlaceClass(int cls) { + if (classes[cls].prev != -1) { + classes[classes[cls].prev].next = classes[cls].next; + } else { + firstClass = classes[cls].next; + } + if (classes[cls].next != -1) { + classes[classes[cls].next].prev = classes[cls].prev; + } + + classes[cls].next = firstFreeClass; + firstFreeClass = cls; + } + + public: + + UnionFindEnum(ItemIntMap& _index) + : index(_index), items(), firstFreeItem(-1), + firstClass(-1), firstFreeClass(-1) {} + + /// \brief Inserts the given element into a new component. + /// + /// This method creates a new component consisting only of the + /// given element. + /// + int insert(const Item& item) { + int idx = newItem(); + + index.set(item, idx); + + singletonItem(idx); + items[idx].item = item; + + int cdx = newClass(); + + items[idx].parent = ~cdx; + + laceClass(cdx); + classes[cdx].size = 1; + classes[cdx].firstItem = idx; + + firstClass = cdx; + + return cdx; + } + + /// \brief Inserts the given element into the component of the others. + /// + /// This methods inserts the element \e a into the component of the + /// element \e comp. + void insert(const Item& item, int cls) { + int rdx = classes[cls].firstItem; + int idx = newItem(); + + index.set(item, idx); + + laceItem(idx, rdx); + + items[idx].item = item; + items[idx].parent = rdx; + + ++classes[~(items[rdx].parent)].size; + } + + /// \brief Clears the union-find data structure + /// + /// Erase each item from the data structure. + void clear() { + items.clear(); + firstClass = -1; + firstFreeItem = -1; + } + + /// \brief Finds the component of the given element. + /// + /// The method returns the component id of the given element. + int find(const Item &item) const { + return ~(items[repIndex(index[item])].parent); + } + + /// \brief Joining the component of element \e a and element \e b. + /// + /// This is the \e union operation of the Union-Find structure. + /// Joins the component of element \e a and component of + /// element \e b. If \e a and \e b are in the same component then + /// returns -1 else returns the remaining class. + int join(const Item& a, const Item& b) { + + int ak = repIndex(index[a]); + int bk = repIndex(index[b]); + + if (ak == bk) { + return -1; + } + + int acx = ~(items[ak].parent); + int bcx = ~(items[bk].parent); + + int rcx; + + if (classes[acx].size > classes[bcx].size) { + classes[acx].size += classes[bcx].size; + items[bk].parent = ak; + unlaceClass(bcx); + rcx = acx; + } else { + classes[bcx].size += classes[acx].size; + items[ak].parent = bk; + unlaceClass(acx); + rcx = bcx; + } + spliceItems(ak, bk); + + return rcx; + } + + /// \brief Returns the size of the class. + /// + /// Returns the size of the class. + int size(int cls) const { + return classes[cls].size; + } + + /// \brief Splits up the component. + /// + /// Splitting the component into singleton components (component + /// of size one). + void split(int cls) { + int fdx = classes[cls].firstItem; + int idx = items[fdx].next; + while (idx != fdx) { + int next = items[idx].next; + + singletonItem(idx); + + int cdx = newClass(); + items[idx].parent = ~cdx; + + laceClass(cdx); + classes[cdx].size = 1; + classes[cdx].firstItem = idx; + + idx = next; + } + + items[idx].prev = idx; + items[idx].next = idx; + + classes[~(items[idx].parent)].size = 1; + + } + + /// \brief Removes the given element from the structure. + /// + /// Removes the element from its component and if the component becomes + /// empty then removes that component from the component list. + /// + /// \warning It is an error to remove an element which is not in + /// the structure. + /// \warning This running time of this operation is proportional to the + /// number of the items in this class. + void erase(const Item& item) { + int idx = index[item]; + int fdx = items[idx].next; + + int cdx = classIndex(idx); + if (idx == fdx) { + unlaceClass(cdx); + items[idx].next = firstFreeItem; + firstFreeItem = idx; + return; + } else { + classes[cdx].firstItem = fdx; + --classes[cdx].size; + items[fdx].parent = ~cdx; + + unlaceItem(idx); + idx = items[fdx].next; + while (idx != fdx) { + items[idx].parent = fdx; + idx = items[idx].next; + } + + } + + } + + /// \brief Gives back a representant item of the component. + /// + /// Gives back a representant item of the component. + Item item(int cls) const { + return items[classes[cls].firstItem].item; + } + + /// \brief Removes the component of the given element from the structure. + /// + /// Removes the component of the given element from the structure. + /// + /// \warning It is an error to give an element which is not in the + /// structure. + void eraseClass(int cls) { + int fdx = classes[cls].firstItem; + unlaceClass(cls); + items[items[fdx].prev].next = firstFreeItem; + firstFreeItem = fdx; + } + + /// \brief LEMON style iterator for the representant items. + /// + /// ClassIt is a lemon style iterator for the components. It iterates + /// on the ids of the classes. + class ClassIt { + public: + /// \brief Constructor of the iterator + /// + /// Constructor of the iterator + ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) { + cdx = unionFind->firstClass; + } + + /// \brief Constructor to get invalid iterator + /// + /// Constructor to get invalid iterator + ClassIt(Invalid) : unionFind(0), cdx(-1) {} + + /// \brief Increment operator + /// + /// It steps to the next representant item. + ClassIt& operator++() { + cdx = unionFind->classes[cdx].next; + return *this; + } + + /// \brief Conversion operator + /// + /// It converts the iterator to the current representant item. + operator int() const { + return cdx; + } + + /// \brief Equality operator + /// + /// Equality operator + bool operator==(const ClassIt& i) { + return i.cdx == cdx; + } + + /// \brief Inequality operator + /// + /// Inequality operator + bool operator!=(const ClassIt& i) { + return i.cdx != cdx; + } + + private: + const UnionFindEnum* unionFind; + int cdx; + }; + + /// \brief LEMON style iterator for the items of a component. + /// + /// ClassIt is a lemon style iterator for the components. It iterates + /// on the items of a class. By example if you want to iterate on + /// each items of each classes then you may write the next code. + ///\code + /// for (ClassIt cit(ufe); cit != INVALID; ++cit) { + /// std::cout << "Class: "; + /// for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) { + /// std::cout << toString(iit) << ' ' << std::endl; + /// } + /// std::cout << std::endl; + /// } + ///\endcode + class ItemIt { + public: + /// \brief Constructor of the iterator + /// + /// Constructor of the iterator. The iterator iterates + /// on the class of the \c item. + ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) { + fdx = idx = unionFind->classes[cls].firstItem; + } + + /// \brief Constructor to get invalid iterator + /// + /// Constructor to get invalid iterator + ItemIt(Invalid) : unionFind(0), idx(-1) {} + + /// \brief Increment operator + /// + /// It steps to the next item in the class. + ItemIt& operator++() { + idx = unionFind->items[idx].next; + if (idx == fdx) idx = -1; + return *this; + } + + /// \brief Conversion operator + /// + /// It converts the iterator to the current item. + operator const Item&() const { + return unionFind->items[idx].item; + } + + /// \brief Equality operator + /// + /// Equality operator + bool operator==(const ItemIt& i) { + return i.idx == idx; + } + + /// \brief Inequality operator + /// + /// Inequality operator + bool operator!=(const ItemIt& i) { + return i.idx != idx; + } + + private: + const UnionFindEnum* unionFind; + int idx, fdx; + }; + + }; + + /// \ingroup auxdat + /// + /// \brief A \e Extend-Find data structure implementation which + /// is able to enumerate the components. + /// + /// The class implements an \e Extend-Find data structure which is + /// able to enumerate the components and the items in a + /// component. The data structure is a simplification of the + /// Union-Find structure, and it does not allow to merge two components. + /// + /// \pre You need to add all the elements by the \ref insert() + /// method. + template + class ExtendFindEnum { + public: + + ///\e + typedef IM ItemIntMap; + ///\e + typedef typename ItemIntMap::Key Item; + + private: + + ItemIntMap& index; + + struct ItemT { + int cls; + Item item; + int next, prev; + }; + + std::vector items; + int firstFreeItem; + + struct ClassT { + int firstItem; + int next, prev; + }; + + std::vector classes; + + int firstClass, firstFreeClass; + + int newClass() { + if (firstFreeClass != -1) { + int cdx = firstFreeClass; + firstFreeClass = classes[cdx].next; + return cdx; + } else { + classes.push_back(ClassT()); + return classes.size() - 1; + } + } + + int newItem() { + if (firstFreeItem != -1) { + int idx = firstFreeItem; + firstFreeItem = items[idx].next; + return idx; + } else { + items.push_back(ItemT()); + return items.size() - 1; + } + } + + public: + + /// \brief Constructor + ExtendFindEnum(ItemIntMap& _index) + : index(_index), items(), firstFreeItem(-1), + classes(), firstClass(-1), firstFreeClass(-1) {} + + /// \brief Inserts the given element into a new component. + /// + /// This method creates a new component consisting only of the + /// given element. + int insert(const Item& item) { + int cdx = newClass(); + classes[cdx].prev = -1; + classes[cdx].next = firstClass; + if (firstClass != -1) { + classes[firstClass].prev = cdx; + } + firstClass = cdx; + + int idx = newItem(); + items[idx].item = item; + items[idx].cls = cdx; + items[idx].prev = idx; + items[idx].next = idx; + + classes[cdx].firstItem = idx; + + index.set(item, idx); + + return cdx; + } + + /// \brief Inserts the given element into the given component. + /// + /// This methods inserts the element \e item a into the \e cls class. + void insert(const Item& item, int cls) { + int idx = newItem(); + int rdx = classes[cls].firstItem; + items[idx].item = item; + items[idx].cls = cls; + + items[idx].prev = rdx; + items[idx].next = items[rdx].next; + items[items[rdx].next].prev = idx; + items[rdx].next = idx; + + index.set(item, idx); + } + + /// \brief Clears the union-find data structure + /// + /// Erase each item from the data structure. + void clear() { + items.clear(); + classes.clear(); + firstClass = firstFreeClass = firstFreeItem = -1; + } + + /// \brief Gives back the class of the \e item. + /// + /// Gives back the class of the \e item. + int find(const Item &item) const { + return items[index[item]].cls; + } + + /// \brief Gives back a representant item of the component. + /// + /// Gives back a representant item of the component. + Item item(int cls) const { + return items[classes[cls].firstItem].item; + } + + /// \brief Removes the given element from the structure. + /// + /// Removes the element from its component and if the component becomes + /// empty then removes that component from the component list. + /// + /// \warning It is an error to remove an element which is not in + /// the structure. + void erase(const Item &item) { + int idx = index[item]; + int cdx = items[idx].cls; + + if (idx == items[idx].next) { + if (classes[cdx].prev != -1) { + classes[classes[cdx].prev].next = classes[cdx].next; + } else { + firstClass = classes[cdx].next; + } + if (classes[cdx].next != -1) { + classes[classes[cdx].next].prev = classes[cdx].prev; + } + classes[cdx].next = firstFreeClass; + firstFreeClass = cdx; + } else { + classes[cdx].firstItem = items[idx].next; + items[items[idx].next].prev = items[idx].prev; + items[items[idx].prev].next = items[idx].next; + } + items[idx].next = firstFreeItem; + firstFreeItem = idx; + + } + + + /// \brief Removes the component of the given element from the structure. + /// + /// Removes the component of the given element from the structure. + /// + /// \warning It is an error to give an element which is not in the + /// structure. + void eraseClass(int cdx) { + int idx = classes[cdx].firstItem; + items[items[idx].prev].next = firstFreeItem; + firstFreeItem = idx; + + if (classes[cdx].prev != -1) { + classes[classes[cdx].prev].next = classes[cdx].next; + } else { + firstClass = classes[cdx].next; + } + if (classes[cdx].next != -1) { + classes[classes[cdx].next].prev = classes[cdx].prev; + } + classes[cdx].next = firstFreeClass; + firstFreeClass = cdx; + } + + /// \brief LEMON style iterator for the classes. + /// + /// ClassIt is a lemon style iterator for the components. It iterates + /// on the ids of classes. + class ClassIt { + public: + /// \brief Constructor of the iterator + /// + /// Constructor of the iterator + ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) { + cdx = extendFind->firstClass; + } + + /// \brief Constructor to get invalid iterator + /// + /// Constructor to get invalid iterator + ClassIt(Invalid) : extendFind(0), cdx(-1) {} + + /// \brief Increment operator + /// + /// It steps to the next representant item. + ClassIt& operator++() { + cdx = extendFind->classes[cdx].next; + return *this; + } + + /// \brief Conversion operator + /// + /// It converts the iterator to the current class id. + operator int() const { + return cdx; + } + + /// \brief Equality operator + /// + /// Equality operator + bool operator==(const ClassIt& i) { + return i.cdx == cdx; + } + + /// \brief Inequality operator + /// + /// Inequality operator + bool operator!=(const ClassIt& i) { + return i.cdx != cdx; + } + + private: + const ExtendFindEnum* extendFind; + int cdx; + }; + + /// \brief LEMON style iterator for the items of a component. + /// + /// ClassIt is a lemon style iterator for the components. It iterates + /// on the items of a class. By example if you want to iterate on + /// each items of each classes then you may write the next code. + ///\code + /// for (ClassIt cit(ufe); cit != INVALID; ++cit) { + /// std::cout << "Class: "; + /// for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) { + /// std::cout << toString(iit) << ' ' << std::endl; + /// } + /// std::cout << std::endl; + /// } + ///\endcode + class ItemIt { + public: + /// \brief Constructor of the iterator + /// + /// Constructor of the iterator. The iterator iterates + /// on the class of the \c item. + ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) { + fdx = idx = extendFind->classes[cls].firstItem; + } + + /// \brief Constructor to get invalid iterator + /// + /// Constructor to get invalid iterator + ItemIt(Invalid) : extendFind(0), idx(-1) {} + + /// \brief Increment operator + /// + /// It steps to the next item in the class. + ItemIt& operator++() { + idx = extendFind->items[idx].next; + if (fdx == idx) idx = -1; + return *this; + } + + /// \brief Conversion operator + /// + /// It converts the iterator to the current item. + operator const Item&() const { + return extendFind->items[idx].item; + } + + /// \brief Equality operator + /// + /// Equality operator + bool operator==(const ItemIt& i) { + return i.idx == idx; + } + + /// \brief Inequality operator + /// + /// Inequality operator + bool operator!=(const ItemIt& i) { + return i.idx != idx; + } + + private: + const ExtendFindEnum* extendFind; + int idx, fdx; + }; + + }; + + /// \ingroup auxdat + /// + /// \brief A \e Union-Find data structure implementation which + /// is able to store a priority for each item and retrieve the minimum of + /// each class. + /// + /// A \e Union-Find data structure implementation which is able to + /// store a priority for each item and retrieve the minimum of each + /// class. In addition, it supports the joining and splitting the + /// components. If you don't need this feature then you makes + /// better to use the \ref UnionFind class which is more efficient. + /// + /// The union-find data strcuture based on a (2, 16)-tree with a + /// tournament minimum selection on the internal nodes. The insert + /// operation takes O(1), the find, set, decrease and increase takes + /// O(log(n)), where n is the number of nodes in the current + /// component. The complexity of join and split is O(log(n)*k), + /// where n is the sum of the number of the nodes and k is the + /// number of joined components or the number of the components + /// after the split. + /// + /// \pre You need to add all the elements by the \ref insert() + /// method. + template > + class HeapUnionFind { + public: + + ///\e + typedef V Value; + ///\e + typedef typename IM::Key Item; + ///\e + typedef IM ItemIntMap; + ///\e + typedef Comp Compare; + + private: + + static const int cmax = 16; + + ItemIntMap& index; + + struct ClassNode { + int parent; + int depth; + + int left, right; + int next, prev; + }; + + int first_class; + int first_free_class; + std::vector classes; + + int newClass() { + if (first_free_class < 0) { + int id = classes.size(); + classes.push_back(ClassNode()); + return id; + } else { + int id = first_free_class; + first_free_class = classes[id].next; + return id; + } + } + + void deleteClass(int id) { + classes[id].next = first_free_class; + first_free_class = id; + } + + struct ItemNode { + int parent; + Item item; + Value prio; + int next, prev; + int left, right; + int size; + }; + + int first_free_node; + std::vector nodes; + + int newNode() { + if (first_free_node < 0) { + int id = nodes.size(); + nodes.push_back(ItemNode()); + return id; + } else { + int id = first_free_node; + first_free_node = nodes[id].next; + return id; + } + } + + void deleteNode(int id) { + nodes[id].next = first_free_node; + first_free_node = id; + } + + Comp comp; + + int findClass(int id) const { + int kd = id; + while (kd >= 0) { + kd = nodes[kd].parent; + } + return ~kd; + } + + int leftNode(int id) const { + int kd = ~(classes[id].parent); + for (int i = 0; i < classes[id].depth; ++i) { + kd = nodes[kd].left; + } + return kd; + } + + int nextNode(int id) const { + int depth = 0; + while (id >= 0 && nodes[id].next == -1) { + id = nodes[id].parent; + ++depth; + } + if (id < 0) { + return -1; + } + id = nodes[id].next; + while (depth--) { + id = nodes[id].left; + } + return id; + } + + + void setPrio(int id) { + int jd = nodes[id].left; + nodes[id].prio = nodes[jd].prio; + nodes[id].item = nodes[jd].item; + jd = nodes[jd].next; + while (jd != -1) { + if (comp(nodes[jd].prio, nodes[id].prio)) { + nodes[id].prio = nodes[jd].prio; + nodes[id].item = nodes[jd].item; + } + jd = nodes[jd].next; + } + } + + void push(int id, int jd) { + nodes[id].size = 1; + nodes[id].left = nodes[id].right = jd; + nodes[jd].next = nodes[jd].prev = -1; + nodes[jd].parent = id; + } + + void pushAfter(int id, int jd) { + int kd = nodes[id].parent; + if (nodes[id].next != -1) { + nodes[nodes[id].next].prev = jd; + if (kd >= 0) { + nodes[kd].size += 1; + } + } else { + if (kd >= 0) { + nodes[kd].right = jd; + nodes[kd].size += 1; + } + } + nodes[jd].next = nodes[id].next; + nodes[jd].prev = id; + nodes[id].next = jd; + nodes[jd].parent = kd; + } + + void pushRight(int id, int jd) { + nodes[id].size += 1; + nodes[jd].prev = nodes[id].right; + nodes[jd].next = -1; + nodes[nodes[id].right].next = jd; + nodes[id].right = jd; + nodes[jd].parent = id; + } + + void popRight(int id) { + nodes[id].size -= 1; + int jd = nodes[id].right; + nodes[nodes[jd].prev].next = -1; + nodes[id].right = nodes[jd].prev; + } + + void splice(int id, int jd) { + nodes[id].size += nodes[jd].size; + nodes[nodes[id].right].next = nodes[jd].left; + nodes[nodes[jd].left].prev = nodes[id].right; + int kd = nodes[jd].left; + while (kd != -1) { + nodes[kd].parent = id; + kd = nodes[kd].next; + } + nodes[id].right = nodes[jd].right; + } + + void split(int id, int jd) { + int kd = nodes[id].parent; + nodes[kd].right = nodes[id].prev; + nodes[nodes[id].prev].next = -1; + + nodes[jd].left = id; + nodes[id].prev = -1; + int num = 0; + while (id != -1) { + nodes[id].parent = jd; + nodes[jd].right = id; + id = nodes[id].next; + ++num; + } + nodes[kd].size -= num; + nodes[jd].size = num; + } + + void pushLeft(int id, int jd) { + nodes[id].size += 1; + nodes[jd].next = nodes[id].left; + nodes[jd].prev = -1; + nodes[nodes[id].left].prev = jd; + nodes[id].left = jd; + nodes[jd].parent = id; + } + + void popLeft(int id) { + nodes[id].size -= 1; + int jd = nodes[id].left; + nodes[nodes[jd].next].prev = -1; + nodes[id].left = nodes[jd].next; + } + + void repairLeft(int id) { + int jd = ~(classes[id].parent); + while (nodes[jd].left != -1) { + int kd = nodes[jd].left; + if (nodes[jd].size == 1) { + if (nodes[jd].parent < 0) { + classes[id].parent = ~kd; + classes[id].depth -= 1; + nodes[kd].parent = ~id; + deleteNode(jd); + jd = kd; + } else { + int pd = nodes[jd].parent; + if (nodes[nodes[jd].next].size < cmax) { + pushLeft(nodes[jd].next, nodes[jd].left); + if (less(jd, nodes[jd].next) || + nodes[jd].item == nodes[pd].item) { + nodes[nodes[jd].next].prio = nodes[jd].prio; + nodes[nodes[jd].next].item = nodes[jd].item; + } + popLeft(pd); + deleteNode(jd); + jd = pd; + } else { + int ld = nodes[nodes[jd].next].left; + popLeft(nodes[jd].next); + pushRight(jd, ld); + if (less(ld, nodes[jd].left) || + nodes[ld].item == nodes[pd].item) { + nodes[jd].item = nodes[ld].item; + nodes[jd].prio = nodes[ld].prio; + } + if (nodes[nodes[jd].next].item == nodes[ld].item) { + setPrio(nodes[jd].next); + } + jd = nodes[jd].left; + } + } + } else { + jd = nodes[jd].left; + } + } + } + + void repairRight(int id) { + int jd = ~(classes[id].parent); + while (nodes[jd].right != -1) { + int kd = nodes[jd].right; + if (nodes[jd].size == 1) { + if (nodes[jd].parent < 0) { + classes[id].parent = ~kd; + classes[id].depth -= 1; + nodes[kd].parent = ~id; + deleteNode(jd); + jd = kd; + } else { + int pd = nodes[jd].parent; + if (nodes[nodes[jd].prev].size < cmax) { + pushRight(nodes[jd].prev, nodes[jd].right); + if (less(jd, nodes[jd].prev) || + nodes[jd].item == nodes[pd].item) { + nodes[nodes[jd].prev].prio = nodes[jd].prio; + nodes[nodes[jd].prev].item = nodes[jd].item; + } + popRight(pd); + deleteNode(jd); + jd = pd; + } else { + int ld = nodes[nodes[jd].prev].right; + popRight(nodes[jd].prev); + pushLeft(jd, ld); + if (less(ld, nodes[jd].right) || + nodes[ld].item == nodes[pd].item) { + nodes[jd].item = nodes[ld].item; + nodes[jd].prio = nodes[ld].prio; + } + if (nodes[nodes[jd].prev].item == nodes[ld].item) { + setPrio(nodes[jd].prev); + } + jd = nodes[jd].right; + } + } + } else { + jd = nodes[jd].right; + } + } + } + + + bool less(int id, int jd) const { + return comp(nodes[id].prio, nodes[jd].prio); + } + + public: + + /// \brief Returns true when the given class is alive. + /// + /// Returns true when the given class is alive, ie. the class is + /// not nested into other class. + bool alive(int cls) const { + return classes[cls].parent < 0; + } + + /// \brief Returns true when the given class is trivial. + /// + /// Returns true when the given class is trivial, ie. the class + /// contains just one item directly. + bool trivial(int cls) const { + return classes[cls].left == -1; + } + + /// \brief Constructs the union-find. + /// + /// Constructs the union-find. + /// \brief _index The index map of the union-find. The data + /// structure uses internally for store references. + HeapUnionFind(ItemIntMap& _index) + : index(_index), first_class(-1), + first_free_class(-1), first_free_node(-1) {} + + /// \brief Clears the union-find data structure + /// + /// Erase each item from the data structure. + void clear() { + nodes.clear(); + classes.clear(); + first_free_node = first_free_class = first_class = -1; + } + + /// \brief Insert a new node into a new component. + /// + /// Insert a new node into a new component. + /// \param item The item of the new node. + /// \param prio The priority of the new node. + /// \return The class id of the one-item-heap. + int insert(const Item& item, const Value& prio) { + int id = newNode(); + nodes[id].item = item; + nodes[id].prio = prio; + nodes[id].size = 0; + + nodes[id].prev = -1; + nodes[id].next = -1; + + nodes[id].left = -1; + nodes[id].right = -1; + + nodes[id].item = item; + index[item] = id; + + int class_id = newClass(); + classes[class_id].parent = ~id; + classes[class_id].depth = 0; + + classes[class_id].left = -1; + classes[class_id].right = -1; + + if (first_class != -1) { + classes[first_class].prev = class_id; + } + classes[class_id].next = first_class; + classes[class_id].prev = -1; + first_class = class_id; + + nodes[id].parent = ~class_id; + + return class_id; + } + + /// \brief The class of the item. + /// + /// \return The alive class id of the item, which is not nested into + /// other classes. + /// + /// The time complexity is O(log(n)). + int find(const Item& item) const { + return findClass(index[item]); + } + + /// \brief Joins the classes. + /// + /// The current function joins the given classes. The parameter is + /// an STL range which should be contains valid class ids. The + /// time complexity is O(log(n)*k) where n is the overall number + /// of the joined nodes and k is the number of classes. + /// \return The class of the joined classes. + /// \pre The range should contain at least two class ids. + template + int join(Iterator begin, Iterator end) { + std::vector cs; + for (Iterator it = begin; it != end; ++it) { + cs.push_back(*it); + } + + int class_id = newClass(); + { // creation union-find + + if (first_class != -1) { + classes[first_class].prev = class_id; + } + classes[class_id].next = first_class; + classes[class_id].prev = -1; + first_class = class_id; + + classes[class_id].depth = classes[cs[0]].depth; + classes[class_id].parent = classes[cs[0]].parent; + nodes[~(classes[class_id].parent)].parent = ~class_id; + + int l = cs[0]; + + classes[class_id].left = l; + classes[class_id].right = l; + + if (classes[l].next != -1) { + classes[classes[l].next].prev = classes[l].prev; + } + classes[classes[l].prev].next = classes[l].next; + + classes[l].prev = -1; + classes[l].next = -1; + + classes[l].depth = leftNode(l); + classes[l].parent = class_id; + + } + + { // merging of heap + int l = class_id; + for (int ci = 1; ci < int(cs.size()); ++ci) { + int r = cs[ci]; + int rln = leftNode(r); + if (classes[l].depth > classes[r].depth) { + int id = ~(classes[l].parent); + for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) { + id = nodes[id].right; + } + while (id >= 0 && nodes[id].size == cmax) { + int new_id = newNode(); + int right_id = nodes[id].right; + + popRight(id); + if (nodes[id].item == nodes[right_id].item) { + setPrio(id); + } + push(new_id, right_id); + pushRight(new_id, ~(classes[r].parent)); + + if (less(~classes[r].parent, right_id)) { + nodes[new_id].item = nodes[~classes[r].parent].item; + nodes[new_id].prio = nodes[~classes[r].parent].prio; + } else { + nodes[new_id].item = nodes[right_id].item; + nodes[new_id].prio = nodes[right_id].prio; + } + + id = nodes[id].parent; + classes[r].parent = ~new_id; + } + if (id < 0) { + int new_parent = newNode(); + nodes[new_parent].next = -1; + nodes[new_parent].prev = -1; + nodes[new_parent].parent = ~l; + + push(new_parent, ~(classes[l].parent)); + pushRight(new_parent, ~(classes[r].parent)); + setPrio(new_parent); + + classes[l].parent = ~new_parent; + classes[l].depth += 1; + } else { + pushRight(id, ~(classes[r].parent)); + while (id >= 0 && less(~(classes[r].parent), id)) { + nodes[id].prio = nodes[~(classes[r].parent)].prio; + nodes[id].item = nodes[~(classes[r].parent)].item; + id = nodes[id].parent; + } + } + } else if (classes[r].depth > classes[l].depth) { + int id = ~(classes[r].parent); + for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) { + id = nodes[id].left; + } + while (id >= 0 && nodes[id].size == cmax) { + int new_id = newNode(); + int left_id = nodes[id].left; + + popLeft(id); + if (nodes[id].prio == nodes[left_id].prio) { + setPrio(id); + } + push(new_id, left_id); + pushLeft(new_id, ~(classes[l].parent)); + + if (less(~classes[l].parent, left_id)) { + nodes[new_id].item = nodes[~classes[l].parent].item; + nodes[new_id].prio = nodes[~classes[l].parent].prio; + } else { + nodes[new_id].item = nodes[left_id].item; + nodes[new_id].prio = nodes[left_id].prio; + } + + id = nodes[id].parent; + classes[l].parent = ~new_id; + + } + if (id < 0) { + int new_parent = newNode(); + nodes[new_parent].next = -1; + nodes[new_parent].prev = -1; + nodes[new_parent].parent = ~l; + + push(new_parent, ~(classes[r].parent)); + pushLeft(new_parent, ~(classes[l].parent)); + setPrio(new_parent); + + classes[r].parent = ~new_parent; + classes[r].depth += 1; + } else { + pushLeft(id, ~(classes[l].parent)); + while (id >= 0 && less(~(classes[l].parent), id)) { + nodes[id].prio = nodes[~(classes[l].parent)].prio; + nodes[id].item = nodes[~(classes[l].parent)].item; + id = nodes[id].parent; + } + } + nodes[~(classes[r].parent)].parent = ~l; + classes[l].parent = classes[r].parent; + classes[l].depth = classes[r].depth; + } else { + if (classes[l].depth != 0 && + nodes[~(classes[l].parent)].size + + nodes[~(classes[r].parent)].size <= cmax) { + splice(~(classes[l].parent), ~(classes[r].parent)); + deleteNode(~(classes[r].parent)); + if (less(~(classes[r].parent), ~(classes[l].parent))) { + nodes[~(classes[l].parent)].prio = + nodes[~(classes[r].parent)].prio; + nodes[~(classes[l].parent)].item = + nodes[~(classes[r].parent)].item; + } + } else { + int new_parent = newNode(); + nodes[new_parent].next = nodes[new_parent].prev = -1; + push(new_parent, ~(classes[l].parent)); + pushRight(new_parent, ~(classes[r].parent)); + setPrio(new_parent); + + classes[l].parent = ~new_parent; + classes[l].depth += 1; + nodes[new_parent].parent = ~l; + } + } + if (classes[r].next != -1) { + classes[classes[r].next].prev = classes[r].prev; + } + classes[classes[r].prev].next = classes[r].next; + + classes[r].prev = classes[l].right; + classes[classes[l].right].next = r; + classes[l].right = r; + classes[r].parent = l; + + classes[r].next = -1; + classes[r].depth = rln; + } + } + return class_id; + } + + /// \brief Split the class to subclasses. + /// + /// The current function splits the given class. The join, which + /// made the current class, stored a reference to the + /// subclasses. The \c splitClass() member restores the classes + /// and creates the heaps. The parameter is an STL output iterator + /// which will be filled with the subclass ids. The time + /// complexity is O(log(n)*k) where n is the overall number of + /// nodes in the splitted classes and k is the number of the + /// classes. + template + void split(int cls, Iterator out) { + std::vector cs; + { // splitting union-find + int id = cls; + int l = classes[id].left; + + classes[l].parent = classes[id].parent; + classes[l].depth = classes[id].depth; + + nodes[~(classes[l].parent)].parent = ~l; + + *out++ = l; + + while (l != -1) { + cs.push_back(l); + l = classes[l].next; + } + + classes[classes[id].right].next = first_class; + classes[first_class].prev = classes[id].right; + first_class = classes[id].left; + + if (classes[id].next != -1) { + classes[classes[id].next].prev = classes[id].prev; + } + classes[classes[id].prev].next = classes[id].next; + + deleteClass(id); + } + + { + for (int i = 1; i < int(cs.size()); ++i) { + int l = classes[cs[i]].depth; + while (nodes[nodes[l].parent].left == l) { + l = nodes[l].parent; + } + int r = l; + while (nodes[l].parent >= 0) { + l = nodes[l].parent; + int new_node = newNode(); + + nodes[new_node].prev = -1; + nodes[new_node].next = -1; + + split(r, new_node); + pushAfter(l, new_node); + setPrio(l); + setPrio(new_node); + r = new_node; + } + classes[cs[i]].parent = ~r; + classes[cs[i]].depth = classes[~(nodes[l].parent)].depth; + nodes[r].parent = ~cs[i]; + + nodes[l].next = -1; + nodes[r].prev = -1; + + repairRight(~(nodes[l].parent)); + repairLeft(cs[i]); + + *out++ = cs[i]; + } + } + } + + /// \brief Gives back the priority of the current item. + /// + /// Gives back the priority of the current item. + const Value& operator[](const Item& item) const { + return nodes[index[item]].prio; + } + + /// \brief Sets the priority of the current item. + /// + /// Sets the priority of the current item. + void set(const Item& item, const Value& prio) { + if (comp(prio, nodes[index[item]].prio)) { + decrease(item, prio); + } else if (!comp(prio, nodes[index[item]].prio)) { + increase(item, prio); + } + } + + /// \brief Increase the priority of the current item. + /// + /// Increase the priority of the current item. + void increase(const Item& item, const Value& prio) { + int id = index[item]; + int kd = nodes[id].parent; + nodes[id].prio = prio; + while (kd >= 0 && nodes[kd].item == item) { + setPrio(kd); + kd = nodes[kd].parent; + } + } + + /// \brief Increase the priority of the current item. + /// + /// Increase the priority of the current item. + void decrease(const Item& item, const Value& prio) { + int id = index[item]; + int kd = nodes[id].parent; + nodes[id].prio = prio; + while (kd >= 0 && less(id, kd)) { + nodes[kd].prio = prio; + nodes[kd].item = item; + kd = nodes[kd].parent; + } + } + + /// \brief Gives back the minimum priority of the class. + /// + /// Gives back the minimum priority of the class. + const Value& classPrio(int cls) const { + return nodes[~(classes[cls].parent)].prio; + } + + /// \brief Gives back the minimum priority item of the class. + /// + /// \return Gives back the minimum priority item of the class. + const Item& classTop(int cls) const { + return nodes[~(classes[cls].parent)].item; + } + + /// \brief Gives back a representant item of the class. + /// + /// Gives back a representant item of the class. + /// The representant is indpendent from the priorities of the + /// items. + const Item& classRep(int id) const { + int parent = classes[id].parent; + return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item; + } + + /// \brief LEMON style iterator for the items of a class. + /// + /// ClassIt is a lemon style iterator for the components. It iterates + /// on the items of a class. By example if you want to iterate on + /// each items of each classes then you may write the next code. + ///\code + /// for (ClassIt cit(huf); cit != INVALID; ++cit) { + /// std::cout << "Class: "; + /// for (ItemIt iit(huf, cit); iit != INVALID; ++iit) { + /// std::cout << toString(iit) << ' ' << std::endl; + /// } + /// std::cout << std::endl; + /// } + ///\endcode + class ItemIt { + private: + + const HeapUnionFind* _huf; + int _id, _lid; + + public: + + /// \brief Default constructor + /// + /// Default constructor + ItemIt() {} + + ItemIt(const HeapUnionFind& huf, int cls) : _huf(&huf) { + int id = cls; + int parent = _huf->classes[id].parent; + if (parent >= 0) { + _id = _huf->classes[id].depth; + if (_huf->classes[id].next != -1) { + _lid = _huf->classes[_huf->classes[id].next].depth; + } else { + _lid = -1; + } + } else { + _id = _huf->leftNode(id); + _lid = -1; + } + } + + /// \brief Increment operator + /// + /// It steps to the next item in the class. + ItemIt& operator++() { + _id = _huf->nextNode(_id); + return *this; + } + + /// \brief Conversion operator + /// + /// It converts the iterator to the current item. + operator const Item&() const { + return _huf->nodes[_id].item; + } + + /// \brief Equality operator + /// + /// Equality operator + bool operator==(const ItemIt& i) { + return i._id == _id; + } + + /// \brief Inequality operator + /// + /// Inequality operator + bool operator!=(const ItemIt& i) { + return i._id != _id; + } + + /// \brief Equality operator + /// + /// Equality operator + bool operator==(Invalid) { + return _id == _lid; + } + + /// \brief Inequality operator + /// + /// Inequality operator + bool operator!=(Invalid) { + return _id != _lid; + } + + }; + + /// \brief Class iterator + /// + /// The iterator stores + class ClassIt { + private: + + const HeapUnionFind* _huf; + int _id; + + public: + + ClassIt(const HeapUnionFind& huf) + : _huf(&huf), _id(huf.first_class) {} + + ClassIt(const HeapUnionFind& huf, int cls) + : _huf(&huf), _id(huf.classes[cls].left) {} + + ClassIt(Invalid) : _huf(0), _id(-1) {} + + const ClassIt& operator++() { + _id = _huf->classes[_id].next; + return *this; + } + + /// \brief Equality operator + /// + /// Equality operator + bool operator==(const ClassIt& i) { + return i._id == _id; + } + + /// \brief Inequality operator + /// + /// Inequality operator + bool operator!=(const ClassIt& i) { + return i._id != _id; + } + + operator int() const { + return _id; + } + + }; + + }; + + //! @} + +} //namespace lemon + +#endif //LEMON_UNION_FIND_H diff --git a/lemon/libtool b/lemon/libtool new file mode 100755 index 0000000..d5e5405 --- /dev/null +++ b/lemon/libtool @@ -0,0 +1,9055 @@ +#! /bin/bash + +# libtool - Provide generalized library-building support services. +# Generated automatically by config.status (lemon) 1.2.3 +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build shared libraries. +build_libtool_libs=no + +# Which release of libtool.m4 was used? +macro_version=2.2.6b +macro_revision=1.3018 + +# Whether or not to build static libraries. +build_old_libs=yes + +# What type of objects to build. +pic_mode=default + +# Whether or not to optimize for fast installation. +fast_install=needless + +# The host system. +host_alias= +host=x86_64-unknown-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=x86_64-unknown-linux-gnu +build_os=linux-gnu + +# A sed program that does not truncate output. +SED="/bin/sed" + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP="/bin/grep" + +# An ERE matcher. +EGREP="/bin/grep -E" + +# A literal string matcher. +FGREP="/bin/grep -F" + +# A BSD- or MS-compatible name lister. +NM="/usr/bin/nm -B" + +# Whether we need soft or hard links. +LN_S="ln -s" + +# What is the maximum length of a command? +max_cmd_len=1572864 + +# Object file suffix (normally "o"). +objext=o + +# Executable file suffix (normally ""). +exeext= + +# whether the shell understands "unset". +lt_unset=unset + +# turn spaces into newlines. +SP2NL="tr \\040 \\012" + +# turn newlines into spaces. +NL2SP="tr \\015\\012 \\040\\040" + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# An object symbol dumper. +OBJDUMP="objdump" + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd="\$MAGIC_CMD" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A symbol stripping program. +STRIP="strip" + +# Commands used to install an old-style archive. +RANLIB="ranlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" +old_postuninstall_cmds="" + +# A C compiler. +LTCC="gcc" + +# LTCC compiler flags. +LTCFLAGS="-g -O2" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl="sed -n -e 's/^T .* \\(.*\\)\$/extern int \\1();/p' -e 's/^[ABCDGIRSTW]* .* \\(.*\\)\$/extern char \\1;/p'" + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (void *) 0},/p' -e 's/^[ABCDGIRSTW]* \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (void *) \\&\\2},/p'" + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (void *) 0},/p' -e 's/^[ABCDGIRSTW]* \\([^ ]*\\) \\(lib[^ ]*\\)\$/ {\"\\2\", (void *) \\&\\2},/p' -e 's/^[ABCDGIRSTW]* \\([^ ]*\\) \\([^ ]*\\)\$/ {\"lib\\2\", (void *) \\&\\2},/p'" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# Shell to use when invoking shell scripts. +SHELL="/bin/bash" + +# An echo program that does not interpret backslashes. +ECHO="echo" + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=file + +# Must we lock files when doing compilation? +need_locks="no" + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL="" + +# Tool to change global to local symbols on Mac OS X. +NMEDIT="" + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO="" + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL="" + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64="" + +# Old archive suffix (normally "a"). +libext=a + +# Shared library suffix (normally ".so"). +shrext_cmds=".so" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Do we need the "lib" prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Library versioning type. +version_type=linux + +# Shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# Shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Command to use after installation of a shared archive. +postinstall_cmds="" + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval="" + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Compile-time system search path for libraries. +sys_lib_search_path_spec="/usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib" + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/local/lib /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu /lib32 /usr/lib32 " + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + + +# The linker used to build libraries. +LD="/usr/bin/ld -m elf_x86_64" + +# Commands used to build an old-style archive. +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" + +# A language specific compiler. +CC="gcc" + +# Is the compiler the GNU compiler? +with_gcc=yes + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=yes + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=no + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object="no" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build a shared archive. +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ + cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ + echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds="" +module_expsym_cmds="" + +# Whether we are building with GNU ld or not. +with_gnu_ld="yes" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that enforces no undefined symbols. +no_undefined_flag="" + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist +hardcode_libdir_flag_spec="\${wl}-rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into a binary +# during linking. This must work even if $libdir does not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator="" + +# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=no + +# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting ${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=no + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=no + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=no + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=no + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to "yes" if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*" + +# Symbols that must always be exported. +include_expsyms="" + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds="" + +# Specify filename containing input files. +file_list_spec="" + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs="" + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects="" +postdep_objects="" +predeps="" +postdeps="" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="" + +# ### END LIBTOOL CONFIG + +# Generated from ltmain.m4sh. + +# ltmain.sh (GNU libtool) 2.2.6b +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print informational messages (default) +# --version print version information +# -h, --help print short or long help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.2.6b +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=2.2.6b +TIMESTAMP="" +package_revision=1.3018 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# NLS nuisances: We save the old values to restore during execute mode. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done + +$lt_unset CDPATH + + + + + +: ${CP="cp -f"} +: ${ECHO="echo"} +: ${EGREP="/usr/bin/grep -E"} +: ${FGREP="/usr/bin/grep -F"} +: ${GREP="/usr/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/usr/bin/sed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +# Generated shell functions inserted here. + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +# Generated shell functions inserted here. + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +# In the unlikely event $progname began with a '-', it would play havoc with +# func_echo (imagine progname=-n), so we prepend ./ in that case: +func_dirname_and_basename "$progpath" +progname=$func_basename_result +case $progname in + -*) progname=./$progname ;; +esac + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname${mode+: }$mode: $*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` + done + my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "X$my_tmpdir" | $Xsed +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "X$1" | $Xsed \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + + + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $SED -n '/^# Usage:/,/# -h/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + $ECHO + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help +# Echo long help message to standard output and exit. +func_help () +{ + $SED -n '/^# Usage:/,/# Report bugs to/ { + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + }' < "$progpath" + exit $? +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1" + exit_cmd=exit +} + +exit_cmd=: + + + + + +# Check that we have a working $ECHO. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell, and then maybe $ECHO will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `libtool --version' happen quickly. +{ + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Parse non-mode specific arguments: + while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --config) func_config ;; + + --debug) preserve_args="$preserve_args $opt" + func_echo "enabling shell trace mode" + opt_debug='set -x' + $opt_debug + ;; + + -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break + execute_dlfiles="$execute_dlfiles $1" + shift + ;; + + --dry-run | -n) opt_dry_run=: ;; + --features) func_features ;; + --finish) mode="finish" ;; + + --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break + case $1 in + # Valid mode arguments: + clean) ;; + compile) ;; + execute) ;; + finish) ;; + install) ;; + link) ;; + relink) ;; + uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; + esac + + mode="$1" + shift + ;; + + --preserve-dup-deps) + opt_duplicate_deps=: ;; + + --quiet|--silent) preserve_args="$preserve_args $opt" + opt_silent=: + ;; + + --verbose| -v) preserve_args="$preserve_args $opt" + opt_silent=false + ;; + + --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break + preserve_args="$preserve_args $opt $1" + func_enable_tag "$1" # tagname is set here + shift + ;; + + # Separate optargs to long options: + -dlopen=*|--mode=*|--tag=*) + func_opt_split "$opt" + set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + shift + ;; + + -\?|-h) func_usage ;; + --help) opt_help=: ;; + --version) func_version ;; + + -*) func_fatal_help "unrecognized option \`$opt'" ;; + + *) nonopt="$opt" + break + ;; + esac + done + + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_duplicate_deps + ;; + esac + + # Having warned about all mis-specified options, bail out if + # anything was wrong. + $exit_cmd $EXIT_FAILURE +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +## ----------- ## +## Main. ## +## ----------- ## + +$opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + test -z "$mode" && func_fatal_error "error: you must specify a MODE." + + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$mode' for more information." +} + + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_ltwrapper_scriptname_result="" + if func_ltwrapper_executable_p "$1"; then + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + fi +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case "$@ " in + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + removelist="$removelist $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + removelist="$removelist $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { +test "$mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$mode'" + ;; + esac + + $ECHO + $ECHO "Try \`$progname --help' for more information about other modes." + + exit $? +} + + # Now that we've collected a possible --mode arg, show help if necessary + $opt_help && func_mode_help + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_quote_for_eval "$file" + args="$args $func_quote_for_eval_result" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + $ECHO "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + $ECHO "X----------------------------------------------------------------------" | $Xsed + $ECHO "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + $ECHO + $ECHO "If you ever happen to want to link against installed libraries" + $ECHO "in a given directory, LIBDIR, you must either use libtool, and" + $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" + $ECHO "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" + $ECHO " during execution" + fi + if test -n "$runpath_var"; then + $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" + $ECHO " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $ECHO + + $ECHO "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" + $ECHO "pages." + ;; + *) + $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + $ECHO "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS +} + +test "$mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $ECHO "X$nonopt" | $GREP shtool >/dev/null; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + install_prog="$install_prog$func_quote_for_eval_result" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + install_prog="$install_prog $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_verbose "extracting global C symbols from \`$progfile'" + $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + $ECHO >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +" + case $host in + *cygwin* | *mingw* | *cegcc* ) + $ECHO >> "$output_objdir/$my_dlsyms" "\ +/* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs. */" + lt_dlsym_const= ;; + *osf5*) + echo >> "$output_objdir/$my_dlsyms" "\ +/* This system does not cope well with relocations in const data */" + lt_dlsym_const= ;; + *) + lt_dlsym_const=const ;; + esac + + $ECHO >> "$output_objdir/$my_dlsyms" "\ +extern $lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +$lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + $ECHO >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) symtab_cflags="$symtab_cflags $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + + +# func_emit_wrapper_part1 [arg=no] +# +# Emit the first part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part1 () +{ + func_emit_wrapper_part1_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part1_arg1=$1 + fi + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + ECHO=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$ECHO works! + : + else + # Restart under the correct shell, and then maybe \$ECHO will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $ECHO "\ + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done +" +} +# end: func_emit_wrapper_part1 + +# func_emit_wrapper_part2 [arg=no] +# +# Emit the second part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part2 () +{ + func_emit_wrapper_part2_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part2_arg1=$1 + fi + + $ECHO "\ + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} +# end: func_emit_wrapper_part2 + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=no + if test -n "$1" ; then + func_emit_wrapper_arg1=$1 + fi + + # split this up so that func_emit_cwrapperexe_src + # can call each part independently. + func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" + func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" +} + + +# func_to_host_path arg +# +# Convert paths to host format when used with build tools. +# Intended for use with "native" mingw (where libtool itself +# is running under the msys shell), or in the following cross- +# build environments: +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# where wine is equipped with the `winepath' executable. +# In the native mingw case, the (msys) shell automatically +# converts paths for any non-msys applications it launches, +# but that facility isn't available from inside the cwrapper. +# Similar accommodations are necessary for $host mingw and +# $build cygwin. Calling this function does no harm for other +# $host/$build combinations not listed above. +# +# ARG is the path (on $build) that should be converted to +# the proper representation for $host. The result is stored +# in $func_to_host_path_result. +func_to_host_path () +{ + func_to_host_path_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + case $build in + *mingw* ) # actually, msys + # awkward: cmd appends spaces to result + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_path_tmp1=`( cmd //c echo "$1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_path_tmp1=`cygpath -w "$1"` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # Unfortunately, winepath does not exit with a non-zero + # error code, so we are forced to check the contents of + # stdout. On the other hand, if the command is not + # found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both + # error code of zero AND non-empty stdout, which explains + # the odd construction: + func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + else + # Allow warning below. + func_to_host_path_result="" + fi + ;; + esac + if test -z "$func_to_host_path_result" ; then + func_error "Could not determine host path corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_path_result="$1" + fi + ;; + esac + fi +} +# end: func_to_host_path + +# func_to_host_pathlist arg +# +# Convert pathlists to host format when used with build tools. +# See func_to_host_path(), above. This function supports the +# following $build/$host combinations (but does no harm for +# combinations not listed here): +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# +# Path separators are also converted from $build format to +# $host format. If ARG begins or ends with a path separator +# character, it is preserved (but converted to $host format) +# on output. +# +# ARG is a pathlist (on $build) that should be converted to +# the proper representation on $host. The result is stored +# in $func_to_host_pathlist_result. +func_to_host_pathlist () +{ + func_to_host_pathlist_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_to_host_pathlist_tmp2="$1" + # Once set for this call, this variable should not be + # reassigned. It is used in tha fallback case. + func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e 's|^:*||' -e 's|:*$||'` + case $build in + *mingw* ) # Actually, msys. + # Awkward: cmd appends spaces to result. + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # unfortunately, winepath doesn't convert pathlists + func_to_host_pathlist_result="" + func_to_host_pathlist_oldIFS=$IFS + IFS=: + for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do + IFS=$func_to_host_pathlist_oldIFS + if test -n "$func_to_host_pathlist_f" ; then + func_to_host_path "$func_to_host_pathlist_f" + if test -n "$func_to_host_path_result" ; then + if test -z "$func_to_host_pathlist_result" ; then + func_to_host_pathlist_result="$func_to_host_path_result" + else + func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" + fi + fi + fi + IFS=: + done + IFS=$func_to_host_pathlist_oldIFS + ;; + esac + if test -z "$func_to_host_pathlist_result" ; then + func_error "Could not determine the host path(s) corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This may break if $1 contains DOS-style drive + # specifications. The fix is not to complicate the expression + # below, but for the user to provide a working wine installation + # with winepath so that path translation in the cross-to-mingw + # case works properly. + lt_replace_pathsep_nix_to_dos="s|:|;|g" + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_replace_pathsep_nix_to_dos"` + fi + # Now, add the leading and trailing path separators back + case "$1" in + :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" + ;; + esac + case "$1" in + *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" + ;; + esac + ;; + esac + fi +} +# end: func_to_host_pathlist + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +# define setmode _setmode +#else +# include +# include +# ifdef __CYGWIN__ +# include +# define HAVE_SETENV +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +#ifdef _MSC_VER +# define S_IXUSR _S_IEXEC +# define stat _stat +# ifndef _INTPTR_T_DEFINED +# define intptr_t int +# endif +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifdef __CYGWIN__ +# define FOPEN_WB "wb" +#endif + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#undef LTWRAPPER_DEBUGPRINTF +#if defined DEBUGWRAPPER +# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args +static void +ltwrapper_debugprintf (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); +} +#else +# define LTWRAPPER_DEBUGPRINTF(args) +#endif + +const char *program_name = NULL; + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_fatal (const char *message, ...); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_opt_process_env_set (const char *arg); +void lt_opt_process_env_prepend (const char *arg); +void lt_opt_process_env_append (const char *arg); +int lt_split_name_value (const char *arg, char** name, char** value); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); + +static const char *script_text_part1 = +EOF + + func_emit_wrapper_part1 yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ "/' -e 's/$/\\n"/' + echo ";" + cat <"))); + for (i = 0; i < newargc; i++) + { + LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", + wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", + tmp_pathspec)); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + char *errstr = strerror (errno); + lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal ("Could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} + +void +lt_setenv (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", + (name ? name : ""), + (value ? value : ""))); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +int +lt_split_name_value (const char *arg, char** name, char** value) +{ + const char *p; + int len; + if (!arg || !*arg) + return 1; + + p = strchr (arg, (int)'='); + + if (!p) + return 1; + + *value = xstrdup (++p); + + len = strlen (arg) - strlen (*value); + *name = XMALLOC (char, len); + strncpy (*name, arg, len-1); + (*name)[len - 1] = '\0'; + + return 0; +} + +void +lt_opt_process_env_set (const char *arg) +{ + char *name = NULL; + char *value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); + } + + lt_setenv (name, value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_prepend (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_append (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 1); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + + +EOF +} +# end: func_emit_cwrapperexe_src + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + weak_libs="$weak_libs $arg" + prev= + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname '-L' '' "$arg" + dir=$func_stripname_result + if test -z "$dir"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" + linker_flags="$linker_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_duplicate_deps ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + case $lib in + *.la) func_source "$lib" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` + case " $weak_libs " in + *" $deplib_base "*) ;; + *) deplibs="$deplibs $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + dir=$func_stripname_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $ECHO + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because the file extensions .$libext of this argument makes me believe" + $ECHO "*** that it is just a static archive that I should not use here." + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) temp_rpath="$temp_rpath$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + $ECHO + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $ECHO + $ECHO "*** And there doesn't seem to be a static archive available" + $ECHO "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $ECHO + $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $ECHO "*** But as you try to build a module library, libtool will still create " + $ECHO "*** a static module, that should work as long as the dlopening application" + $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_dirname "$deplib" "" "." + dir="$func_dirname_result" + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + libobjs="$libobjs $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` + # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` + # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ + -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` + done + fi + if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | + $GREP . >/dev/null; then + $ECHO + if test "X$deplibs_check_method" = "Xnone"; then + $ECHO "*** Warning: inter-library dependencies are not supported in this platform." + else + $ECHO "*** Warning: inter-library dependencies are not known to be supported." + fi + $ECHO "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $ECHO + $ECHO "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + $ECHO "*** a static module, that should work as long as the dlopening" + $ECHO "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $ECHO "*** The inter-library dependencies that have been dropped here will be" + $ECHO "*** automatically added whenever a program is linked with this library" + $ECHO "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $ECHO + $ECHO "*** Since this library must not contain undefined symbols," + $ECHO "*** because either the platform does not support them or" + $ECHO "*** it was explicitly requested with -no-undefined," + $ECHO "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + delfiles="$delfiles $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$ECHO "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + $ECHO 'INPUT (' > $output + for obj in $save_libobjs + do + $ECHO "$obj" >> $output + done + $ECHO ')' >> $output + delfiles="$delfiles $output" + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + $ECHO "$obj" >> $output + done + delfiles="$delfiles $output" + output=$firstobj\"$file_list_spec$output\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + delfiles="$delfiles $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *cegcc) + # Disable wrappers for cegcc, we are cross compiling anyway. + wrappers_required=no + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $ECHO for shipping. + if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + oldobjs="$oldobjs $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $ECHO "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlfiles="$newdlfiles $libdir/$name" + ;; + *) newdlfiles="$newdlfiles $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlprefiles="$newdlprefiles $libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$mode" = link || test "$mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) RM="$RM $arg"; rmforce=yes ;; + -*) RM="$RM $arg" ;; + *) files="$files $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$mode" = uninstall || test "$mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD="/usr/bin/ld -m elf_x86_64" + +# Commands used to build an old-style archive. +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" + +# A language specific compiler. +CC="g++" + +# Is the compiler the GNU compiler? +with_gcc=yes + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=no + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object="no" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build a shared archive. +archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds="" +module_expsym_cmds="" + +# Whether we are building with GNU ld or not. +with_gnu_ld="yes" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that enforces no undefined symbols. +no_undefined_flag="" + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist +hardcode_libdir_flag_spec="\${wl}-rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into a binary +# during linking. This must work even if $libdir does not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator="" + +# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=no + +# Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting ${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=no + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=no + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=no + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=no + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to "yes" if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*" + +# Symbols that must always be exported. +include_expsyms="" + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds="" + +# Specify filename containing input files. +file_list_spec="" + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs="/usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /usr/lib/gcc/x86_64-linux-gnu/4.7/../../.." + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects="/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o" +postdep_objects="/usr/lib/gcc/x86_64-linux-gnu/4.7/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o" +predeps="" +postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="-L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../.." + +# ### END LIBTOOL TAG CONFIG: CXX diff --git a/lemon/m4/libtool.m4 b/lemon/m4/libtool.m4 new file mode 100644 index 0000000..4ff44c8 --- /dev/null +++ b/lemon/m4/libtool.m4 @@ -0,0 +1,7365 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 56 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl +_LT_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\[$]0 --fallback-echo"')dnl " + lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` + ;; +esac + +_LT_OUTPUT_LIBTOOL_INIT +]) + + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +cat >"$CONFIG_LT" <<_LTEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate a libtool stub with the current configuration. + +lt_cl_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AS_SHELL_SANITIZE +_AS_PREPARE + +exec AS_MESSAGE_FD>&1 +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +if test "$no_create" != yes; then + lt_cl_success=: + test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" + exec AS_MESSAGE_LOG_FD>/dev/null + $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false + exec AS_MESSAGE_LOG_FD>>config.log + $lt_cl_success || AS_EXIT(1) +fi +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_XSI_SHELLFNS + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX +# ----------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +AC_LINK_IFELSE([AC_LANG_PROGRAM],[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_SHELL_INIT + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[_LT_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +[$]* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(lt_ECHO) +]) +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], + [An echo program that does not interpret backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[AC_CHECK_TOOL(AR, ar, false) +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1]) + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line __oline__ "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method == "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac +AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], [ + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + ]) + LDFLAGS="$save_LDFLAGS" + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [fix_srcfile_path], [1], + [Fix the shell variable $srcfile for the compiler]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_PROG_CXX +# ------------ +# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ +# compiler, we have our own version here. +m4_defun([_LT_PROG_CXX], +[ +pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) +AC_PROG_CXX +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_CXX + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_CXX], []) + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[AC_REQUIRE([_LT_PROG_CXX])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +]) +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_PROG_F77 +# ------------ +# Since AC_PROG_F77 is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_F77], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) +AC_PROG_F77 +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_F77 + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_F77], []) + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_REQUIRE([_LT_PROG_F77])dnl +AC_LANG_PUSH(Fortran 77) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${F77-"f77"} + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_PROG_FC +# ----------- +# Since AC_PROG_FC is broken, in that it returns the empty string +# if there is no fortran compiler, we have our own version here. +m4_defun([_LT_PROG_FC], +[ +pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) +AC_PROG_FC +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi +popdef([AC_MSG_ERROR]) +])# _LT_PROG_FC + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([_LT_PROG_FC], []) + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_REQUIRE([_LT_PROG_FC])dnl +AC_LANG_PUSH(Fortran) + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + CC=${FC-"f95"} + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC="$lt_save_CC" +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC="$lt_save_CC" +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_XSI_SHELLFNS +# --------------------- +# Bourne and XSI compatible variants of some useful shell functions. +m4_defun([_LT_PROG_XSI_SHELLFNS], +[case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $[*] )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +dnl func_dirname_and_basename +dnl A portable version of this function is already defined in general.m4sh +dnl so there is no need for it here. + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[[^=]]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$[@]"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]+=\$[2]" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$[1]=\$$[1]\$[2]" +} + +_LT_EOF + ;; + esac +]) diff --git a/lemon/m4/ltoptions.m4 b/lemon/m4/ltoptions.m4 new file mode 100644 index 0000000..34151a3 --- /dev/null +++ b/lemon/m4/ltoptions.m4 @@ -0,0 +1,368 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [0], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/lemon/m4/ltsugar.m4 b/lemon/m4/ltsugar.m4 new file mode 100644 index 0000000..9000a05 --- /dev/null +++ b/lemon/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/lemon/m4/ltversion.m4 b/lemon/m4/ltversion.m4 new file mode 100644 index 0000000..1da0e8c --- /dev/null +++ b/lemon/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# Generated from ltversion.in. + +# serial 3018 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.2.6b]) +m4_define([LT_PACKAGE_REVISION], [1.3018]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.2.6b' +macro_revision='1.3018' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/lemon/m4/lt~obsolete.m4 b/lemon/m4/lt~obsolete.m4 new file mode 100644 index 0000000..637bb20 --- /dev/null +++ b/lemon/m4/lt~obsolete.m4 @@ -0,0 +1,92 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 4 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) diff --git a/lemon/m4/lx_check_coin.m4 b/lemon/m4/lx_check_coin.m4 new file mode 100644 index 0000000..7a939b3 --- /dev/null +++ b/lemon/m4/lx_check_coin.m4 @@ -0,0 +1,136 @@ +AC_DEFUN([LX_CHECK_COIN], +[ + AC_ARG_WITH([coin], +AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@]) +AS_HELP_STRING([--without-coin], [disable checking for CLP]), + [], [with_coin=yes]) + + AC_ARG_WITH([coin-includedir], +AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]), + [], [with_coin_includedir=no]) + + AC_ARG_WITH([coin-libdir], +AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]), + [], [with_coin_libdir=no]) + + lx_clp_found=no + if test x"$with_coin" != x"no"; then + AC_MSG_CHECKING([for CLP]) + + if test x"$with_coin_includedir" != x"no"; then + CLP_CXXFLAGS="-I$with_coin_includedir" + elif test x"$with_coin" != x"yes"; then + CLP_CXXFLAGS="-I$with_coin/include" + fi + + if test x"$with_coin_libdir" != x"no"; then + CLP_LDFLAGS="-L$with_coin_libdir" + elif test x"$with_coin" != x"yes"; then + CLP_LDFLAGS="-L$with_coin/lib" + fi + CLP_LIBS="-lClp -lCoinUtils -lm" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$CLP_CXXFLAGS" + LDFLAGS="$CLP_LDFLAGS" + LIBS="$CLP_LIBS" + + lx_clp_test_prog=' + #include + + int main(int argc, char** argv) + { + ClpModel clp; + return 0; + }' + + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no]) + AC_LANG_POP(C++) + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_clp_found" = x"yes"; then + AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.]) + lx_lp_found=yes + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.]) + AC_MSG_RESULT([yes]) + else + CLP_CXXFLAGS="" + CLP_LDFLAGS="" + CLP_LIBS="" + AC_MSG_RESULT([no]) + fi + fi + CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS" + AC_SUBST(CLP_CXXFLAGS) + AC_SUBST(CLP_LIBS) + AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"]) + + + lx_cbc_found=no + if test x"$lx_clp_found" = x"yes"; then + if test x"$with_coin" != x"no"; then + AC_MSG_CHECKING([for CBC]) + + if test x"$with_coin_includedir" != x"no"; then + CBC_CXXFLAGS="-I$with_coin_includedir" + elif test x"$with_coin" != x"yes"; then + CBC_CXXFLAGS="-I$with_coin/include" + fi + + if test x"$with_coin_libdir" != x"no"; then + CBC_LDFLAGS="-L$with_coin_libdir" + elif test x"$with_coin" != x"yes"; then + CBC_LDFLAGS="-L$with_coin/lib" + fi + CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$CBC_CXXFLAGS" + LDFLAGS="$CBC_LDFLAGS" + LIBS="$CBC_LIBS" + + lx_cbc_test_prog=' + #include + + int main(int argc, char** argv) + { + CbcModel cbc; + return 0; + }' + + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no]) + AC_LANG_POP(C++) + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_cbc_found" = x"yes"; then + AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.]) + lx_lp_found=yes + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.]) + lx_mip_found=yes + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.]) + AC_MSG_RESULT([yes]) + else + CBC_CXXFLAGS="" + CBC_LDFLAGS="" + CBC_LIBS="" + AC_MSG_RESULT([no]) + fi + fi + fi + CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS" + AC_SUBST(CBC_CXXFLAGS) + AC_SUBST(CBC_LIBS) + AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"]) +]) diff --git a/lemon/m4/lx_check_cplex.m4 b/lemon/m4/lx_check_cplex.m4 new file mode 100644 index 0000000..5541027 --- /dev/null +++ b/lemon/m4/lx_check_cplex.m4 @@ -0,0 +1,81 @@ +AC_DEFUN([LX_CHECK_CPLEX], +[ + AC_ARG_WITH([cplex], +AS_HELP_STRING([--with-cplex@<:@=PREFIX@:>@], [search for CPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@]) +AS_HELP_STRING([--without-cplex], [disable checking for CPLEX]), + [], [with_cplex=yes]) + + AC_ARG_WITH([cplex-includedir], +AS_HELP_STRING([--with-cplex-includedir=DIR], [search for CPLEX headers in DIR]), + [], [with_cplex_includedir=no]) + + AC_ARG_WITH([cplex-libdir], +AS_HELP_STRING([--with-cplex-libdir=DIR], [search for CPLEX libraries in DIR]), + [], [with_cplex_libdir=no]) + + lx_cplex_found=no + if test x"$with_cplex" != x"no"; then + AC_MSG_CHECKING([for CPLEX]) + + if test x"$with_cplex_includedir" != x"no"; then + CPLEX_CFLAGS="-I$with_cplex_includedir" + elif test x"$with_cplex" != x"yes"; then + CPLEX_CFLAGS="-I$with_cplex/include" + elif test x"$CPLEX_INCLUDEDIR" != x; then + CPLEX_CFLAGS="-I$CPLEX_INCLUDEDIR" + fi + + if test x"$with_cplex_libdir" != x"no"; then + CPLEX_LDFLAGS="-L$with_cplex_libdir" + elif test x"$with_cplex" != x"yes"; then + CPLEX_LDFLAGS="-L$with_cplex/lib" + elif test x"$CPLEX_LIBDIR" != x; then + CPLEX_LDFLAGS="-L$CPLEX_LIBDIR" + fi + CPLEX_LIBS="-lcplex -lm -lpthread" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$CPLEX_CFLAGS" + LDFLAGS="$CPLEX_LDFLAGS" + LIBS="$CPLEX_LIBS" + + lx_cplex_test_prog=' + extern "C" { + #include + } + + int main(int argc, char** argv) + { + CPXENVptr env = NULL; + return 0; + }' + + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([$lx_cplex_test_prog], [lx_cplex_found=yes], [lx_cplex_found=no]) + AC_LANG_POP(C++) + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_cplex_found" = x"yes"; then + AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.]) + lx_lp_found=yes + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.]) + lx_mip_found=yes + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.]) + AC_MSG_RESULT([yes]) + else + CPLEX_CFLAGS="" + CPLEX_LDFLAGS="" + CPLEX_LIBS="" + AC_MSG_RESULT([no]) + fi + fi + CPLEX_LIBS="$CPLEX_LDFLAGS $CPLEX_LIBS" + AC_SUBST(CPLEX_CFLAGS) + AC_SUBST(CPLEX_LIBS) + AM_CONDITIONAL([HAVE_CPLEX], [test x"$lx_cplex_found" = x"yes"]) +]) diff --git a/lemon/m4/lx_check_glpk.m4 b/lemon/m4/lx_check_glpk.m4 new file mode 100644 index 0000000..0d20124 --- /dev/null +++ b/lemon/m4/lx_check_glpk.m4 @@ -0,0 +1,84 @@ +AC_DEFUN([LX_CHECK_GLPK], +[ + AC_ARG_WITH([glpk], +AS_HELP_STRING([--with-glpk@<:@=PREFIX@:>@], [search for GLPK under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@]) +AS_HELP_STRING([--without-glpk], [disable checking for GLPK]), + [], [with_glpk=yes]) + + AC_ARG_WITH([glpk-includedir], +AS_HELP_STRING([--with-glpk-includedir=DIR], [search for GLPK headers in DIR]), + [], [with_glpk_includedir=no]) + + AC_ARG_WITH([glpk-libdir], +AS_HELP_STRING([--with-glpk-libdir=DIR], [search for GLPK libraries in DIR]), + [], [with_glpk_libdir=no]) + + lx_glpk_found=no + if test x"$with_glpk" != x"no"; then + AC_MSG_CHECKING([for GLPK]) + + if test x"$with_glpk_includedir" != x"no"; then + GLPK_CFLAGS="-I$with_glpk_includedir" + elif test x"$with_glpk" != x"yes"; then + GLPK_CFLAGS="-I$with_glpk/include" + fi + + if test x"$with_glpk_libdir" != x"no"; then + GLPK_LDFLAGS="-L$with_glpk_libdir" + elif test x"$with_glpk" != x"yes"; then + GLPK_LDFLAGS="-L$with_glpk/lib" + fi + GLPK_LIBS="-lglpk" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$GLPK_CFLAGS" + LDFLAGS="$GLPK_LDFLAGS" + LIBS="$GLPK_LIBS" + + lx_glpk_test_prog=' + extern "C" { + #include + } + + #if (GLP_MAJOR_VERSION < 4) \ + || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33) + #error Supported GLPK versions: 4.33 or above + #endif + + int main(int argc, char** argv) + { + LPX *lp; + lp = lpx_create_prob(); + lpx_delete_prob(lp); + return 0; + }' + + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([$lx_glpk_test_prog], [lx_glpk_found=yes], [lx_glpk_found=no]) + AC_LANG_POP(C++) + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_glpk_found" = x"yes"; then + AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.]) + lx_lp_found=yes + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.]) + lx_mip_found=yes + AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.]) + AC_MSG_RESULT([yes]) + else + GLPK_CFLAGS="" + GLPK_LDFLAGS="" + GLPK_LIBS="" + AC_MSG_RESULT([no]) + fi + fi + GLPK_LIBS="$GLPK_LDFLAGS $GLPK_LIBS" + AC_SUBST(GLPK_CFLAGS) + AC_SUBST(GLPK_LIBS) + AM_CONDITIONAL([HAVE_GLPK], [test x"$lx_glpk_found" = x"yes"]) +]) diff --git a/lemon/m4/lx_check_soplex.m4 b/lemon/m4/lx_check_soplex.m4 new file mode 100644 index 0000000..c9d6c9d --- /dev/null +++ b/lemon/m4/lx_check_soplex.m4 @@ -0,0 +1,73 @@ +AC_DEFUN([LX_CHECK_SOPLEX], +[ + AC_ARG_WITH([soplex], +AS_HELP_STRING([--with-soplex@<:@=PREFIX@:>@], [search for SOPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@]) +AS_HELP_STRING([--without-soplex], [disable checking for SOPLEX]), + [], [with_soplex=yes]) + + AC_ARG_WITH([soplex-includedir], +AS_HELP_STRING([--with-soplex-includedir=DIR], [search for SOPLEX headers in DIR]), + [], [with_soplex_includedir=no]) + + AC_ARG_WITH([soplex-libdir], +AS_HELP_STRING([--with-soplex-libdir=DIR], [search for SOPLEX libraries in DIR]), + [], [with_soplex_libdir=no]) + + lx_soplex_found=no + if test x"$with_soplex" != x"no"; then + AC_MSG_CHECKING([for SOPLEX]) + + if test x"$with_soplex_includedir" != x"no"; then + SOPLEX_CXXFLAGS="-I$with_soplex_includedir" + elif test x"$with_soplex" != x"yes"; then + SOPLEX_CXXFLAGS="-I$with_soplex/src" + fi + + if test x"$with_soplex_libdir" != x"no"; then + SOPLEX_LDFLAGS="-L$with_soplex_libdir" + elif test x"$with_soplex" != x"yes"; then + SOPLEX_LDFLAGS="-L$with_soplex/lib" + fi + SOPLEX_LIBS="-lsoplex -lz" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$SOPLEX_CXXFLAGS" + LDFLAGS="$SOPLEX_LDFLAGS" + LIBS="$SOPLEX_LIBS" + + lx_soplex_test_prog=' + #include + + int main(int argc, char** argv) + { + soplex::SoPlex soplex; + return 0; + }' + + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([$lx_soplex_test_prog], [lx_soplex_found=yes], [lx_soplex_found=no]) + AC_LANG_POP(C++) + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_soplex_found" = x"yes"; then + AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.]) + lx_lp_found=yes + AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.]) + AC_MSG_RESULT([yes]) + else + SOPLEX_CXXFLAGS="" + SOPLEX_LDFLAGS="" + SOPLEX_LIBS="" + AC_MSG_RESULT([no]) + fi + fi + SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS" + AC_SUBST(SOPLEX_CXXFLAGS) + AC_SUBST(SOPLEX_LIBS) + AM_CONDITIONAL([HAVE_SOPLEX], [test x"$lx_soplex_found" = x"yes"]) +]) diff --git a/lemon/scripts/Makefile.am b/lemon/scripts/Makefile.am new file mode 100644 index 0000000..ede305d --- /dev/null +++ b/lemon/scripts/Makefile.am @@ -0,0 +1,7 @@ +EXTRA_DIST += \ + scripts/bib2dox.py \ + scripts/bootstrap.sh \ + scripts/chg-len.py \ + scripts/mk-release.sh \ + scripts/unify-sources.sh \ + scripts/valgrind-wrapper.sh diff --git a/lemon/scripts/bib2dox.py b/lemon/scripts/bib2dox.py new file mode 100755 index 0000000..0284a3e --- /dev/null +++ b/lemon/scripts/bib2dox.py @@ -0,0 +1,816 @@ +#! /usr/bin/env python +""" + BibTeX to Doxygen converter + Usage: python bib2dox.py bibfile.bib > bibfile.dox + + This file is a part of LEMON, a generic C++ optimization library. + + ********************************************************************** + + This code is the modification of the BibTeX to XML converter + by Vidar Bronken Gundersen et al. + See the original copyright notices below. + + ********************************************************************** + + Decoder for bibliographic data, BibTeX + Usage: python bibtex2xml.py bibfile.bib > bibfile.xml + + v.8 + (c)2002-06-23 Vidar Bronken Gundersen + http://bibtexml.sf.net/ + Reuse approved as long as this notification is kept. + Licence: GPL. + + Contributions/thanks to: + Egon Willighagen, http://sf.net/projects/jreferences/ + Richard Mahoney (for providing a test case) + + Editted by Sara Sprenkle to be more robust and handle more bibtex features. + (c) 2003-01-15 + + 1. Changed bibtex: tags to bibxml: tags. + 2. Use xmlns:bibxml="http://bibtexml.sf.net/" + 3. Allow spaces between @type and first { + 4. "author" fields with multiple authors split by " and " + are put in separate xml "bibxml:author" tags. + 5. Option for Titles: words are capitalized + only if first letter in title or capitalized inside braces + 6. Removes braces from within field values + 7. Ignores comments in bibtex file (including @comment{ or % ) + 8. Replaces some special latex tags, e.g., replaces ~ with ' ' + 9. Handles bibtex @string abbreviations + --> includes bibtex's default abbreviations for months + --> does concatenation of abbr # " more " and " more " # abbr + 10. Handles @type( ... ) or @type{ ... } + 11. The keywords field is split on , or ; and put into separate xml + "bibxml:keywords" tags + 12. Ignores @preamble + + Known Limitations + 1. Does not transform Latex encoding like math mode and special + latex symbols. + 2. Does not parse author fields into first and last names. + E.g., It does not do anything special to an author whose name is + in the form LAST_NAME, FIRST_NAME + In "author" tag, will show up as + LAST_NAME, FIRST_NAME + 3. Does not handle "crossref" fields other than to print + ... + 4. Does not inform user of the input's format errors. You just won't + be able to transform the file later with XSL + + You will have to manually edit the XML output if you need to handle + these (and unknown) limitations. + +""" + +import string, re + +# set of valid name characters +valid_name_chars = '[\w\-:]' + +# +# define global regular expression variables +# +author_rex = re.compile('\s+and\s+') +rembraces_rex = re.compile('[{}]') +capitalize_rex = re.compile('({[^}]*})') + +# used by bibtexkeywords(data) +keywords_rex = re.compile('[,;]') + +# used by concat_line(line) +concatsplit_rex = re.compile('\s*#\s*') + +# split on {, }, or " in verify_out_of_braces +delimiter_rex = re.compile('([{}"])',re.I) + +field_rex = re.compile('\s*(\w*)\s*=\s*(.*)') +data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?') + +url_rex = re.compile('\\\url\{([^}]*)\}') + +# +# styles for html formatting +# +divstyle = 'margin-top: -4ex; margin-left: 8em;' + +# +# return the string parameter without braces +# +def transformurls(str): + return url_rex.sub(r'\1', str) + +# +# return the string parameter without braces +# +def removebraces(str): + return rembraces_rex.sub('', str) + +# +# latex-specific replacements +# (do this after braces were removed) +# +def latexreplacements(line): + line = string.replace(line, '~', ' ') + line = string.replace(line, '\\\'a', 'á') + line = string.replace(line, '\\"a', 'ä') + line = string.replace(line, '\\\'e', 'é') + line = string.replace(line, '\\"e', 'ë') + line = string.replace(line, '\\\'i', 'í') + line = string.replace(line, '\\"i', 'ï') + line = string.replace(line, '\\\'o', 'ó') + line = string.replace(line, '\\"o', 'ö') + line = string.replace(line, '\\\'u', 'ú') + line = string.replace(line, '\\"u', 'ü') + line = string.replace(line, '\\H o', 'õ') + line = string.replace(line, '\\H u', 'ü') # ũ does not exist + line = string.replace(line, '\\\'A', 'Á') + line = string.replace(line, '\\"A', 'Ä') + line = string.replace(line, '\\\'E', 'É') + line = string.replace(line, '\\"E', 'Ë') + line = string.replace(line, '\\\'I', 'Í') + line = string.replace(line, '\\"I', 'Ï') + line = string.replace(line, '\\\'O', 'Ó') + line = string.replace(line, '\\"O', 'Ö') + line = string.replace(line, '\\\'U', 'Ú') + line = string.replace(line, '\\"U', 'Ü') + line = string.replace(line, '\\H O', 'Õ') + line = string.replace(line, '\\H U', 'Ü') # Ũ does not exist + + return line + +# +# copy characters form a string decoding html expressions (&xyz;) +# +def copychars(str, ifrom, count): + result = '' + i = ifrom + c = 0 + html_spec = False + while (i < len(str)) and (c < count): + if str[i] == '&': + html_spec = True; + if i+1 < len(str): + result += str[i+1] + c += 1 + i += 2 + else: + if not html_spec: + if ((str[i] >= 'A') and (str[i] <= 'Z')) or \ + ((str[i] >= 'a') and (str[i] <= 'z')): + result += str[i] + c += 1 + elif str[i] == ';': + html_spec = False; + i += 1 + + return result + + +# +# Handle a list of authors (separated by 'and'). +# It gives back an array of the follwing values: +# - num: the number of authors, +# - list: the list of the author names, +# - text: the bibtex text (separated by commas and/or 'and') +# - abbrev: abbreviation that can be used for indicate the +# bibliography entries +# +def bibtexauthor(data): + result = {} + bibtex = '' + result['list'] = author_rex.split(data) + result['num'] = len(result['list']) + for i, author in enumerate(result['list']): + # general transformations + author = latexreplacements(removebraces(author.strip())) + # transform "Xyz, A. B." to "A. B. Xyz" + pos = author.find(',') + if pos != -1: + author = author[pos+1:].strip() + ' ' + author[:pos].strip() + result['list'][i] = author + bibtex += author + '#' + bibtex = bibtex[:-1] + if result['num'] > 1: + ix = bibtex.rfind('#') + if result['num'] == 2: + bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:] + else: + bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:] + bibtex = bibtex.replace('#', ', ') + result['text'] = bibtex + + result['abbrev'] = '' + for author in result['list']: + pos = author.rfind(' ') + 1 + count = 1 + if result['num'] == 1: + count = 3 + result['abbrev'] += copychars(author, pos, count) + + return result + + +# +# data = title string +# @return the capitalized title (first letter is capitalized), rest are capitalized +# only if capitalized inside braces +# +def capitalizetitle(data): + title_list = capitalize_rex.split(data) + title = '' + count = 0 + for phrase in title_list: + check = string.lstrip(phrase) + + # keep phrase's capitalization the same + if check.find('{') == 0: + title += removebraces(phrase) + else: + # first word --> capitalize first letter (after spaces) + if count == 0: + title += check.capitalize() + else: + title += phrase.lower() + count = count + 1 + + return title + + +# +# @return the bibtex for the title +# @param data --> title string +# braces are removed from title +# +def bibtextitle(data, entrytype): + if entrytype in ('book', 'inbook'): + title = removebraces(data.strip()) + else: + title = removebraces(capitalizetitle(data.strip())) + bibtex = title + return bibtex + + +# +# function to compare entry lists +# +def entry_cmp(x, y): + return cmp(x[0], y[0]) + + +# +# print the XML for the transformed "filecont_source" +# +def bibtexdecoder(filecont_source): + filecont = [] + file = [] + + # want @{, + pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),') + endtype_rex = re.compile('}\s*$') + endtag_rex = re.compile('^\s*}\s*$') + + bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)') + bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?') + + quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)') + quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?') + + for line in filecont_source: + line = line[:-1] + + # encode character entities + line = string.replace(line, '&', '&') + line = string.replace(line, '<', '<') + line = string.replace(line, '>', '>') + + # start entry: publication type (store for later use) + if pubtype_rex.match(line): + # want @{, + entrycont = {} + entry = [] + entrytype = pubtype_rex.sub('\g<1>',line) + entrytype = string.lower(entrytype) + entryid = pubtype_rex.sub('\g<2>', line) + + # end entry if just a } + elif endtype_rex.match(line): + # generate doxygen code for the entry + + # enty type related formattings + if entrytype in ('book', 'inbook'): + entrycont['title'] = '' + entrycont['title'] + '' + if not entrycont.has_key('author'): + entrycont['author'] = entrycont['editor'] + entrycont['author']['text'] += ', editors' + elif entrytype == 'article': + entrycont['journal'] = '' + entrycont['journal'] + '' + elif entrytype in ('inproceedings', 'incollection', 'conference'): + entrycont['booktitle'] = '' + entrycont['booktitle'] + '' + elif entrytype == 'techreport': + if not entrycont.has_key('type'): + entrycont['type'] = 'Technical report' + elif entrytype == 'mastersthesis': + entrycont['type'] = 'Master\'s thesis' + elif entrytype == 'phdthesis': + entrycont['type'] = 'PhD thesis' + + for eline in entrycont: + if eline != '': + eline = latexreplacements(eline) + + if entrycont.has_key('pages') and (entrycont['pages'] != ''): + entrycont['pages'] = string.replace(entrycont['pages'], '--', '-') + + if entrycont.has_key('author') and (entrycont['author'] != ''): + entry.append(entrycont['author']['text'] + '.') + if entrycont.has_key('title') and (entrycont['title'] != ''): + entry.append(entrycont['title'] + '.') + if entrycont.has_key('journal') and (entrycont['journal'] != ''): + entry.append(entrycont['journal'] + ',') + if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''): + entry.append('In ' + entrycont['booktitle'] + ',') + if entrycont.has_key('type') and (entrycont['type'] != ''): + eline = entrycont['type'] + if entrycont.has_key('number') and (entrycont['number'] != ''): + eline += ' ' + entrycont['number'] + eline += ',' + entry.append(eline) + if entrycont.has_key('institution') and (entrycont['institution'] != ''): + entry.append(entrycont['institution'] + ',') + if entrycont.has_key('publisher') and (entrycont['publisher'] != ''): + entry.append(entrycont['publisher'] + ',') + if entrycont.has_key('school') and (entrycont['school'] != ''): + entry.append(entrycont['school'] + ',') + if entrycont.has_key('address') and (entrycont['address'] != ''): + entry.append(entrycont['address'] + ',') + if entrycont.has_key('edition') and (entrycont['edition'] != ''): + entry.append(entrycont['edition'] + ' edition,') + if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''): + entry.append(entrycont['howpublished'] + ',') + if entrycont.has_key('volume') and (entrycont['volume'] != ''): + eline = entrycont['volume']; + if entrycont.has_key('number') and (entrycont['number'] != ''): + eline += '(' + entrycont['number'] + ')' + if entrycont.has_key('pages') and (entrycont['pages'] != ''): + eline += ':' + entrycont['pages'] + eline += ',' + entry.append(eline) + else: + if entrycont.has_key('pages') and (entrycont['pages'] != ''): + entry.append('pages ' + entrycont['pages'] + ',') + if entrycont.has_key('year') and (entrycont['year'] != ''): + if entrycont.has_key('month') and (entrycont['month'] != ''): + entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.') + else: + entry.append(entrycont['year'] + '.') + if entrycont.has_key('note') and (entrycont['note'] != ''): + entry.append(entrycont['note'] + '.') + if entrycont.has_key('url') and (entrycont['url'] != ''): + entry.append(entrycont['url'] + '.') + + # generate keys for sorting and for the output + sortkey = '' + bibkey = '' + if entrycont.has_key('author'): + for author in entrycont['author']['list']: + sortkey += copychars(author, author.rfind(' ')+1, len(author)) + bibkey = entrycont['author']['abbrev'] + else: + bibkey = 'x' + if entrycont.has_key('year'): + sortkey += entrycont['year'] + bibkey += entrycont['year'][-2:] + if entrycont.has_key('title'): + sortkey += entrycont['title'] + if entrycont.has_key('key'): + sortkey = entrycont['key'] + sortkey + bibkey = entrycont['key'] + entry.insert(0, sortkey) + entry.insert(1, bibkey) + entry.insert(2, entryid) + + # add the entry to the file contents + filecont.append(entry) + + else: + # field, publication info + field = '' + data = '' + + # field = {data} entries + if bracedata_rex.match(line): + field = bracefield_rex.sub('\g<1>', line) + field = string.lower(field) + data = bracedata_rex.sub('\g<2>', line) + + # field = "data" entries + elif quotedata_rex.match(line): + field = quotefield_rex.sub('\g<1>', line) + field = string.lower(field) + data = quotedata_rex.sub('\g<2>', line) + + # field = data entries + elif data_rex.match(line): + field = field_rex.sub('\g<1>', line) + field = string.lower(field) + data = data_rex.sub('\g<2>', line) + + if field == 'url': + data = '\\url{' + data.strip() + '}' + + if field in ('author', 'editor'): + entrycont[field] = bibtexauthor(data) + line = '' + elif field == 'title': + line = bibtextitle(data, entrytype) + elif field != '': + line = removebraces(transformurls(data.strip())) + + if line != '': + line = latexreplacements(line) + entrycont[field] = line + + + # sort entries + filecont.sort(entry_cmp) + + # count the bibtex keys + keytable = {} + counttable = {} + for entry in filecont: + bibkey = entry[1] + if not keytable.has_key(bibkey): + keytable[bibkey] = 1 + else: + keytable[bibkey] += 1 + + for bibkey in keytable.keys(): + counttable[bibkey] = 0 + + # generate output + for entry in filecont: + # generate output key form the bibtex key + bibkey = entry[1] + entryid = entry[2] + if keytable[bibkey] == 1: + outkey = bibkey + else: + outkey = bibkey + chr(97 + counttable[bibkey]) + counttable[bibkey] += 1 + + # append the entry code to the output + file.append('\\section ' + entryid + ' [' + outkey + ']') + file.append('

') + for line in entry[3:]: + file.append(line) + file.append('
') + file.append('') + + return file + + +# +# return 1 iff abbr is in line but not inside braces or quotes +# assumes that abbr appears only once on the line (out of braces and quotes) +# +def verify_out_of_braces(line, abbr): + + phrase_split = delimiter_rex.split(line) + + abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I) + + open_brace = 0 + open_quote = 0 + + for phrase in phrase_split: + if phrase == "{": + open_brace = open_brace + 1 + elif phrase == "}": + open_brace = open_brace - 1 + elif phrase == '"': + if open_quote == 1: + open_quote = 0 + else: + open_quote = 1 + elif abbr_rex.search(phrase): + if open_brace == 0 and open_quote == 0: + return 1 + + return 0 + + +# +# a line in the form phrase1 # phrase2 # ... # phrasen +# is returned as phrase1 phrase2 ... phrasen +# with the correct punctuation +# Bug: Doesn't always work with multiple abbreviations plugged in +# +def concat_line(line): + # only look at part after equals + field = field_rex.sub('\g<1>',line) + rest = field_rex.sub('\g<2>',line) + + concat_line = field + ' =' + + pound_split = concatsplit_rex.split(rest) + + phrase_count = 0 + length = len(pound_split) + + for phrase in pound_split: + phrase = phrase.strip() + if phrase_count != 0: + if phrase.startswith('"') or phrase.startswith('{'): + phrase = phrase[1:] + elif phrase.startswith('"'): + phrase = phrase.replace('"','{',1) + + if phrase_count != length-1: + if phrase.endswith('"') or phrase.endswith('}'): + phrase = phrase[:-1] + else: + if phrase.endswith('"'): + phrase = phrase[:-1] + phrase = phrase + "}" + elif phrase.endswith('",'): + phrase = phrase[:-2] + phrase = phrase + "}," + + # if phrase did have \#, add the \# back + if phrase.endswith('\\'): + phrase = phrase + "#" + concat_line = concat_line + ' ' + phrase + + phrase_count = phrase_count + 1 + + return concat_line + + +# +# substitute abbreviations into filecont +# @param filecont_source - string of data from file +# +def bibtex_replace_abbreviations(filecont_source): + filecont = filecont_source.splitlines() + + # These are defined in bibtex, so we'll define them too + abbr_list = ['jan','feb','mar','apr','may','jun', + 'jul','aug','sep','oct','nov','dec'] + value_list = ['January','February','March','April', + 'May','June','July','August','September', + 'October','November','December'] + + abbr_rex = [] + total_abbr_count = 0 + + front = '\\b' + back = '(,?)\\b' + + for x in abbr_list: + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) ) + total_abbr_count = total_abbr_count + 1 + + + abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)', + re.I) + + comment_rex = re.compile('@comment\s*{',re.I) + preamble_rex = re.compile('@preamble\s*{',re.I) + + waiting_for_end_string = 0 + i = 0 + filecont2 = '' + + for line in filecont: + if line == ' ' or line == '': + continue + + if waiting_for_end_string: + if re.search('}',line): + waiting_for_end_string = 0 + continue + + if abbrdef_rex.search(line): + abbr = abbrdef_rex.sub('\g<1>', line) + + if abbr_list.count(abbr) == 0: + val = abbrdef_rex.sub('\g<2>', line) + abbr_list.append(abbr) + value_list.append(string.strip(val)) + abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) ) + total_abbr_count = total_abbr_count + 1 + waiting_for_end_string = 1 + continue + + if comment_rex.search(line): + waiting_for_end_string = 1 + continue + + if preamble_rex.search(line): + waiting_for_end_string = 1 + continue + + + # replace subsequent abbreviations with the value + abbr_count = 0 + + for x in abbr_list: + + if abbr_rex[abbr_count].search(line): + if verify_out_of_braces(line,abbr_list[abbr_count]) == 1: + line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line) + # Check for # concatenations + if concatsplit_rex.search(line): + line = concat_line(line) + abbr_count = abbr_count + 1 + + + filecont2 = filecont2 + line + '\n' + i = i+1 + + + # Do one final pass over file + + # make sure that didn't end up with {" or }" after the substitution + filecont2 = filecont2.replace('{"','{{') + filecont2 = filecont2.replace('"}','}}') + + afterquotevalue_rex = re.compile('"\s*,\s*') + afterbrace_rex = re.compile('"\s*}') + afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*') + + # add new lines to data that changed because of abbreviation substitutions + filecont2 = afterquotevalue_rex.sub('",\n', filecont2) + filecont2 = afterbrace_rex.sub('"\n}', filecont2) + filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2) + + return filecont2 + +# +# convert @type( ... ) to @type{ ... } +# +def no_outer_parens(filecont): + + # do checking for open parens + # will convert to braces + paren_split = re.split('([(){}])',filecont) + + open_paren_count = 0 + open_type = 0 + look_next = 0 + + # rebuild filecont + filecont = '' + + at_rex = re.compile('@\w*') + + for phrase in paren_split: + if look_next == 1: + if phrase == '(': + phrase = '{' + open_paren_count = open_paren_count + 1 + else: + open_type = 0 + look_next = 0 + + if phrase == '(': + open_paren_count = open_paren_count + 1 + + elif phrase == ')': + open_paren_count = open_paren_count - 1 + if open_type == 1 and open_paren_count == 0: + phrase = '}' + open_type = 0 + + elif at_rex.search( phrase ): + open_type = 1 + look_next = 1 + + filecont = filecont + phrase + + return filecont + + +# +# make all whitespace into just one space +# format the bibtex file into a usable form. +# +def bibtexwasher(filecont_source): + + space_rex = re.compile('\s+') + comment_rex = re.compile('\s*%') + + filecont = [] + + # remove trailing and excessive whitespace + # ignore comments + for line in filecont_source: + line = string.strip(line) + line = space_rex.sub(' ', line) + # ignore comments + if not comment_rex.match(line) and line != '': + filecont.append(' '+ line) + + filecont = string.join(filecont, '') + + # the file is in one long string + + filecont = no_outer_parens(filecont) + + # + # split lines according to preferred syntax scheme + # + filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont) + + # add new lines after commas that are after values + filecont = re.sub('"\s*,', '",\n', filecont) + filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont) + filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,', + '\n\n\g<1>\g<2>,\n', filecont) + + # add new lines after } + filecont = re.sub('"\s*}','"\n}\n', filecont) + filecont = re.sub('}\s*,','},\n', filecont) + + + filecont = re.sub('@(\w*)', '\n@\g<1>', filecont) + + # character encoding, reserved latex characters + filecont = re.sub('{\\\&}', '&', filecont) + filecont = re.sub('\\\&', '&', filecont) + + # do checking for open braces to get format correct + open_brace_count = 0 + brace_split = re.split('([{}])',filecont) + + # rebuild filecont + filecont = '' + + for phrase in brace_split: + if phrase == '{': + open_brace_count = open_brace_count + 1 + elif phrase == '}': + open_brace_count = open_brace_count - 1 + if open_brace_count == 0: + filecont = filecont + '\n' + + filecont = filecont + phrase + + filecont2 = bibtex_replace_abbreviations(filecont) + + # gather + filecont = filecont2.splitlines() + i=0 + j=0 # count the number of blank lines + for line in filecont: + # ignore blank lines + if line == '' or line == ' ': + j = j+1 + continue + filecont[i] = line + '\n' + i = i+1 + + # get rid of the extra stuff at the end of the array + # (The extra stuff are duplicates that are in the array because + # blank lines were removed.) + length = len( filecont) + filecont[length-j:length] = [] + + return filecont + + +def filehandler(filepath): + try: + fd = open(filepath, 'r') + filecont_source = fd.readlines() + fd.close() + except: + print 'Could not open file:', filepath + washeddata = bibtexwasher(filecont_source) + outdata = bibtexdecoder(washeddata) + print '/**' + print '\page references References' + print + for line in outdata: + print line + print '*/' + + +# main program + +def main(): + import sys + if sys.argv[1:]: + filepath = sys.argv[1] + else: + print "No input file" + sys.exit() + filehandler(filepath) + +if __name__ == "__main__": main() + + +# end python script diff --git a/lemon/scripts/bootstrap.sh b/lemon/scripts/bootstrap.sh new file mode 100755 index 0000000..17960cf --- /dev/null +++ b/lemon/scripts/bootstrap.sh @@ -0,0 +1,157 @@ +#!/bin/bash +# +# This file is a part of LEMON, a generic C++ optimization library. +# +# Copyright (C) 2003-2009 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport +# (Egervary Research Group on Combinatorial Optimization, EGRES). +# +# Permission to use, modify and distribute this software is granted +# provided that this copyright notice appears in all copies. For +# precise terms see the accompanying LICENSE file. +# +# This software is provided "AS IS" with no warranty of any kind, +# express or implied, and with no claim as to its suitability for any +# purpose. + + +if [ ! -f ~/.lemon-bootstrap ]; then + echo 'Create ~/.lemon-bootstrap'. + cat >~/.lemon-bootstrap <>~/.lemon-bootstrap + echo $3 >>~/.lemon-bootstrap + echo $1=$2 >>~/.lemon-bootstrap + fi +} + +augment_config LEMON_INSTALL_PREFIX /usr/local \ + "# LEMON installation prefix" + +augment_config GLPK_PREFIX /usr/local/ \ + "# GLPK installation root prefix" + +augment_config COIN_OR_PREFIX /usr/local/coin-or \ + "# COIN-OR installation root prefix (used for CLP/CBC)" + +augment_config SOPLEX_PREFIX /usr/local/soplex \ + "# Soplex build prefix" + + +function ask() { +echo -n "$1 [$2]? " +read _an +if [ "x$_an" == "x" ]; then + ret="$2" +else + ret=$_an +fi +} + +function yesorno() { + ret='rossz' + while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do + ask "$1" "$2" + done + if [ "$ret" != "y" -a "$ret" != "yes" ]; then + return 1 + else + return 0 + fi +} + +if yesorno "External build" "n" +then + CONFIGURE_PATH=".." +else + CONFIGURE_PATH="." + if yesorno "Autoreconf" "y" + then + AUTORE=yes + else + AUTORE=no + fi +fi + +if yesorno "Optimize" "n" +then + opt_flags=' -O2' +else + opt_flags='' +fi + +if yesorno "Stop on warning" "y" +then + werror_flags=' -Werror' +else + werror_flags='' +fi + +cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags" + +if yesorno "Check with valgrind" "n" +then + valgrind_flags=' --enable-valgrind' +else + valgrind_flags='' +fi + +if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then + if yesorno "Use GLPK" "y" + then + glpk_flag="--with-glpk=$GLPK_PREFIX" + else + glpk_flag="--without-glpk" + fi +else + glpk_flag="--without-glpk" +fi + +if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then + if yesorno "Use COIN-OR (CBC/CLP)" "n" + then + coin_flag="--with-coin=$COIN_OR_PREFIX" + else + coin_flag="--without-coin" + fi +else + coin_flag="--without-coin" +fi + +if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then + if yesorno "Use Soplex" "n" + then + soplex_flag="--with-soplex=$SOPLEX_PREFIX" + else + soplex_flag="--without-soplex" + fi +else + soplex_flag="--without-soplex" +fi + +if [ "x$AUTORE" == "xyes" ]; then + autoreconf -vif; +fi +${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \ +$valgrind_flags \ +"$cxx_flags" \ +$glpk_flag \ +$coin_flag \ +$soplex_flag \ +$* diff --git a/lemon/scripts/chg-len.py b/lemon/scripts/chg-len.py new file mode 100755 index 0000000..aa2be0f --- /dev/null +++ b/lemon/scripts/chg-len.py @@ -0,0 +1,46 @@ +#! /usr/bin/env python +# +# This file is a part of LEMON, a generic C++ optimization library. +# +# Copyright (C) 2003-2009 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport +# (Egervary Research Group on Combinatorial Optimization, EGRES). +# +# Permission to use, modify and distribute this software is granted +# provided that this copyright notice appears in all copies. For +# precise terms see the accompanying LICENSE file. +# +# This software is provided "AS IS" with no warranty of any kind, +# express or implied, and with no claim as to its suitability for any +# purpose. + +import sys + +from mercurial import ui, hg +from mercurial import util + +util.rcpath = lambda : [] + +if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]: + print """ +This utility just prints the length of the longest path +in the revision graph from revison 0 to the current one. +""" + exit(0) + +u = ui.ui() +r = hg.repository(u, ".") +N = r.changectx(".").rev() +lengths=[0]*(N+1) +for i in range(N+1): + p=r.changectx(i).parents() + if p[0]: + p0=lengths[p[0].rev()] + else: + p0=-1 + if len(p)>1 and p[1]: + p1=lengths[p[1].rev()] + else: + p1=-1 + lengths[i]=max(p0,p1)+1 +print lengths[N] diff --git a/lemon/scripts/mk-release.sh b/lemon/scripts/mk-release.sh new file mode 100755 index 0000000..d3439b1 --- /dev/null +++ b/lemon/scripts/mk-release.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# This file is a part of LEMON, a generic C++ optimization library. +# +# Copyright (C) 2003-2009 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport +# (Egervary Research Group on Combinatorial Optimization, EGRES). +# +# Permission to use, modify and distribute this software is granted +# provided that this copyright notice appears in all copies. For +# precise terms see the accompanying LICENSE file. +# +# This software is provided "AS IS" with no warranty of any kind, +# express or implied, and with no claim as to its suitability for any +# purpose. + +set -e + +if [ $# = 0 ]; then + echo "Usage: $0 release-id" + exit 1 +else + export LEMON_VERSION=$1 +fi + +echo '*****************************************************************' +echo ' Start making release tarballs for version '${LEMON_VERSION} +echo '*****************************************************************' + +autoreconf -vif +./configure + +make +make html +make distcheck +tar xf lemon-${LEMON_VERSION}.tar.gz +zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION} +mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION} +tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION} +zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION} +tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION} +zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION} +hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION} + +rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION} + +echo '*****************************************************************' +echo ' Release '${LEMON_VERSION}' has been created' +echo '*****************************************************************' diff --git a/lemon/scripts/unify-sources.sh b/lemon/scripts/unify-sources.sh new file mode 100755 index 0000000..6aae63a --- /dev/null +++ b/lemon/scripts/unify-sources.sh @@ -0,0 +1,390 @@ +#!/bin/bash +# +# This file is a part of LEMON, a generic C++ optimization library. +# +# Copyright (C) 2003-2009 +# Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport +# (Egervary Research Group on Combinatorial Optimization, EGRES). +# +# Permission to use, modify and distribute this software is granted +# provided that this copyright notice appears in all copies. For +# precise terms see the accompanying LICENSE file. +# +# This software is provided "AS IS" with no warranty of any kind, +# express or implied, and with no claim as to its suitability for any +# purpose. + +YEAR=`date +%Y` +HGROOT=`hg root` + +function hg_year() { + if [ -n "$(hg st $1)" ]; then + echo $YEAR + else + hg log -l 1 --template='{date|isodate}\n' $1 | + cut -d '-' -f 1 + fi +} + +# file enumaration modes + +function all_files() { + hg status -a -m -c | + cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | + while read file; do echo $HGROOT/$file; done +} + +function modified_files() { + hg status -a -m | + cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | + while read file; do echo $HGROOT/$file; done +} + +function changed_files() { + { + if [ -n "$HG_PARENT1" ] + then + hg status --rev $HG_PARENT1:$HG_NODE -a -m + fi + if [ -n "$HG_PARENT2" ] + then + hg status --rev $HG_PARENT2:$HG_NODE -a -m + fi + } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | + sort | uniq | + while read file; do echo $HGROOT/$file; done +} + +function given_files() { + for file in $GIVEN_FILES + do + echo $file + done +} + +# actions + +function update_action() { + if ! diff -q $1 $2 >/dev/null + then + echo -n " [$3 updated]" + rm $2 + mv $1 $2 + CHANGED=YES + fi +} + +function update_warning() { + echo -n " [$2 warning]" + WARNED=YES +} + +function update_init() { + echo Update source files... + TOTAL_FILES=0 + CHANGED_FILES=0 + WARNED_FILES=0 +} + +function update_done() { + echo $CHANGED_FILES out of $TOTAL_FILES files has been changed. + echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings. +} + +function update_begin() { + ((TOTAL_FILES++)) + CHANGED=NO + WARNED=NO +} + +function update_end() { + if [ $CHANGED == YES ] + then + ((++CHANGED_FILES)) + fi + if [ $WARNED == YES ] + then + ((++WARNED_FILES)) + fi +} + +function check_action() { + if [ "$3" == 'tabs' ] + then + if echo $2 | grep -q -v -E 'Makefile\.am$' + then + PATTERN=$(echo -e '\t') + else + PATTERN=' ' + fi + elif [ "$3" == 'trailing spaces' ] + then + PATTERN='\ +$' + else + PATTERN='*' + fi + + if ! diff -q $1 $2 >/dev/null + then + if [ "$PATTERN" == '*' ] + then + diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" | + sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g" + else + grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g" + fi + FAILED=YES + fi +} + +function check_warning() { + if [ "$2" == 'long lines' ] + then + grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g" + else + echo "$1: warning: $2" + fi + WARNED=YES +} + +function check_init() { + echo Check source files... + FAILED_FILES=0 + WARNED_FILES=0 + TOTAL_FILES=0 +} + +function check_done() { + echo $FAILED_FILES out of $TOTAL_FILES files has been failed. + echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings. + + if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ] + then + if [ "$WARNING" == 'INTERACTIVE' ] + then + echo -n "Are the files with errors/warnings acceptable? (yes/no) " + while read answer + do + if [ "$answer" == 'yes' ] + then + return 0 + elif [ "$answer" == 'no' ] + then + return 1 + fi + echo -n "Are the files with errors/warnings acceptable? (yes/no) " + done + elif [ "$WARNING" == 'WERROR' ] + then + return 1 + fi + fi +} + +function check_begin() { + ((TOTAL_FILES++)) + FAILED=NO + WARNED=NO +} + +function check_end() { + if [ $FAILED == YES ] + then + ((++FAILED_FILES)) + fi + if [ $WARNED == YES ] + then + ((++WARNED_FILES)) + fi +} + + + +# checks + +function header_check() { + if echo $1 | grep -q -E 'Makefile\.am$' + then + return + fi + + TMP_FILE=`mktemp` + + (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-"$(hg_year $1)" + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided \"AS IS\" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ +" + awk 'BEGIN { pm=0; } + pm==3 { print } + /\/\* / && pm==0 { pm=1;} + /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;} + /\*\// && pm==1 { pm=2;} + ' $1 + ) >$TMP_FILE + + "$ACTION"_action "$TMP_FILE" "$1" header +} + +function tabs_check() { + if echo $1 | grep -q -v -E 'Makefile\.am$' + then + OLD_PATTERN=$(echo -e '\t') + NEW_PATTERN=' ' + else + OLD_PATTERN=' ' + NEW_PATTERN=$(echo -e '\t') + fi + TMP_FILE=`mktemp` + cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE + + "$ACTION"_action "$TMP_FILE" "$1" 'tabs' +} + +function spaces_check() { + TMP_FILE=`mktemp` + cat $1 | sed -e 's/ \+$//g' >$TMP_FILE + + "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces' +} + +function long_lines_check() { + if cat $1 | grep -q -E '.{81,}' + then + "$ACTION"_warning $1 'long lines' + fi +} + +# process the file + +function process_file() { + if [ "$ACTION" == 'update' ] + then + echo -n " $ACTION $1..." + else + echo " $ACTION $1..." + fi + + CHECKING="header tabs spaces long_lines" + + "$ACTION"_begin $1 + for check in $CHECKING + do + "$check"_check $1 + done + "$ACTION"_end $1 + if [ "$ACTION" == 'update' ] + then + echo + fi +} + +function process_all { + "$ACTION"_init + while read file + do + process_file $file + done < <($FILES) + "$ACTION"_done +} + +while [ $# -gt 0 ] +do + + if [ "$1" == '--help' ] || [ "$1" == '-h' ] + then + echo -n \ +"Usage: + $0 [OPTIONS] [files] +Options: + --dry-run|-n + Check the files, but do not modify them. + --interactive|-i + If --dry-run is specified and the checker emits warnings, + then the user is asked if the warnings should be considered + errors. + --werror|-w + Make all warnings into errors. + --all|-a + Check all source files in the repository. + --modified|-m + Check only the modified (and new) source files. This option is + useful to check the modification before making a commit. + --changed|-c + Check only the changed source files compared to the parent(s) of + the current hg node. This option is useful as hg hook script. + To automatically check all your changes before making a commit, + add the following section to the appropriate .hg/hgrc file. + + [hooks] + pretxncommit.checksources = scripts/unify-sources.sh -c -n -i + + --help|-h + Print this help message. + files + The files to check/unify. If no file names are given, the modified + source files will be checked/unified (just like using the + --modified|-m option). +" + exit 0 + elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ] + then + [ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1 + ACTION=check + elif [ "$1" == "--all" ] || [ "$1" == '-a' ] + then + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1 + FILES=all_files + elif [ "$1" == "--changed" ] || [ "$1" == '-c' ] + then + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1 + FILES=changed_files + elif [ "$1" == "--modified" ] || [ "$1" == '-m' ] + then + [ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1 + FILES=modified_files + elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ] + then + [ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1 + WARNING='INTERACTIVE' + elif [ "$1" == "--werror" ] || [ "$1" == "-w" ] + then + [ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1 + WARNING='WERROR' + elif [ $(echo x$1 | cut -c 2) == '-' ] + then + echo "Invalid option $1" >&2 && exit 1 + else + [ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1 + GIVEN_FILES=$@ + FILES=given_files + break + fi + + shift +done + +if [ -z $FILES ] +then + FILES=modified_files +fi + +if [ -z $ACTION ] +then + ACTION=update +fi + +process_all diff --git a/lemon/scripts/valgrind-wrapper.sh b/lemon/scripts/valgrind-wrapper.sh new file mode 100755 index 0000000..bbb1222 --- /dev/null +++ b/lemon/scripts/valgrind-wrapper.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# Run in valgrind, with leak checking enabled + +valgrind -q --leak-check=full "$@" 2> .valgrind-log + +# Save the test result + +result="$?" + +# Valgrind should generate no error messages + +log_contents="`cat .valgrind-log`" + +if [ "$log_contents" != "" ]; then + cat .valgrind-log >&2 + result=1 +fi + +rm -f .valgrind-log + +exit $result diff --git a/lemon/stamp-h1 b/lemon/stamp-h1 new file mode 100644 index 0000000..4547fe1 --- /dev/null +++ b/lemon/stamp-h1 @@ -0,0 +1 @@ +timestamp for config.h diff --git a/lemon/test/.deps/adaptors_test.Po b/lemon/test/.deps/adaptors_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/adaptors_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/bellman_ford_test.Po b/lemon/test/.deps/bellman_ford_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/bellman_ford_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/bfs_test.Po b/lemon/test/.deps/bfs_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/bfs_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/circulation_test.Po b/lemon/test/.deps/circulation_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/circulation_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/connectivity_test.Po b/lemon/test/.deps/connectivity_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/connectivity_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/counter_test.Po b/lemon/test/.deps/counter_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/counter_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/dfs_test.Po b/lemon/test/.deps/dfs_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/dfs_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/digraph_test.Po b/lemon/test/.deps/digraph_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/digraph_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/dijkstra_test.Po b/lemon/test/.deps/dijkstra_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/dijkstra_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/dim_test.Po b/lemon/test/.deps/dim_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/dim_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/edge_set_test.Po b/lemon/test/.deps/edge_set_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/edge_set_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/error_test.Po b/lemon/test/.deps/error_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/error_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/euler_test.Po b/lemon/test/.deps/euler_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/euler_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/fractional_matching_test.Po b/lemon/test/.deps/fractional_matching_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/fractional_matching_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/gomory_hu_test.Po b/lemon/test/.deps/gomory_hu_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/gomory_hu_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/graph_copy_test.Po b/lemon/test/.deps/graph_copy_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/graph_copy_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/graph_test.Po b/lemon/test/.deps/graph_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/graph_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/graph_utils_test.Po b/lemon/test/.deps/graph_utils_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/graph_utils_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/hao_orlin_test.Po b/lemon/test/.deps/hao_orlin_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/hao_orlin_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/heap_test.Po b/lemon/test/.deps/heap_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/heap_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/kruskal_test.Po b/lemon/test/.deps/kruskal_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/kruskal_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/lgf_test.Po b/lemon/test/.deps/lgf_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/lgf_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/lp_test.Po b/lemon/test/.deps/lp_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/lp_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/maps_test.Po b/lemon/test/.deps/maps_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/maps_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/matching_test.Po b/lemon/test/.deps/matching_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/matching_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/min_cost_arborescence_test.Po b/lemon/test/.deps/min_cost_arborescence_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/min_cost_arborescence_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/min_cost_flow_test.Po b/lemon/test/.deps/min_cost_flow_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/min_cost_flow_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/min_mean_cycle_test.Po b/lemon/test/.deps/min_mean_cycle_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/min_mean_cycle_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/mip_test.Po b/lemon/test/.deps/mip_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/mip_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/path_test.Po b/lemon/test/.deps/path_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/path_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/planarity_test.Po b/lemon/test/.deps/planarity_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/planarity_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/preflow_test.Po b/lemon/test/.deps/preflow_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/preflow_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/radix_sort_test.Po b/lemon/test/.deps/radix_sort_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/radix_sort_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/random_test.Po b/lemon/test/.deps/random_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/random_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/suurballe_test.Po b/lemon/test/.deps/suurballe_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/suurballe_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/test_tools_fail.Po b/lemon/test/.deps/test_tools_fail.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/test_tools_fail.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/test_tools_pass.Po b/lemon/test/.deps/test_tools_pass.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/test_tools_pass.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/time_measure_test.Po b/lemon/test/.deps/time_measure_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/time_measure_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/.deps/unionfind_test.Po b/lemon/test/.deps/unionfind_test.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/lemon/test/.deps/unionfind_test.Po @@ -0,0 +1 @@ +# dummy diff --git a/lemon/test/CMakeLists.txt b/lemon/test/CMakeLists.txt new file mode 100644 index 0000000..8d13982 --- /dev/null +++ b/lemon/test/CMakeLists.txt @@ -0,0 +1,151 @@ +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} +) + +LINK_DIRECTORIES( + ${PROJECT_BINARY_DIR}/lemon +) + +SET(TEST_WITH_VALGRIND "NO" CACHE STRING + "Run the test with valgrind (YES/NO).") +SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.") + +SET(TESTS + adaptors_test + bellman_ford_test + bfs_test + circulation_test + connectivity_test + counter_test + dfs_test + digraph_test + dijkstra_test + dim_test + edge_set_test + error_test + euler_test + fractional_matching_test + gomory_hu_test + graph_copy_test + graph_test + graph_utils_test + hao_orlin_test + heap_test + kruskal_test + lgf_test + maps_test + matching_test + min_cost_arborescence_test + min_cost_flow_test + min_mean_cycle_test + path_test + planarity_test + preflow_test + radix_sort_test + random_test + suurballe_test + time_measure_test + unionfind_test +) + +IF(LEMON_HAVE_LP) + IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") + ADD_EXECUTABLE(lp_test lp_test.cc) + ELSE() + ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc) + ENDIF() + + SET(LP_TEST_LIBS lemon) + + IF(LEMON_HAVE_GLPK) + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES}) + ENDIF() + IF(LEMON_HAVE_CPLEX) + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES}) + ENDIF() + IF(LEMON_HAVE_CLP) + SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES}) + ENDIF() + + TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS}) + ADD_TEST(lp_test lp_test) + ADD_DEPENDENCIES(check lp_test) + + IF(WIN32 AND LEMON_HAVE_GLPK) + GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION) + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH) + ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH} + ) + ENDIF() + + IF(WIN32 AND LEMON_HAVE_CPLEX) + GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION) + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH) + ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH} + ) + ENDIF() +ENDIF() + +IF(LEMON_HAVE_MIP) + IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") + ADD_EXECUTABLE(mip_test mip_test.cc) + ELSE() + ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc) + ENDIF() + + SET(MIP_TEST_LIBS lemon) + + IF(LEMON_HAVE_GLPK) + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES}) + ENDIF() + IF(LEMON_HAVE_CPLEX) + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES}) + ENDIF() + IF(LEMON_HAVE_CBC) + SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES}) + ENDIF() + + TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS}) + ADD_TEST(mip_test mip_test) + ADD_DEPENDENCIES(check mip_test) + + IF(WIN32 AND LEMON_HAVE_GLPK) + GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION) + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH) + ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH} + ) + ENDIF() + + IF(WIN32 AND LEMON_HAVE_CPLEX) + GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION) + GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH) + ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH} + ) + ENDIF() +ENDIF() + +FOREACH(TEST_NAME ${TESTS}) + IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") + ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc) + ELSE() + ADD_EXECUTABLE(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cc) + ENDIF() + TARGET_LINK_LIBRARIES(${TEST_NAME} lemon) + IF(TEST_WITH_VALGRIND) + ADD_TEST(${TEST_NAME} + valgrind --error-exitcode=1 ${VALGRIND_FLAGS} + ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} ) + ELSE() + ADD_TEST(${TEST_NAME} ${TEST_NAME}) + ENDIF() + ADD_DEPENDENCIES(check ${TEST_NAME}) +ENDFOREACH() diff --git a/lemon/test/Makefile.am b/lemon/test/Makefile.am new file mode 100644 index 0000000..b5fcca7 --- /dev/null +++ b/lemon/test/Makefile.am @@ -0,0 +1,101 @@ +if USE_VALGRIND +TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh +endif + +EXTRA_DIST += \ + test/CMakeLists.txt + +noinst_HEADERS += \ + test/graph_test.h \ + test/test_tools.h + +check_PROGRAMS += \ + test/adaptors_test \ + test/bellman_ford_test \ + test/bfs_test \ + test/circulation_test \ + test/connectivity_test \ + test/counter_test \ + test/dfs_test \ + test/digraph_test \ + test/dijkstra_test \ + test/dim_test \ + test/edge_set_test \ + test/error_test \ + test/euler_test \ + test/fractional_matching_test \ + test/gomory_hu_test \ + test/graph_copy_test \ + test/graph_test \ + test/graph_utils_test \ + test/hao_orlin_test \ + test/heap_test \ + test/kruskal_test \ + test/lgf_test \ + test/maps_test \ + test/matching_test \ + test/min_cost_arborescence_test \ + test/min_cost_flow_test \ + test/min_mean_cycle_test \ + test/path_test \ + test/planarity_test \ + test/preflow_test \ + test/radix_sort_test \ + test/random_test \ + test/suurballe_test \ + test/test_tools_fail \ + test/test_tools_pass \ + test/time_measure_test \ + test/unionfind_test + +test_test_tools_pass_DEPENDENCIES = demo + +if HAVE_LP +check_PROGRAMS += test/lp_test +endif HAVE_LP +if HAVE_MIP +check_PROGRAMS += test/mip_test +endif HAVE_MIP + +TESTS += $(check_PROGRAMS) +XFAIL_TESTS += test/test_tools_fail$(EXEEXT) + +test_adaptors_test_SOURCES = test/adaptors_test.cc +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc +test_bfs_test_SOURCES = test/bfs_test.cc +test_circulation_test_SOURCES = test/circulation_test.cc +test_counter_test_SOURCES = test/counter_test.cc +test_connectivity_test_SOURCES = test/connectivity_test.cc +test_dfs_test_SOURCES = test/dfs_test.cc +test_digraph_test_SOURCES = test/digraph_test.cc +test_dijkstra_test_SOURCES = test/dijkstra_test.cc +test_dim_test_SOURCES = test/dim_test.cc +test_edge_set_test_SOURCES = test/edge_set_test.cc +test_error_test_SOURCES = test/error_test.cc +test_euler_test_SOURCES = test/euler_test.cc +test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc +test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc +test_graph_copy_test_SOURCES = test/graph_copy_test.cc +test_graph_test_SOURCES = test/graph_test.cc +test_graph_utils_test_SOURCES = test/graph_utils_test.cc +test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc +test_heap_test_SOURCES = test/heap_test.cc +test_kruskal_test_SOURCES = test/kruskal_test.cc +test_lgf_test_SOURCES = test/lgf_test.cc +test_lp_test_SOURCES = test/lp_test.cc +test_maps_test_SOURCES = test/maps_test.cc +test_mip_test_SOURCES = test/mip_test.cc +test_matching_test_SOURCES = test/matching_test.cc +test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc +test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc +test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc +test_path_test_SOURCES = test/path_test.cc +test_planarity_test_SOURCES = test/planarity_test.cc +test_preflow_test_SOURCES = test/preflow_test.cc +test_radix_sort_test_SOURCES = test/radix_sort_test.cc +test_suurballe_test_SOURCES = test/suurballe_test.cc +test_random_test_SOURCES = test/random_test.cc +test_test_tools_fail_SOURCES = test/test_tools_fail.cc +test_test_tools_pass_SOURCES = test/test_tools_pass.cc +test_time_measure_test_SOURCES = test/time_measure_test.cc +test_unionfind_test_SOURCES = test/unionfind_test.cc diff --git a/lemon/test/adaptors_test.cc b/lemon/test/adaptors_test.cc new file mode 100644 index 0000000..9c625f2 --- /dev/null +++ b/lemon/test/adaptors_test.cc @@ -0,0 +1,1463 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "test/test_tools.h" +#include "test/graph_test.h" + +using namespace lemon; + +void checkReverseDigraph() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + ReverseDigraph >(); + checkConcept, + ReverseDigraph >(); + checkConcept, + ReverseDigraph >(); + checkConcept, + ReverseDigraph >(); + + // Create a digraph and an adaptor + typedef ListDigraph Digraph; + typedef ReverseDigraph Adaptor; + + Digraph digraph; + Adaptor adaptor(digraph); + + // Add nodes and arcs to the original digraph + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Digraph::Node n3 = digraph.addNode(); + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n1, n3); + Digraph::Arc a3 = digraph.addArc(n2, n3); + + // Check the adaptor + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 3); + checkGraphConArcList(adaptor, 3); + + checkGraphOutArcList(adaptor, n1, 0); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 2); + + checkGraphInArcList(adaptor, n1, 2); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 0); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check the orientation of the arcs + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) { + check(adaptor.source(a) == digraph.target(a), "Wrong reverse"); + check(adaptor.target(a) == digraph.source(a), "Wrong reverse"); + } + + // Add and erase nodes and arcs in the digraph through the adaptor + Adaptor::Node n4 = adaptor.addNode(); + + Adaptor::Arc a4 = adaptor.addArc(n4, n3); + Adaptor::Arc a5 = adaptor.addArc(n2, n4); + Adaptor::Arc a6 = adaptor.addArc(n2, n4); + Adaptor::Arc a7 = adaptor.addArc(n1, n4); + Adaptor::Arc a8 = adaptor.addArc(n1, n2); + + adaptor.erase(a1); + adaptor.erase(n3); + + // Check the adaptor + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 4); + checkGraphConArcList(adaptor, 4); + + checkGraphOutArcList(adaptor, n1, 2); + checkGraphOutArcList(adaptor, n2, 2); + checkGraphOutArcList(adaptor, n4, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n4, 3); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check the digraph + checkGraphNodeList(digraph, 3); + checkGraphArcList(digraph, 4); + checkGraphConArcList(digraph, 4); + + checkGraphOutArcList(digraph, n1, 0); + checkGraphOutArcList(digraph, n2, 1); + checkGraphOutArcList(digraph, n4, 3); + + checkGraphInArcList(digraph, n1, 2); + checkGraphInArcList(digraph, n2, 2); + checkGraphInArcList(digraph, n4, 0); + + checkNodeIds(digraph); + checkArcIds(digraph); + + checkGraphNodeMap(digraph); + checkGraphArcMap(digraph); + + // Check the conversion of nodes and arcs + Digraph::Node nd = n4; + nd = n4; + Adaptor::Node na = n1; + na = n2; + Digraph::Arc ad = a4; + ad = a5; + Adaptor::Arc aa = a1; + aa = a2; +} + +void checkSubDigraph() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + SubDigraph >(); + checkConcept, + SubDigraph >(); + checkConcept, + SubDigraph >(); + checkConcept, + SubDigraph >(); + + // Create a digraph and an adaptor + typedef ListDigraph Digraph; + typedef Digraph::NodeMap NodeFilter; + typedef Digraph::ArcMap ArcFilter; + typedef SubDigraph Adaptor; + + Digraph digraph; + NodeFilter node_filter(digraph); + ArcFilter arc_filter(digraph); + Adaptor adaptor(digraph, node_filter, arc_filter); + + // Add nodes and arcs to the original digraph and the adaptor + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + + node_filter[n1] = node_filter[n2] = node_filter[n3] = true; + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n1, n3); + Adaptor::Arc a3 = adaptor.addArc(n2, n3); + + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true; + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 3); + checkGraphConArcList(adaptor, 3); + + checkGraphOutArcList(adaptor, n1, 2); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 2); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Hide an arc + adaptor.status(a2, false); + adaptor.disable(a3); + if (!adaptor.status(a3)) adaptor.enable(a3); + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 2); + checkGraphConArcList(adaptor, 2); + + checkGraphOutArcList(adaptor, n1, 1); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Hide a node + adaptor.status(n1, false); + adaptor.disable(n3); + if (!adaptor.status(n3)) adaptor.enable(n3); + + checkGraphNodeList(adaptor, 2); + checkGraphArcList(adaptor, 1); + checkGraphConArcList(adaptor, 1); + + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n2, 0); + checkGraphInArcList(adaptor, n3, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Hide all nodes and arcs + node_filter[n1] = node_filter[n2] = node_filter[n3] = false; + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false; + + checkGraphNodeList(adaptor, 0); + checkGraphArcList(adaptor, 0); + checkGraphConArcList(adaptor, 0); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check the conversion of nodes and arcs + Digraph::Node nd = n3; + nd = n3; + Adaptor::Node na = n1; + na = n2; + Digraph::Arc ad = a3; + ad = a3; + Adaptor::Arc aa = a1; + aa = a2; +} + +void checkFilterNodes1() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + FilterNodes >(); + checkConcept, + FilterNodes >(); + checkConcept, + FilterNodes >(); + checkConcept, + FilterNodes >(); + + // Create a digraph and an adaptor + typedef ListDigraph Digraph; + typedef Digraph::NodeMap NodeFilter; + typedef FilterNodes Adaptor; + + Digraph digraph; + NodeFilter node_filter(digraph); + Adaptor adaptor(digraph, node_filter); + + // Add nodes and arcs to the original digraph and the adaptor + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + + node_filter[n1] = node_filter[n2] = node_filter[n3] = true; + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n1, n3); + Adaptor::Arc a3 = adaptor.addArc(n2, n3); + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 3); + checkGraphConArcList(adaptor, 3); + + checkGraphOutArcList(adaptor, n1, 2); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 2); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Hide a node + adaptor.status(n1, false); + adaptor.disable(n3); + if (!adaptor.status(n3)) adaptor.enable(n3); + + checkGraphNodeList(adaptor, 2); + checkGraphArcList(adaptor, 1); + checkGraphConArcList(adaptor, 1); + + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n2, 0); + checkGraphInArcList(adaptor, n3, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Hide all nodes + node_filter[n1] = node_filter[n2] = node_filter[n3] = false; + + checkGraphNodeList(adaptor, 0); + checkGraphArcList(adaptor, 0); + checkGraphConArcList(adaptor, 0); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check the conversion of nodes and arcs + Digraph::Node nd = n3; + nd = n3; + Adaptor::Node na = n1; + na = n2; + Digraph::Arc ad = a3; + ad = a3; + Adaptor::Arc aa = a1; + aa = a2; +} + +void checkFilterArcs() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + FilterArcs >(); + checkConcept, + FilterArcs >(); + checkConcept, + FilterArcs >(); + checkConcept, + FilterArcs >(); + + // Create a digraph and an adaptor + typedef ListDigraph Digraph; + typedef Digraph::ArcMap ArcFilter; + typedef FilterArcs Adaptor; + + Digraph digraph; + ArcFilter arc_filter(digraph); + Adaptor adaptor(digraph, arc_filter); + + // Add nodes and arcs to the original digraph and the adaptor + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n1, n3); + Adaptor::Arc a3 = adaptor.addArc(n2, n3); + + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true; + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 3); + checkGraphConArcList(adaptor, 3); + + checkGraphOutArcList(adaptor, n1, 2); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 2); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Hide an arc + adaptor.status(a2, false); + adaptor.disable(a3); + if (!adaptor.status(a3)) adaptor.enable(a3); + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 2); + checkGraphConArcList(adaptor, 2); + + checkGraphOutArcList(adaptor, n1, 1); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Hide all arcs + arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false; + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 0); + checkGraphConArcList(adaptor, 0); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check the conversion of nodes and arcs + Digraph::Node nd = n3; + nd = n3; + Adaptor::Node na = n1; + na = n2; + Digraph::Arc ad = a3; + ad = a3; + Adaptor::Arc aa = a1; + aa = a2; +} + +void checkUndirector() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + Undirector >(); + checkConcept, + Undirector >(); + checkConcept, + Undirector >(); + checkConcept, + Undirector >(); + + + // Create a digraph and an adaptor + typedef ListDigraph Digraph; + typedef Undirector Adaptor; + + Digraph digraph; + Adaptor adaptor(digraph); + + // Add nodes and arcs/edges to the original digraph and the adaptor + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n1, n3); + Adaptor::Edge e3 = adaptor.addEdge(n2, n3); + + // Check the original digraph + checkGraphNodeList(digraph, 3); + checkGraphArcList(digraph, 3); + checkGraphConArcList(digraph, 3); + + checkGraphOutArcList(digraph, n1, 2); + checkGraphOutArcList(digraph, n2, 1); + checkGraphOutArcList(digraph, n3, 0); + + checkGraphInArcList(digraph, n1, 0); + checkGraphInArcList(digraph, n2, 1); + checkGraphInArcList(digraph, n3, 2); + + checkNodeIds(digraph); + checkArcIds(digraph); + + checkGraphNodeMap(digraph); + checkGraphArcMap(digraph); + + // Check the adaptor + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 6); + checkGraphEdgeList(adaptor, 3); + checkGraphConArcList(adaptor, 6); + checkGraphConEdgeList(adaptor, 3); + + checkGraphIncEdgeArcLists(adaptor, n1, 2); + checkGraphIncEdgeArcLists(adaptor, n2, 2); + checkGraphIncEdgeArcLists(adaptor, n3, 2); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Check the edges of the adaptor + for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) { + check(adaptor.u(e) == digraph.source(e), "Wrong undir"); + check(adaptor.v(e) == digraph.target(e), "Wrong undir"); + } + + // Check CombinedArcMap + typedef Adaptor::CombinedArcMap + , Digraph::ArcMap > IntCombinedMap; + typedef Adaptor::CombinedArcMap + , Digraph::ArcMap > BoolCombinedMap; + checkConcept, + IntCombinedMap>(); + checkConcept, + BoolCombinedMap>(); + + Digraph::ArcMap fw_map(digraph), bk_map(digraph); + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) { + fw_map[a] = digraph.id(a); + bk_map[a] = -digraph.id(a); + } + + Adaptor::CombinedArcMap, Digraph::ArcMap > + comb_map(fw_map, bk_map); + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) { + if (adaptor.source(a) == digraph.source(a)) { + check(comb_map[a] == fw_map[a], "Wrong combined map"); + } else { + check(comb_map[a] == bk_map[a], "Wrong combined map"); + } + } + + // Check the conversion of nodes and arcs/edges + Digraph::Node nd = n3; + nd = n3; + Adaptor::Node na = n1; + na = n2; + Digraph::Arc ad = e3; + ad = e3; + Adaptor::Edge ea = a1; + ea = a2; +} + +void checkResidualDigraph() { + // Check concepts + checkConcept >(); + checkConcept >(); + + // Create a digraph and an adaptor + typedef ListDigraph Digraph; + typedef Digraph::ArcMap IntArcMap; + typedef ResidualDigraph Adaptor; + + Digraph digraph; + IntArcMap capacity(digraph), flow(digraph); + Adaptor adaptor(digraph, capacity, flow); + + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Digraph::Node n3 = digraph.addNode(); + Digraph::Node n4 = digraph.addNode(); + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n1, n3); + Digraph::Arc a3 = digraph.addArc(n1, n4); + Digraph::Arc a4 = digraph.addArc(n2, n3); + Digraph::Arc a5 = digraph.addArc(n2, n4); + Digraph::Arc a6 = digraph.addArc(n3, n4); + + capacity[a1] = 8; + capacity[a2] = 6; + capacity[a3] = 4; + capacity[a4] = 4; + capacity[a5] = 6; + capacity[a6] = 10; + + // Check the adaptor with various flow values + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) { + flow[a] = 0; + } + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 6); + checkGraphConArcList(adaptor, 6); + + checkGraphOutArcList(adaptor, n1, 3); + checkGraphOutArcList(adaptor, n2, 2); + checkGraphOutArcList(adaptor, n3, 1); + checkGraphOutArcList(adaptor, n4, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 2); + checkGraphInArcList(adaptor, n4, 3); + + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) { + flow[a] = capacity[a] / 2; + } + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 12); + checkGraphConArcList(adaptor, 12); + + checkGraphOutArcList(adaptor, n1, 3); + checkGraphOutArcList(adaptor, n2, 3); + checkGraphOutArcList(adaptor, n3, 3); + checkGraphOutArcList(adaptor, n4, 3); + + checkGraphInArcList(adaptor, n1, 3); + checkGraphInArcList(adaptor, n2, 3); + checkGraphInArcList(adaptor, n3, 3); + checkGraphInArcList(adaptor, n4, 3); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) { + flow[a] = capacity[a]; + } + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 6); + checkGraphConArcList(adaptor, 6); + + checkGraphOutArcList(adaptor, n1, 0); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 2); + checkGraphOutArcList(adaptor, n4, 3); + + checkGraphInArcList(adaptor, n1, 3); + checkGraphInArcList(adaptor, n2, 2); + checkGraphInArcList(adaptor, n3, 1); + checkGraphInArcList(adaptor, n4, 0); + + // Saturate all backward arcs + // (set the flow to zero on all forward arcs) + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) { + if (adaptor.backward(a)) + adaptor.augment(a, adaptor.residualCapacity(a)); + } + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 6); + checkGraphConArcList(adaptor, 6); + + checkGraphOutArcList(adaptor, n1, 3); + checkGraphOutArcList(adaptor, n2, 2); + checkGraphOutArcList(adaptor, n3, 1); + checkGraphOutArcList(adaptor, n4, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 2); + checkGraphInArcList(adaptor, n4, 3); + + // Find maximum flow by augmenting along shortest paths + int flow_value = 0; + Adaptor::ResidualCapacity res_cap(adaptor); + while (true) { + + Bfs bfs(adaptor); + bfs.run(n1, n4); + + if (!bfs.reached(n4)) break; + + Path p = bfs.path(n4); + + int min = std::numeric_limits::max(); + for (Path::ArcIt a(p); a != INVALID; ++a) { + if (res_cap[a] < min) min = res_cap[a]; + } + + for (Path::ArcIt a(p); a != INVALID; ++a) { + adaptor.augment(a, min); + } + flow_value += min; + } + + check(flow_value == 18, "Wrong flow with res graph adaptor"); + + // Check forward() and backward() + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) { + check(adaptor.forward(a) != adaptor.backward(a), + "Wrong forward() or backward()"); + check((adaptor.forward(a) && adaptor.forward(Digraph::Arc(a)) == a) || + (adaptor.backward(a) && adaptor.backward(Digraph::Arc(a)) == a), + "Wrong forward() or backward()"); + } + + // Check the conversion of nodes and arcs + Digraph::Node nd = Adaptor::NodeIt(adaptor); + nd = ++Adaptor::NodeIt(adaptor); + Adaptor::Node na = n1; + na = n2; + Digraph::Arc ad = Adaptor::ArcIt(adaptor); + ad = ++Adaptor::ArcIt(adaptor); +} + +void checkSplitNodes() { + // Check concepts + checkConcept >(); + checkConcept >(); + + // Create a digraph and an adaptor + typedef ListDigraph Digraph; + typedef SplitNodes Adaptor; + + Digraph digraph; + Adaptor adaptor(digraph); + + Digraph::Node n1 = digraph.addNode(); + Digraph::Node n2 = digraph.addNode(); + Digraph::Node n3 = digraph.addNode(); + + Digraph::Arc a1 = digraph.addArc(n1, n2); + Digraph::Arc a2 = digraph.addArc(n1, n3); + Digraph::Arc a3 = digraph.addArc(n2, n3); + + checkGraphNodeList(adaptor, 6); + checkGraphArcList(adaptor, 6); + checkGraphConArcList(adaptor, 6); + + checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1); + checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2); + checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1); + checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1); + checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1); + checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0); + + checkGraphInArcList(adaptor, adaptor.inNode(n1), 0); + checkGraphInArcList(adaptor, adaptor.outNode(n1), 1); + checkGraphInArcList(adaptor, adaptor.inNode(n2), 1); + checkGraphInArcList(adaptor, adaptor.outNode(n2), 1); + checkGraphInArcList(adaptor, adaptor.inNode(n3), 2); + checkGraphInArcList(adaptor, adaptor.outNode(n3), 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check split + for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) { + if (adaptor.origArc(a)) { + Digraph::Arc oa = a; + check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)), + "Wrong split"); + check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)), + "Wrong split"); + } else { + Digraph::Node on = a; + check(adaptor.source(a) == adaptor.inNode(on), "Wrong split"); + check(adaptor.target(a) == adaptor.outNode(on), "Wrong split"); + } + } + + // Check combined node map + typedef Adaptor::CombinedNodeMap + , Digraph::NodeMap > IntCombinedNodeMap; + typedef Adaptor::CombinedNodeMap + , Digraph::NodeMap > BoolCombinedNodeMap; + checkConcept, + IntCombinedNodeMap>(); +//checkConcept, +// BoolCombinedNodeMap>(); + checkConcept, + BoolCombinedNodeMap>(); + + Digraph::NodeMap in_map(digraph), out_map(digraph); + for (Digraph::NodeIt n(digraph); n != INVALID; ++n) { + in_map[n] = digraph.id(n); + out_map[n] = -digraph.id(n); + } + + Adaptor::CombinedNodeMap, Digraph::NodeMap > + node_map(in_map, out_map); + for (Adaptor::NodeIt n(adaptor); n != INVALID; ++n) { + if (adaptor.inNode(n)) { + check(node_map[n] == in_map[n], "Wrong combined node map"); + } else { + check(node_map[n] == out_map[n], "Wrong combined node map"); + } + } + + // Check combined arc map + typedef Adaptor::CombinedArcMap + , Digraph::NodeMap > IntCombinedArcMap; + typedef Adaptor::CombinedArcMap + , Digraph::NodeMap > BoolCombinedArcMap; + checkConcept, + IntCombinedArcMap>(); +//checkConcept, +// BoolCombinedArcMap>(); + checkConcept, + BoolCombinedArcMap>(); + + Digraph::ArcMap a_map(digraph); + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) { + a_map[a] = digraph.id(a); + } + + Adaptor::CombinedArcMap, Digraph::NodeMap > + arc_map(a_map, out_map); + for (Digraph::ArcIt a(digraph); a != INVALID; ++a) { + check(arc_map[adaptor.arc(a)] == a_map[a], "Wrong combined arc map"); + } + for (Digraph::NodeIt n(digraph); n != INVALID; ++n) { + check(arc_map[adaptor.arc(n)] == out_map[n], "Wrong combined arc map"); + } + + // Check the conversion of nodes + Digraph::Node nd = adaptor.inNode(n1); + check (nd == n1, "Wrong node conversion"); + nd = adaptor.outNode(n2); + check (nd == n2, "Wrong node conversion"); +} + +void checkSubGraph() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + SubGraph >(); + checkConcept, + SubGraph >(); + checkConcept, + SubGraph >(); + checkConcept, + SubGraph >(); + + // Create a graph and an adaptor + typedef ListGraph Graph; + typedef Graph::NodeMap NodeFilter; + typedef Graph::EdgeMap EdgeFilter; + typedef SubGraph Adaptor; + + Graph graph; + NodeFilter node_filter(graph); + EdgeFilter edge_filter(graph); + Adaptor adaptor(graph, node_filter, edge_filter); + + // Add nodes and edges to the original graph and the adaptor + Graph::Node n1 = graph.addNode(); + Graph::Node n2 = graph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + Adaptor::Node n4 = adaptor.addNode(); + + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true; + + Graph::Edge e1 = graph.addEdge(n1, n2); + Graph::Edge e2 = graph.addEdge(n1, n3); + Adaptor::Edge e3 = adaptor.addEdge(n2, n3); + Adaptor::Edge e4 = adaptor.addEdge(n3, n4); + + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true; + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 8); + checkGraphEdgeList(adaptor, 4); + checkGraphConArcList(adaptor, 8); + checkGraphConEdgeList(adaptor, 4); + + checkGraphIncEdgeArcLists(adaptor, n1, 2); + checkGraphIncEdgeArcLists(adaptor, n2, 2); + checkGraphIncEdgeArcLists(adaptor, n3, 3); + checkGraphIncEdgeArcLists(adaptor, n4, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Hide an edge + adaptor.status(e2, false); + adaptor.disable(e3); + if (!adaptor.status(e3)) adaptor.enable(e3); + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 6); + checkGraphEdgeList(adaptor, 3); + checkGraphConArcList(adaptor, 6); + checkGraphConEdgeList(adaptor, 3); + + checkGraphIncEdgeArcLists(adaptor, n1, 1); + checkGraphIncEdgeArcLists(adaptor, n2, 2); + checkGraphIncEdgeArcLists(adaptor, n3, 2); + checkGraphIncEdgeArcLists(adaptor, n4, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Hide a node + adaptor.status(n1, false); + adaptor.disable(n3); + if (!adaptor.status(n3)) adaptor.enable(n3); + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 4); + checkGraphEdgeList(adaptor, 2); + checkGraphConArcList(adaptor, 4); + checkGraphConEdgeList(adaptor, 2); + + checkGraphIncEdgeArcLists(adaptor, n2, 1); + checkGraphIncEdgeArcLists(adaptor, n3, 2); + checkGraphIncEdgeArcLists(adaptor, n4, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Hide all nodes and edges + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false; + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false; + + checkGraphNodeList(adaptor, 0); + checkGraphArcList(adaptor, 0); + checkGraphEdgeList(adaptor, 0); + checkGraphConArcList(adaptor, 0); + checkGraphConEdgeList(adaptor, 0); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Check the conversion of nodes and edges + Graph::Node ng = n3; + ng = n4; + Adaptor::Node na = n1; + na = n2; + Graph::Edge eg = e3; + eg = e4; + Adaptor::Edge ea = e1; + ea = e2; +} + +void checkFilterNodes2() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + FilterNodes >(); + checkConcept, + FilterNodes >(); + checkConcept, + FilterNodes >(); + checkConcept, + FilterNodes >(); + + // Create a graph and an adaptor + typedef ListGraph Graph; + typedef Graph::NodeMap NodeFilter; + typedef FilterNodes Adaptor; + + // Add nodes and edges to the original graph and the adaptor + Graph graph; + NodeFilter node_filter(graph); + Adaptor adaptor(graph, node_filter); + + Graph::Node n1 = graph.addNode(); + Graph::Node n2 = graph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + Adaptor::Node n4 = adaptor.addNode(); + + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true; + + Graph::Edge e1 = graph.addEdge(n1, n2); + Graph::Edge e2 = graph.addEdge(n1, n3); + Adaptor::Edge e3 = adaptor.addEdge(n2, n3); + Adaptor::Edge e4 = adaptor.addEdge(n3, n4); + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 8); + checkGraphEdgeList(adaptor, 4); + checkGraphConArcList(adaptor, 8); + checkGraphConEdgeList(adaptor, 4); + + checkGraphIncEdgeArcLists(adaptor, n1, 2); + checkGraphIncEdgeArcLists(adaptor, n2, 2); + checkGraphIncEdgeArcLists(adaptor, n3, 3); + checkGraphIncEdgeArcLists(adaptor, n4, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Hide a node + adaptor.status(n1, false); + adaptor.disable(n3); + if (!adaptor.status(n3)) adaptor.enable(n3); + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 4); + checkGraphEdgeList(adaptor, 2); + checkGraphConArcList(adaptor, 4); + checkGraphConEdgeList(adaptor, 2); + + checkGraphIncEdgeArcLists(adaptor, n2, 1); + checkGraphIncEdgeArcLists(adaptor, n3, 2); + checkGraphIncEdgeArcLists(adaptor, n4, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Hide all nodes + node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false; + + checkGraphNodeList(adaptor, 0); + checkGraphArcList(adaptor, 0); + checkGraphEdgeList(adaptor, 0); + checkGraphConArcList(adaptor, 0); + checkGraphConEdgeList(adaptor, 0); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Check the conversion of nodes and edges + Graph::Node ng = n3; + ng = n4; + Adaptor::Node na = n1; + na = n2; + Graph::Edge eg = e3; + eg = e4; + Adaptor::Edge ea = e1; + ea = e2; +} + +void checkFilterEdges() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + FilterEdges >(); + checkConcept, + FilterEdges >(); + checkConcept, + FilterEdges >(); + checkConcept, + FilterEdges >(); + + // Create a graph and an adaptor + typedef ListGraph Graph; + typedef Graph::EdgeMap EdgeFilter; + typedef FilterEdges Adaptor; + + Graph graph; + EdgeFilter edge_filter(graph); + Adaptor adaptor(graph, edge_filter); + + // Add nodes and edges to the original graph and the adaptor + Graph::Node n1 = graph.addNode(); + Graph::Node n2 = graph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + Adaptor::Node n4 = adaptor.addNode(); + + Graph::Edge e1 = graph.addEdge(n1, n2); + Graph::Edge e2 = graph.addEdge(n1, n3); + Adaptor::Edge e3 = adaptor.addEdge(n2, n3); + Adaptor::Edge e4 = adaptor.addEdge(n3, n4); + + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true; + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 8); + checkGraphEdgeList(adaptor, 4); + checkGraphConArcList(adaptor, 8); + checkGraphConEdgeList(adaptor, 4); + + checkGraphIncEdgeArcLists(adaptor, n1, 2); + checkGraphIncEdgeArcLists(adaptor, n2, 2); + checkGraphIncEdgeArcLists(adaptor, n3, 3); + checkGraphIncEdgeArcLists(adaptor, n4, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Hide an edge + adaptor.status(e2, false); + adaptor.disable(e3); + if (!adaptor.status(e3)) adaptor.enable(e3); + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 6); + checkGraphEdgeList(adaptor, 3); + checkGraphConArcList(adaptor, 6); + checkGraphConEdgeList(adaptor, 3); + + checkGraphIncEdgeArcLists(adaptor, n1, 1); + checkGraphIncEdgeArcLists(adaptor, n2, 2); + checkGraphIncEdgeArcLists(adaptor, n3, 2); + checkGraphIncEdgeArcLists(adaptor, n4, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Hide all edges + edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false; + + checkGraphNodeList(adaptor, 4); + checkGraphArcList(adaptor, 0); + checkGraphEdgeList(adaptor, 0); + checkGraphConArcList(adaptor, 0); + checkGraphConEdgeList(adaptor, 0); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + checkEdgeIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + checkGraphEdgeMap(adaptor); + + // Check the conversion of nodes and edges + Graph::Node ng = n3; + ng = n4; + Adaptor::Node na = n1; + na = n2; + Graph::Edge eg = e3; + eg = e4; + Adaptor::Edge ea = e1; + ea = e2; +} + +void checkOrienter() { + // Check concepts + checkConcept >(); + checkConcept >(); + checkConcept, + Orienter >(); + checkConcept, + Orienter >(); + checkConcept, + Orienter >(); + checkConcept, + Orienter >(); + + // Create a graph and an adaptor + typedef ListGraph Graph; + typedef ListGraph::EdgeMap DirMap; + typedef Orienter Adaptor; + + Graph graph; + DirMap dir(graph); + Adaptor adaptor(graph, dir); + + // Add nodes and edges to the original graph and the adaptor + Graph::Node n1 = graph.addNode(); + Graph::Node n2 = graph.addNode(); + Adaptor::Node n3 = adaptor.addNode(); + + Graph::Edge e1 = graph.addEdge(n1, n2); + Graph::Edge e2 = graph.addEdge(n1, n3); + Adaptor::Arc e3 = adaptor.addArc(n2, n3); + + dir[e1] = dir[e2] = dir[e3] = true; + + // Check the original graph + checkGraphNodeList(graph, 3); + checkGraphArcList(graph, 6); + checkGraphConArcList(graph, 6); + checkGraphEdgeList(graph, 3); + checkGraphConEdgeList(graph, 3); + + checkGraphIncEdgeArcLists(graph, n1, 2); + checkGraphIncEdgeArcLists(graph, n2, 2); + checkGraphIncEdgeArcLists(graph, n3, 2); + + checkNodeIds(graph); + checkArcIds(graph); + checkEdgeIds(graph); + + checkGraphNodeMap(graph); + checkGraphArcMap(graph); + checkGraphEdgeMap(graph); + + // Check the adaptor + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 3); + checkGraphConArcList(adaptor, 3); + + checkGraphOutArcList(adaptor, n1, 2); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 0); + + checkGraphInArcList(adaptor, n1, 0); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 2); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check direction changing + { + dir[e1] = true; + Adaptor::Node u = adaptor.source(e1); + Adaptor::Node v = adaptor.target(e1); + + dir[e1] = false; + check (u == adaptor.target(e1), "Wrong dir"); + check (v == adaptor.source(e1), "Wrong dir"); + + check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir"); + dir[e1] = n1 == u; + } + + { + dir[e2] = true; + Adaptor::Node u = adaptor.source(e2); + Adaptor::Node v = adaptor.target(e2); + + dir[e2] = false; + check (u == adaptor.target(e2), "Wrong dir"); + check (v == adaptor.source(e2), "Wrong dir"); + + check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir"); + dir[e2] = n3 == u; + } + + { + dir[e3] = true; + Adaptor::Node u = adaptor.source(e3); + Adaptor::Node v = adaptor.target(e3); + + dir[e3] = false; + check (u == adaptor.target(e3), "Wrong dir"); + check (v == adaptor.source(e3), "Wrong dir"); + + check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir"); + dir[e3] = n2 == u; + } + + // Check the adaptor again + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 3); + checkGraphConArcList(adaptor, 3); + + checkGraphOutArcList(adaptor, n1, 1); + checkGraphOutArcList(adaptor, n2, 1); + checkGraphOutArcList(adaptor, n3, 1); + + checkGraphInArcList(adaptor, n1, 1); + checkGraphInArcList(adaptor, n2, 1); + checkGraphInArcList(adaptor, n3, 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check reverseArc() + adaptor.reverseArc(e2); + adaptor.reverseArc(e3); + adaptor.reverseArc(e2); + + checkGraphNodeList(adaptor, 3); + checkGraphArcList(adaptor, 3); + checkGraphConArcList(adaptor, 3); + + checkGraphOutArcList(adaptor, n1, 1); + checkGraphOutArcList(adaptor, n2, 0); + checkGraphOutArcList(adaptor, n3, 2); + + checkGraphInArcList(adaptor, n1, 1); + checkGraphInArcList(adaptor, n2, 2); + checkGraphInArcList(adaptor, n3, 0); + + // Check the conversion of nodes and arcs/edges + Graph::Node ng = n3; + ng = n3; + Adaptor::Node na = n1; + na = n2; + Graph::Edge eg = e3; + eg = e3; + Adaptor::Arc aa = e1; + aa = e2; +} + +void checkCombiningAdaptors() { + // Create a grid graph + GridGraph graph(2,2); + GridGraph::Node n1 = graph(0,0); + GridGraph::Node n2 = graph(0,1); + GridGraph::Node n3 = graph(1,0); + GridGraph::Node n4 = graph(1,1); + + GridGraph::EdgeMap dir_map(graph); + dir_map[graph.right(n1)] = graph.u(graph.right(n1)) != n1; + dir_map[graph.up(n1)] = graph.u(graph.up(n1)) == n1; + dir_map[graph.left(n4)] = graph.u(graph.left(n4)) == n4; + dir_map[graph.down(n4)] = graph.u(graph.down(n4)) == n4; + + // Apply several adaptors on the grid graph + typedef SplitNodes > > + SplitGridGraph; + typedef Undirector USplitGridGraph; + checkConcept(); + checkConcept(); + + SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map)); + USplitGridGraph uadaptor = undirector(adaptor); + + // Check adaptor + checkGraphNodeList(adaptor, 8); + checkGraphArcList(adaptor, 8); + checkGraphConArcList(adaptor, 8); + + checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1); + checkGraphOutArcList(adaptor, adaptor.outNode(n1), 1); + checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1); + checkGraphOutArcList(adaptor, adaptor.outNode(n2), 0); + checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1); + checkGraphOutArcList(adaptor, adaptor.outNode(n3), 1); + checkGraphOutArcList(adaptor, adaptor.inNode(n4), 1); + checkGraphOutArcList(adaptor, adaptor.outNode(n4), 2); + + checkGraphInArcList(adaptor, adaptor.inNode(n1), 1); + checkGraphInArcList(adaptor, adaptor.outNode(n1), 1); + checkGraphInArcList(adaptor, adaptor.inNode(n2), 2); + checkGraphInArcList(adaptor, adaptor.outNode(n2), 1); + checkGraphInArcList(adaptor, adaptor.inNode(n3), 1); + checkGraphInArcList(adaptor, adaptor.outNode(n3), 1); + checkGraphInArcList(adaptor, adaptor.inNode(n4), 0); + checkGraphInArcList(adaptor, adaptor.outNode(n4), 1); + + checkNodeIds(adaptor); + checkArcIds(adaptor); + + checkGraphNodeMap(adaptor); + checkGraphArcMap(adaptor); + + // Check uadaptor + checkGraphNodeList(uadaptor, 8); + checkGraphEdgeList(uadaptor, 8); + checkGraphArcList(uadaptor, 16); + checkGraphConEdgeList(uadaptor, 8); + checkGraphConArcList(uadaptor, 16); + + checkNodeIds(uadaptor); + checkEdgeIds(uadaptor); + checkArcIds(uadaptor); + + checkGraphNodeMap(uadaptor); + checkGraphEdgeMap(uadaptor); + checkGraphArcMap(uadaptor); + + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n1), 2); + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n1), 2); + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n2), 3); + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n2), 1); + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n3), 2); + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n3), 2); + checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n4), 1); + checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n4), 3); +} + +int main(int, const char **) { + // Check the digraph adaptors (using ListDigraph) + checkReverseDigraph(); + checkSubDigraph(); + checkFilterNodes1(); + checkFilterArcs(); + checkUndirector(); + checkResidualDigraph(); + checkSplitNodes(); + + // Check the graph adaptors (using ListGraph) + checkSubGraph(); + checkFilterNodes2(); + checkFilterEdges(); + checkOrienter(); + + // Combine adaptors (using GridGraph) + checkCombiningAdaptors(); + + return 0; +} diff --git a/lemon/test/bellman_ford_test.cc b/lemon/test/bellman_ford_test.cc new file mode 100644 index 0000000..2f6c7dd --- /dev/null +++ b/lemon/test/bellman_ford_test.cc @@ -0,0 +1,285 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "graph_test.h" +#include "test_tools.h" + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "@arcs\n" + " length\n" + "0 1 3\n" + "1 2 -3\n" + "1 2 -5\n" + "1 3 -2\n" + "0 2 -1\n" + "1 2 -4\n" + "0 3 2\n" + "4 2 -5\n" + "2 3 1\n" + "@attributes\n" + "source 0\n" + "target 3\n"; + + +void checkBellmanFordCompile() +{ + typedef int Value; + typedef concepts::Digraph Digraph; + typedef concepts::ReadMap LengthMap; + typedef BellmanFord BF; + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + + Digraph gr; + Node s, t, n; + Arc e; + Value l; + int k=3; + bool b; + BF::DistMap d(gr); + BF::PredMap p(gr); + LengthMap length; + concepts::Path pp; + + { + BF bf_test(gr,length); + const BF& const_bf_test = bf_test; + + bf_test.run(s); + bf_test.run(s,k); + + bf_test.init(); + bf_test.addSource(s); + bf_test.addSource(s, 1); + b = bf_test.processNextRound(); + b = bf_test.processNextWeakRound(); + + bf_test.start(); + bf_test.checkedStart(); + bf_test.limitedStart(k); + + l = const_bf_test.dist(t); + e = const_bf_test.predArc(t); + s = const_bf_test.predNode(t); + b = const_bf_test.reached(t); + d = const_bf_test.distMap(); + p = const_bf_test.predMap(); + pp = const_bf_test.path(t); + pp = const_bf_test.negativeCycle(); + + for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {} + } + { + BF::SetPredMap > + ::SetDistMap > + ::SetOperationTraits > + ::Create bf_test(gr,length); + + LengthMap length_map; + concepts::ReadWriteMap pred_map; + concepts::ReadWriteMap dist_map; + + bf_test + .lengthMap(length_map) + .predMap(pred_map) + .distMap(dist_map); + + bf_test.run(s); + bf_test.run(s,k); + + bf_test.init(); + bf_test.addSource(s); + bf_test.addSource(s, 1); + b = bf_test.processNextRound(); + b = bf_test.processNextWeakRound(); + + bf_test.start(); + bf_test.checkedStart(); + bf_test.limitedStart(k); + + l = bf_test.dist(t); + e = bf_test.predArc(t); + s = bf_test.predNode(t); + b = bf_test.reached(t); + pp = bf_test.path(t); + pp = bf_test.negativeCycle(); + } +} + +void checkBellmanFordFunctionCompile() +{ + typedef int Value; + typedef concepts::Digraph Digraph; + typedef Digraph::Arc Arc; + typedef Digraph::Node Node; + typedef concepts::ReadMap LengthMap; + + Digraph g; + bool b; + bellmanFord(g,LengthMap()).run(Node()); + b = bellmanFord(g,LengthMap()).run(Node(),Node()); + bellmanFord(g,LengthMap()) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .run(Node()); + b=bellmanFord(g,LengthMap()) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .path(concepts::Path()) + .dist(Value()) + .run(Node(),Node()); +} + + +template +void checkBellmanFord() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + typedef typename Digraph::template ArcMap LengthMap; + + Digraph gr; + Node s, t; + LengthMap length(gr); + + std::istringstream input(test_lgf); + digraphReader(gr, input). + arcMap("length", length). + node("source", s). + node("target", t). + run(); + + BellmanFord + bf(gr, length); + bf.run(s); + Path p = bf.path(t); + + check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path."); + check(p.length() == 3, "path() found a wrong path."); + check(checkPath(gr, p), "path() found a wrong path."); + check(pathSource(gr, p) == s, "path() found a wrong path."); + check(pathTarget(gr, p) == t, "path() found a wrong path."); + + ListPath path; + Value dist; + bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t); + + check(reached && dist == -1, "Bellman-Ford found a wrong path."); + check(path.length() == 3, "path() found a wrong path."); + check(checkPath(gr, path), "path() found a wrong path."); + check(pathSource(gr, path) == s, "path() found a wrong path."); + check(pathTarget(gr, path) == t, "path() found a wrong path."); + + for(ArcIt e(gr); e!=INVALID; ++e) { + Node u=gr.source(e); + Node v=gr.target(e); + check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]), + "Wrong output. dist(target)-dist(source)-arc_length=" << + bf.dist(v) - bf.dist(u) - length[e]); + } + + for(NodeIt v(gr); v!=INVALID; ++v) { + if (bf.reached(v)) { + check(v==s || bf.predArc(v)!=INVALID, "Wrong tree."); + if (bf.predArc(v)!=INVALID ) { + Arc e=bf.predArc(v); + Node u=gr.source(e); + check(u==bf.predNode(v),"Wrong tree."); + check(bf.dist(v) - bf.dist(u) == length[e], + "Wrong distance! Difference: " << + bf.dist(v) - bf.dist(u) - length[e]); + } + } + } +} + +void checkBellmanFordNegativeCycle() { + DIGRAPH_TYPEDEFS(SmartDigraph); + + SmartDigraph gr; + IntArcMap length(gr); + + Node n1 = gr.addNode(); + Node n2 = gr.addNode(); + Node n3 = gr.addNode(); + Node n4 = gr.addNode(); + + Arc a1 = gr.addArc(n1, n2); + Arc a2 = gr.addArc(n2, n2); + + length[a1] = 2; + length[a2] = -1; + + { + BellmanFord bf(gr, length); + bf.run(n1); + StaticPath p = bf.negativeCycle(); + check(p.length() == 1 && p.front() == p.back() && p.front() == a2, + "Wrong negative cycle."); + } + + length[a2] = 0; + + { + BellmanFord bf(gr, length); + bf.run(n1); + check(bf.negativeCycle().empty(), + "Negative cycle should not be found."); + } + + length[gr.addArc(n1, n3)] = 5; + length[gr.addArc(n4, n3)] = 1; + length[gr.addArc(n2, n4)] = 2; + length[gr.addArc(n3, n2)] = -4; + + { + BellmanFord bf(gr, length); + bf.init(); + bf.addSource(n1); + for (int i = 0; i < 4; ++i) { + check(bf.negativeCycle().empty(), + "Negative cycle should not be found."); + bf.processNextRound(); + } + StaticPath p = bf.negativeCycle(); + check(p.length() == 3, "Wrong negative cycle."); + check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1, + "Wrong negative cycle."); + } +} + +int main() { + checkBellmanFord(); + checkBellmanFord(); + checkBellmanFordNegativeCycle(); + return 0; +} diff --git a/lemon/test/bfs_test.cc b/lemon/test/bfs_test.cc new file mode 100644 index 0000000..a1c16b3 --- /dev/null +++ b/lemon/test/bfs_test.cc @@ -0,0 +1,236 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "graph_test.h" +#include "test_tools.h" + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "@arcs\n" + " label\n" + "0 1 0\n" + "1 2 1\n" + "2 3 2\n" + "3 4 3\n" + "0 3 4\n" + "0 3 5\n" + "5 2 6\n" + "@attributes\n" + "source 0\n" + "target 4\n"; + +void checkBfsCompile() +{ + typedef concepts::Digraph Digraph; + typedef Bfs BType; + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + + Digraph G; + Node s, t, n; + Arc e; + int l, i; + bool b; + BType::DistMap d(G); + BType::PredMap p(G); + Path pp; + concepts::ReadMap nm; + + { + BType bfs_test(G); + const BType& const_bfs_test = bfs_test; + + bfs_test.run(s); + bfs_test.run(s,t); + bfs_test.run(); + + bfs_test.init(); + bfs_test.addSource(s); + n = bfs_test.processNextNode(); + n = bfs_test.processNextNode(t, b); + n = bfs_test.processNextNode(nm, n); + n = const_bfs_test.nextNode(); + b = const_bfs_test.emptyQueue(); + i = const_bfs_test.queueSize(); + + bfs_test.start(); + bfs_test.start(t); + bfs_test.start(nm); + + l = const_bfs_test.dist(t); + e = const_bfs_test.predArc(t); + s = const_bfs_test.predNode(t); + b = const_bfs_test.reached(t); + d = const_bfs_test.distMap(); + p = const_bfs_test.predMap(); + pp = const_bfs_test.path(t); + } + { + BType + ::SetPredMap > + ::SetDistMap > + ::SetReachedMap > + ::SetStandardProcessedMap + ::SetProcessedMap > + ::Create bfs_test(G); + + concepts::ReadWriteMap pred_map; + concepts::ReadWriteMap dist_map; + concepts::ReadWriteMap reached_map; + concepts::WriteMap processed_map; + + bfs_test + .predMap(pred_map) + .distMap(dist_map) + .reachedMap(reached_map) + .processedMap(processed_map); + + bfs_test.run(s); + bfs_test.run(s,t); + bfs_test.run(); + + bfs_test.init(); + bfs_test.addSource(s); + n = bfs_test.processNextNode(); + n = bfs_test.processNextNode(t, b); + n = bfs_test.processNextNode(nm, n); + n = bfs_test.nextNode(); + b = bfs_test.emptyQueue(); + i = bfs_test.queueSize(); + + bfs_test.start(); + bfs_test.start(t); + bfs_test.start(nm); + + l = bfs_test.dist(t); + e = bfs_test.predArc(t); + s = bfs_test.predNode(t); + b = bfs_test.reached(t); + pp = bfs_test.path(t); + } +} + +void checkBfsFunctionCompile() +{ + typedef int VType; + typedef concepts::Digraph Digraph; + typedef Digraph::Arc Arc; + typedef Digraph::Node Node; + + Digraph g; + bool b; + bfs(g).run(Node()); + b=bfs(g).run(Node(),Node()); + bfs(g).run(); + bfs(g) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .reachedMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .run(Node()); + b=bfs(g) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .reachedMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .path(concepts::Path()) + .dist(VType()) + .run(Node(),Node()); + bfs(g) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .reachedMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .run(); +} + +template +void checkBfs() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + Digraph G; + Node s, t; + + std::istringstream input(test_lgf); + digraphReader(G, input). + node("source", s). + node("target", t). + run(); + + Bfs bfs_test(G); + bfs_test.run(s); + + check(bfs_test.dist(t)==2,"Bfs found a wrong path."); + + Path p = bfs_test.path(t); + check(p.length()==2,"path() found a wrong path."); + check(checkPath(G, p),"path() found a wrong path."); + check(pathSource(G, p) == s,"path() found a wrong path."); + check(pathTarget(G, p) == t,"path() found a wrong path."); + + + for(ArcIt a(G); a!=INVALID; ++a) { + Node u=G.source(a); + Node v=G.target(a); + check( !bfs_test.reached(u) || + (bfs_test.dist(v) <= bfs_test.dist(u)+1), + "Wrong output. " << G.id(u) << "->" << G.id(v)); + } + + for(NodeIt v(G); v!=INVALID; ++v) { + if (bfs_test.reached(v)) { + check(v==s || bfs_test.predArc(v)!=INVALID, "Wrong tree."); + if (bfs_test.predArc(v)!=INVALID ) { + Arc a=bfs_test.predArc(v); + Node u=G.source(a); + check(u==bfs_test.predNode(v),"Wrong tree."); + check(bfs_test.dist(v) - bfs_test.dist(u) == 1, + "Wrong distance. Difference: " + << std::abs(bfs_test.dist(v) - bfs_test.dist(u) - 1)); + } + } + } + + { + NullMap myPredMap; + bfs(G).predMap(myPredMap).run(s); + } +} + +int main() +{ + checkBfs(); + checkBfs(); + return 0; +} diff --git a/lemon/test/circulation_test.cc b/lemon/test/circulation_test.cc new file mode 100644 index 0000000..99dc764 --- /dev/null +++ b/lemon/test/circulation_test.cc @@ -0,0 +1,168 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include "test_tools.h" +#include +#include +#include +#include +#include + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "@arcs\n" + " lcap ucap\n" + "0 1 2 10\n" + "0 2 2 6\n" + "1 3 4 7\n" + "1 4 0 5\n" + "2 4 1 3\n" + "3 5 3 8\n" + "4 5 3 7\n" + "@attributes\n" + "source 0\n" + "sink 5\n"; + +void checkCirculationCompile() +{ + typedef int VType; + typedef concepts::Digraph Digraph; + + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + typedef concepts::ReadMap CapMap; + typedef concepts::ReadMap SupplyMap; + typedef concepts::ReadWriteMap FlowMap; + typedef concepts::WriteMap BarrierMap; + + typedef Elevator Elev; + typedef LinkedElevator LinkedElev; + + Digraph g; + Node n; + Arc a; + CapMap lcap, ucap; + SupplyMap supply; + FlowMap flow; + BarrierMap bar; + VType v; + bool b; + + typedef Circulation + ::SetFlowMap + ::SetElevator + ::SetStandardElevator + ::Create CirculationType; + CirculationType circ_test(g, lcap, ucap, supply); + const CirculationType& const_circ_test = circ_test; + + circ_test + .lowerMap(lcap) + .upperMap(ucap) + .supplyMap(supply) + .flowMap(flow); + + const CirculationType::Elevator& elev = const_circ_test.elevator(); + circ_test.elevator(const_cast(elev)); + CirculationType::Tolerance tol = const_circ_test.tolerance(); + circ_test.tolerance(tol); + + circ_test.init(); + circ_test.greedyInit(); + circ_test.start(); + circ_test.run(); + + v = const_circ_test.flow(a); + const FlowMap& fm = const_circ_test.flowMap(); + b = const_circ_test.barrier(n); + const_circ_test.barrierMap(bar); + + ignore_unused_variable_warning(fm); +} + +template +void checkCirculation(const G& g, const LM& lm, const UM& um, + const DM& dm, bool find) +{ + Circulation circ(g, lm, um, dm); + bool ret = circ.run(); + if (find) { + check(ret, "A feasible solution should have been found."); + check(circ.checkFlow(), "The found flow is corrupt."); + check(!circ.checkBarrier(), "A barrier should not have been found."); + } else { + check(!ret, "A feasible solution should not have been found."); + check(circ.checkBarrier(), "The found barrier is corrupt."); + } +} + +int main (int, char*[]) +{ + typedef ListDigraph Digraph; + DIGRAPH_TYPEDEFS(Digraph); + + Digraph g; + IntArcMap lo(g), up(g); + IntNodeMap delta(g, 0); + Node s, t; + + std::istringstream input(test_lgf); + DigraphReader(g,input). + arcMap("lcap", lo). + arcMap("ucap", up). + node("source",s). + node("sink",t). + run(); + + delta[s] = 7; delta[t] = -7; + checkCirculation(g, lo, up, delta, true); + + delta[s] = 13; delta[t] = -13; + checkCirculation(g, lo, up, delta, true); + + delta[s] = 6; delta[t] = -6; + checkCirculation(g, lo, up, delta, false); + + delta[s] = 14; delta[t] = -14; + checkCirculation(g, lo, up, delta, false); + + delta[s] = 7; delta[t] = -13; + checkCirculation(g, lo, up, delta, true); + + delta[s] = 5; delta[t] = -15; + checkCirculation(g, lo, up, delta, true); + + delta[s] = 10; delta[t] = -11; + checkCirculation(g, lo, up, delta, true); + + delta[s] = 11; delta[t] = -10; + checkCirculation(g, lo, up, delta, false); + + return 0; +} diff --git a/lemon/test/connectivity_test.cc b/lemon/test/connectivity_test.cc new file mode 100644 index 0000000..96c47c5 --- /dev/null +++ b/lemon/test/connectivity_test.cc @@ -0,0 +1,297 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; + + +int main() +{ + typedef ListDigraph Digraph; + typedef Undirector Graph; + + { + Digraph d; + Digraph::NodeMap order(d); + Graph g(d); + + check(stronglyConnected(d), "The empty digraph is strongly connected"); + check(countStronglyConnectedComponents(d) == 0, + "The empty digraph has 0 strongly connected component"); + check(connected(g), "The empty graph is connected"); + check(countConnectedComponents(g) == 0, + "The empty graph has 0 connected component"); + + check(biNodeConnected(g), "The empty graph is bi-node-connected"); + check(countBiNodeConnectedComponents(g) == 0, + "The empty graph has 0 bi-node-connected component"); + check(biEdgeConnected(g), "The empty graph is bi-edge-connected"); + check(countBiEdgeConnectedComponents(g) == 0, + "The empty graph has 0 bi-edge-connected component"); + + check(dag(d), "The empty digraph is DAG."); + check(checkedTopologicalSort(d, order), "The empty digraph is DAG."); + check(loopFree(d), "The empty digraph is loop-free."); + check(parallelFree(d), "The empty digraph is parallel-free."); + check(simpleGraph(d), "The empty digraph is simple."); + + check(acyclic(g), "The empty graph is acyclic."); + check(tree(g), "The empty graph is tree."); + check(bipartite(g), "The empty graph is bipartite."); + check(loopFree(g), "The empty graph is loop-free."); + check(parallelFree(g), "The empty graph is parallel-free."); + check(simpleGraph(g), "The empty graph is simple."); + } + + { + Digraph d; + Digraph::NodeMap order(d); + Graph g(d); + Digraph::Node n = d.addNode(); + + check(stronglyConnected(d), "This digraph is strongly connected"); + check(countStronglyConnectedComponents(d) == 1, + "This digraph has 1 strongly connected component"); + check(connected(g), "This graph is connected"); + check(countConnectedComponents(g) == 1, + "This graph has 1 connected component"); + + check(biNodeConnected(g), "This graph is bi-node-connected"); + check(countBiNodeConnectedComponents(g) == 0, + "This graph has 0 bi-node-connected component"); + check(biEdgeConnected(g), "This graph is bi-edge-connected"); + check(countBiEdgeConnectedComponents(g) == 1, + "This graph has 1 bi-edge-connected component"); + + check(dag(d), "This digraph is DAG."); + check(checkedTopologicalSort(d, order), "This digraph is DAG."); + check(loopFree(d), "This digraph is loop-free."); + check(parallelFree(d), "This digraph is parallel-free."); + check(simpleGraph(d), "This digraph is simple."); + + check(acyclic(g), "This graph is acyclic."); + check(tree(g), "This graph is tree."); + check(bipartite(g), "This graph is bipartite."); + check(loopFree(g), "This graph is loop-free."); + check(parallelFree(g), "This graph is parallel-free."); + check(simpleGraph(g), "This graph is simple."); + } + + { + Digraph d; + Digraph::NodeMap order(d); + Graph g(d); + + Digraph::Node n1 = d.addNode(); + Digraph::Node n2 = d.addNode(); + Digraph::Node n3 = d.addNode(); + Digraph::Node n4 = d.addNode(); + Digraph::Node n5 = d.addNode(); + Digraph::Node n6 = d.addNode(); + + d.addArc(n1, n3); + d.addArc(n3, n2); + d.addArc(n2, n1); + d.addArc(n4, n2); + d.addArc(n4, n3); + d.addArc(n5, n6); + d.addArc(n6, n5); + + check(!stronglyConnected(d), "This digraph is not strongly connected"); + check(countStronglyConnectedComponents(d) == 3, + "This digraph has 3 strongly connected components"); + check(!connected(g), "This graph is not connected"); + check(countConnectedComponents(g) == 2, + "This graph has 2 connected components"); + + check(!dag(d), "This digraph is not DAG."); + check(!checkedTopologicalSort(d, order), "This digraph is not DAG."); + check(loopFree(d), "This digraph is loop-free."); + check(parallelFree(d), "This digraph is parallel-free."); + check(simpleGraph(d), "This digraph is simple."); + + check(!acyclic(g), "This graph is not acyclic."); + check(!tree(g), "This graph is not tree."); + check(!bipartite(g), "This graph is not bipartite."); + check(loopFree(g), "This graph is loop-free."); + check(!parallelFree(g), "This graph is not parallel-free."); + check(!simpleGraph(g), "This graph is not simple."); + + d.addArc(n3, n3); + + check(!loopFree(d), "This digraph is not loop-free."); + check(!loopFree(g), "This graph is not loop-free."); + check(!simpleGraph(d), "This digraph is not simple."); + + d.addArc(n3, n2); + + check(!parallelFree(d), "This digraph is not parallel-free."); + } + + { + Digraph d; + Digraph::ArcMap cutarcs(d, false); + Graph g(d); + + Digraph::Node n1 = d.addNode(); + Digraph::Node n2 = d.addNode(); + Digraph::Node n3 = d.addNode(); + Digraph::Node n4 = d.addNode(); + Digraph::Node n5 = d.addNode(); + Digraph::Node n6 = d.addNode(); + Digraph::Node n7 = d.addNode(); + Digraph::Node n8 = d.addNode(); + + d.addArc(n1, n2); + d.addArc(n5, n1); + d.addArc(n2, n8); + d.addArc(n8, n5); + d.addArc(n6, n4); + d.addArc(n4, n6); + d.addArc(n2, n5); + d.addArc(n1, n8); + d.addArc(n6, n7); + d.addArc(n7, n6); + + check(!stronglyConnected(d), "This digraph is not strongly connected"); + check(countStronglyConnectedComponents(d) == 3, + "This digraph has 3 strongly connected components"); + Digraph::NodeMap scomp1(d); + check(stronglyConnectedComponents(d, scomp1) == 3, + "This digraph has 3 strongly connected components"); + check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] && + scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()"); + check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] && + scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()"); + check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7], + "Wrong stronglyConnectedComponents()"); + Digraph::ArcMap scut1(d, false); + check(stronglyConnectedCutArcs(d, scut1) == 0, + "This digraph has 0 strongly connected cut arc."); + for (Digraph::ArcIt a(d); a != INVALID; ++a) { + check(!scut1[a], "Wrong stronglyConnectedCutArcs()"); + } + + check(!connected(g), "This graph is not connected"); + check(countConnectedComponents(g) == 3, + "This graph has 3 connected components"); + Graph::NodeMap comp(g); + check(connectedComponents(g, comp) == 3, + "This graph has 3 connected components"); + check(comp[n1] != comp[n3] && comp[n1] != comp[n4] && + comp[n3] != comp[n4], "Wrong connectedComponents()"); + check(comp[n1] == comp[n2] && comp[n1] == comp[n5] && + comp[n1] == comp[n8], "Wrong connectedComponents()"); + check(comp[n4] == comp[n6] && comp[n4] == comp[n7], + "Wrong connectedComponents()"); + + cutarcs[d.addArc(n3, n1)] = true; + cutarcs[d.addArc(n3, n5)] = true; + cutarcs[d.addArc(n3, n8)] = true; + cutarcs[d.addArc(n8, n6)] = true; + cutarcs[d.addArc(n8, n7)] = true; + + check(!stronglyConnected(d), "This digraph is not strongly connected"); + check(countStronglyConnectedComponents(d) == 3, + "This digraph has 3 strongly connected components"); + Digraph::NodeMap scomp2(d); + check(stronglyConnectedComponents(d, scomp2) == 3, + "This digraph has 3 strongly connected components"); + check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()"); + check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 && + scomp2[n8] == 1, "Wrong stronglyConnectedComponents()"); + check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2, + "Wrong stronglyConnectedComponents()"); + Digraph::ArcMap scut2(d, false); + check(stronglyConnectedCutArcs(d, scut2) == 5, + "This digraph has 5 strongly connected cut arcs."); + for (Digraph::ArcIt a(d); a != INVALID; ++a) { + check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()"); + } + } + + { + // DAG example for topological sort from the book New Algorithms + // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein) + Digraph d; + Digraph::NodeMap order(d); + + Digraph::Node belt = d.addNode(); + Digraph::Node trousers = d.addNode(); + Digraph::Node necktie = d.addNode(); + Digraph::Node coat = d.addNode(); + Digraph::Node socks = d.addNode(); + Digraph::Node shirt = d.addNode(); + Digraph::Node shoe = d.addNode(); + Digraph::Node watch = d.addNode(); + Digraph::Node pants = d.addNode(); + + d.addArc(socks, shoe); + d.addArc(pants, shoe); + d.addArc(pants, trousers); + d.addArc(trousers, shoe); + d.addArc(trousers, belt); + d.addArc(belt, coat); + d.addArc(shirt, belt); + d.addArc(shirt, necktie); + d.addArc(necktie, coat); + + check(dag(d), "This digraph is DAG."); + topologicalSort(d, order); + for (Digraph::ArcIt a(d); a != INVALID; ++a) { + check(order[d.source(a)] < order[d.target(a)], + "Wrong topologicalSort()"); + } + } + + { + ListGraph g; + ListGraph::NodeMap map(g); + + ListGraph::Node n1 = g.addNode(); + ListGraph::Node n2 = g.addNode(); + ListGraph::Node n3 = g.addNode(); + ListGraph::Node n4 = g.addNode(); + ListGraph::Node n5 = g.addNode(); + ListGraph::Node n6 = g.addNode(); + ListGraph::Node n7 = g.addNode(); + + g.addEdge(n1, n3); + g.addEdge(n1, n4); + g.addEdge(n2, n5); + g.addEdge(n3, n6); + g.addEdge(n4, n6); + g.addEdge(n4, n7); + g.addEdge(n5, n7); + + check(bipartite(g), "This graph is bipartite"); + check(bipartitePartitions(g, map), "This graph is bipartite"); + + check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7], + "Wrong bipartitePartitions()"); + check(map[n3] == map[n4] && map[n3] == map[n5], + "Wrong bipartitePartitions()"); + } + + return 0; +} diff --git a/lemon/test/counter_test.cc b/lemon/test/counter_test.cc new file mode 100644 index 0000000..df31dd4 --- /dev/null +++ b/lemon/test/counter_test.cc @@ -0,0 +1,118 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include + +#include "test/test_tools.h" + +using namespace lemon; + +template +void bubbleSort(std::vector& v) { + std::stringstream s1, s2, s3; + { + Counter op("Bubble Sort - Operations: ", s1); + Counter::SubCounter as(op, "Assignments: ", s2); + Counter::SubCounter co(op, "Comparisons: ", s3); + for (int i = v.size()-1; i > 0; --i) { + for (int j = 0; j < i; ++j) { + if (v[j] > v[j+1]) { + T tmp = v[j]; + v[j] = v[j+1]; + v[j+1] = tmp; + as += 3; + } + ++co; + } + } + } + check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter"); + check(s2.str() == "Assignments: 57\n", "Wrong subcounter"); + check(s3.str() == "Comparisons: 45\n", "Wrong subcounter"); +} + +template +void insertionSort(std::vector& v) { + std::stringstream s1, s2, s3; + { + Counter op("Insertion Sort - Operations: ", s1); + Counter::SubCounter as(op, "Assignments: ", s2); + Counter::SubCounter co(op, "Comparisons: ", s3); + for (int i = 1; i < int(v.size()); ++i) { + T value = v[i]; + ++as; + int j = i; + while (j > 0 && v[j-1] > value) { + v[j] = v[j-1]; + --j; + ++co; ++as; + } + v[j] = value; + ++as; + } + } + check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter"); + check(s2.str() == "Assignments: 37\n", "Wrong subcounter"); + check(s3.str() == "Comparisons: 19\n", "Wrong subcounter"); +} + +template +void counterTest(bool output) { + std::stringstream s1, s2, s3; + { + MyCounter c("Main Counter: ", s1); + c++; + typename MyCounter::SubCounter d(c, "SubCounter: ", s2); + d++; + typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3); + e++; + d+=3; + c-=4; + e-=2; + c.reset(2); + c.reset(); + } + if (output) { + check(s1.str() == "Main Counter: 3\n", "Wrong Counter"); + check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter"); + check(s3.str() == "", "Wrong NoSubCounter"); + } else { + check(s1.str() == "", "Wrong NoCounter"); + check(s2.str() == "", "Wrong SubCounter"); + check(s3.str() == "", "Wrong NoSubCounter"); + } +} + +void init(std::vector& v) { + v[0] = 10; v[1] = 60; v[2] = 20; v[3] = 90; v[4] = 100; + v[5] = 80; v[6] = 40; v[7] = 30; v[8] = 50; v[9] = 70; +} + +int main() +{ + counterTest(true); + counterTest(false); + + std::vector x(10); + init(x); bubbleSort(x); + init(x); insertionSort(x); + + return 0; +} diff --git a/lemon/test/dfs_test.cc b/lemon/test/dfs_test.cc new file mode 100644 index 0000000..36f6b0e --- /dev/null +++ b/lemon/test/dfs_test.cc @@ -0,0 +1,234 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "graph_test.h" +#include "test_tools.h" + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "@arcs\n" + " label\n" + "0 1 0\n" + "1 2 1\n" + "2 3 2\n" + "1 4 3\n" + "4 2 4\n" + "4 5 5\n" + "5 0 6\n" + "6 3 7\n" + "@attributes\n" + "source 0\n" + "target 5\n" + "source1 6\n" + "target1 3\n"; + + +void checkDfsCompile() +{ + typedef concepts::Digraph Digraph; + typedef Dfs DType; + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + + Digraph G; + Node s, t; + Arc e; + int l, i; + bool b; + DType::DistMap d(G); + DType::PredMap p(G); + Path pp; + concepts::ReadMap am; + + { + DType dfs_test(G); + const DType& const_dfs_test = dfs_test; + + dfs_test.run(s); + dfs_test.run(s,t); + dfs_test.run(); + + dfs_test.init(); + dfs_test.addSource(s); + e = dfs_test.processNextArc(); + e = const_dfs_test.nextArc(); + b = const_dfs_test.emptyQueue(); + i = const_dfs_test.queueSize(); + + dfs_test.start(); + dfs_test.start(t); + dfs_test.start(am); + + l = const_dfs_test.dist(t); + e = const_dfs_test.predArc(t); + s = const_dfs_test.predNode(t); + b = const_dfs_test.reached(t); + d = const_dfs_test.distMap(); + p = const_dfs_test.predMap(); + pp = const_dfs_test.path(t); + } + { + DType + ::SetPredMap > + ::SetDistMap > + ::SetReachedMap > + ::SetStandardProcessedMap + ::SetProcessedMap > + ::Create dfs_test(G); + + concepts::ReadWriteMap pred_map; + concepts::ReadWriteMap dist_map; + concepts::ReadWriteMap reached_map; + concepts::WriteMap processed_map; + + dfs_test + .predMap(pred_map) + .distMap(dist_map) + .reachedMap(reached_map) + .processedMap(processed_map); + + dfs_test.run(s); + dfs_test.run(s,t); + dfs_test.run(); + dfs_test.init(); + + dfs_test.addSource(s); + e = dfs_test.processNextArc(); + e = dfs_test.nextArc(); + b = dfs_test.emptyQueue(); + i = dfs_test.queueSize(); + + dfs_test.start(); + dfs_test.start(t); + dfs_test.start(am); + + l = dfs_test.dist(t); + e = dfs_test.predArc(t); + s = dfs_test.predNode(t); + b = dfs_test.reached(t); + pp = dfs_test.path(t); + } +} + +void checkDfsFunctionCompile() +{ + typedef int VType; + typedef concepts::Digraph Digraph; + typedef Digraph::Arc Arc; + typedef Digraph::Node Node; + + Digraph g; + bool b; + dfs(g).run(Node()); + b=dfs(g).run(Node(),Node()); + dfs(g).run(); + dfs(g) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .reachedMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .run(Node()); + b=dfs(g) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .reachedMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .path(concepts::Path()) + .dist(VType()) + .run(Node(),Node()); + dfs(g) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .reachedMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .run(); +} + +template +void checkDfs() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + Digraph G; + Node s, t; + Node s1, t1; + + std::istringstream input(test_lgf); + digraphReader(G, input). + node("source", s). + node("target", t). + node("source1", s1). + node("target1", t1). + run(); + + Dfs dfs_test(G); + dfs_test.run(s); + + Path p = dfs_test.path(t); + check(p.length() == dfs_test.dist(t),"path() found a wrong path."); + check(checkPath(G, p),"path() found a wrong path."); + check(pathSource(G, p) == s,"path() found a wrong path."); + check(pathTarget(G, p) == t,"path() found a wrong path."); + + for(NodeIt v(G); v!=INVALID; ++v) { + if (dfs_test.reached(v)) { + check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree."); + if (dfs_test.predArc(v)!=INVALID ) { + Arc e=dfs_test.predArc(v); + Node u=G.source(e); + check(u==dfs_test.predNode(v),"Wrong tree."); + check(dfs_test.dist(v) - dfs_test.dist(u) == 1, + "Wrong distance. (" << dfs_test.dist(u) << "->" + << dfs_test.dist(v) << ")"); + } + } + } + + { + Dfs dfs(G); + check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6."); + } + + { + NullMap myPredMap; + dfs(G).predMap(myPredMap).run(s); + } +} + +int main() +{ + checkDfs(); + checkDfs(); + return 0; +} diff --git a/lemon/test/digraph_test.cc b/lemon/test/digraph_test.cc new file mode 100644 index 0000000..3c5e896 --- /dev/null +++ b/lemon/test/digraph_test.cc @@ -0,0 +1,562 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include + +#include "test_tools.h" +#include "graph_test.h" + +using namespace lemon; +using namespace lemon::concepts; + +template +void checkDigraphBuild() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + Digraph G; + + checkGraphNodeList(G, 0); + checkGraphArcList(G, 0); + + G.reserveNode(3); + G.reserveArc(4); + + Node + n1 = G.addNode(), + n2 = G.addNode(), + n3 = G.addNode(); + checkGraphNodeList(G, 3); + checkGraphArcList(G, 0); + + Arc a1 = G.addArc(n1, n2); + check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc"); + checkGraphNodeList(G, 3); + checkGraphArcList(G, 1); + + checkGraphOutArcList(G, n1, 1); + checkGraphOutArcList(G, n2, 0); + checkGraphOutArcList(G, n3, 0); + + checkGraphInArcList(G, n1, 0); + checkGraphInArcList(G, n2, 1); + checkGraphInArcList(G, n3, 0); + + checkGraphConArcList(G, 1); + + Arc a2 = G.addArc(n2, n1), + a3 = G.addArc(n2, n3), + a4 = G.addArc(n2, n3); + + checkGraphNodeList(G, 3); + checkGraphArcList(G, 4); + + checkGraphOutArcList(G, n1, 1); + checkGraphOutArcList(G, n2, 3); + checkGraphOutArcList(G, n3, 0); + + checkGraphInArcList(G, n1, 1); + checkGraphInArcList(G, n2, 1); + checkGraphInArcList(G, n3, 2); + + checkGraphConArcList(G, 4); + + checkNodeIds(G); + checkArcIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); +} + +template +void checkDigraphSplit() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + Digraph G; + Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode(); + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1), + a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3); + + Node n4 = G.split(n2); + + check(G.target(OutArcIt(G, n2)) == n4 && + G.source(InArcIt(G, n4)) == n2, + "Wrong split."); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 5); + + checkGraphOutArcList(G, n1, 1); + checkGraphOutArcList(G, n2, 1); + checkGraphOutArcList(G, n3, 0); + checkGraphOutArcList(G, n4, 3); + + checkGraphInArcList(G, n1, 1); + checkGraphInArcList(G, n2, 1); + checkGraphInArcList(G, n3, 2); + checkGraphInArcList(G, n4, 1); + + checkGraphConArcList(G, 5); +} + +template +void checkDigraphAlter() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + Digraph G; + Node n1 = G.addNode(), n2 = G.addNode(), + n3 = G.addNode(), n4 = G.addNode(); + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1), + a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3), + a5 = G.addArc(n2, n4); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 5); + + // Check changeSource() and changeTarget() + G.changeTarget(a4, n1); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 5); + + checkGraphOutArcList(G, n1, 1); + checkGraphOutArcList(G, n2, 1); + checkGraphOutArcList(G, n3, 0); + checkGraphOutArcList(G, n4, 3); + + checkGraphInArcList(G, n1, 2); + checkGraphInArcList(G, n2, 1); + checkGraphInArcList(G, n3, 1); + checkGraphInArcList(G, n4, 1); + + checkGraphConArcList(G, 5); + + G.changeSource(a4, n3); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 5); + + checkGraphOutArcList(G, n1, 1); + checkGraphOutArcList(G, n2, 1); + checkGraphOutArcList(G, n3, 1); + checkGraphOutArcList(G, n4, 2); + + checkGraphInArcList(G, n1, 2); + checkGraphInArcList(G, n2, 1); + checkGraphInArcList(G, n3, 1); + checkGraphInArcList(G, n4, 1); + + checkGraphConArcList(G, 5); + + // Check contract() + G.contract(n2, n4, false); + + checkGraphNodeList(G, 3); + checkGraphArcList(G, 5); + + checkGraphOutArcList(G, n1, 1); + checkGraphOutArcList(G, n2, 3); + checkGraphOutArcList(G, n3, 1); + + checkGraphInArcList(G, n1, 2); + checkGraphInArcList(G, n2, 2); + checkGraphInArcList(G, n3, 1); + + checkGraphConArcList(G, 5); + + G.contract(n2, n1); + + checkGraphNodeList(G, 2); + checkGraphArcList(G, 3); + + checkGraphOutArcList(G, n2, 2); + checkGraphOutArcList(G, n3, 1); + + checkGraphInArcList(G, n2, 2); + checkGraphInArcList(G, n3, 1); + + checkGraphConArcList(G, 3); +} + +template +void checkDigraphErase() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + Digraph G; + Node n1 = G.addNode(), n2 = G.addNode(), + n3 = G.addNode(), n4 = G.addNode(); + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1), + a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1), + a5 = G.addArc(n2, n4); + + // Check arc deletion + G.erase(a1); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 4); + + checkGraphOutArcList(G, n1, 0); + checkGraphOutArcList(G, n2, 1); + checkGraphOutArcList(G, n3, 1); + checkGraphOutArcList(G, n4, 2); + + checkGraphInArcList(G, n1, 2); + checkGraphInArcList(G, n2, 0); + checkGraphInArcList(G, n3, 1); + checkGraphInArcList(G, n4, 1); + + checkGraphConArcList(G, 4); + + // Check node deletion + G.erase(n4); + + checkGraphNodeList(G, 3); + checkGraphArcList(G, 1); + + checkGraphOutArcList(G, n1, 0); + checkGraphOutArcList(G, n2, 0); + checkGraphOutArcList(G, n3, 1); + checkGraphOutArcList(G, n4, 0); + + checkGraphInArcList(G, n1, 1); + checkGraphInArcList(G, n2, 0); + checkGraphInArcList(G, n3, 0); + checkGraphInArcList(G, n4, 0); + + checkGraphConArcList(G, 1); +} + + +template +void checkDigraphSnapshot() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + Digraph G; + Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode(); + Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1), + a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3); + + typename Digraph::Snapshot snapshot(G); + + Node n = G.addNode(); + G.addArc(n3, n); + G.addArc(n, n3); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 6); + + snapshot.restore(); + + checkGraphNodeList(G, 3); + checkGraphArcList(G, 4); + + checkGraphOutArcList(G, n1, 1); + checkGraphOutArcList(G, n2, 3); + checkGraphOutArcList(G, n3, 0); + + checkGraphInArcList(G, n1, 1); + checkGraphInArcList(G, n2, 1); + checkGraphInArcList(G, n3, 2); + + checkGraphConArcList(G, 4); + + checkNodeIds(G); + checkArcIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); + + G.addNode(); + snapshot.save(G); + + G.addArc(G.addNode(), G.addNode()); + + snapshot.restore(); + snapshot.save(G); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 4); + + G.addArc(G.addNode(), G.addNode()); + + snapshot.restore(); + + checkGraphNodeList(G, 4); + checkGraphArcList(G, 4); +} + +void checkConcepts() { + { // Checking digraph components + checkConcept(); + + checkConcept, + IDableDigraphComponent<> >(); + + checkConcept, + IterableDigraphComponent<> >(); + + checkConcept, + MappableDigraphComponent<> >(); + } + { // Checking skeleton digraph + checkConcept(); + } + { // Checking ListDigraph + checkConcept(); + checkConcept, ListDigraph>(); + checkConcept, ListDigraph>(); + checkConcept, ListDigraph>(); + checkConcept, ListDigraph>(); + } + { // Checking SmartDigraph + checkConcept(); + checkConcept, SmartDigraph>(); + checkConcept, SmartDigraph>(); + checkConcept, SmartDigraph>(); + } + { // Checking StaticDigraph + checkConcept(); + checkConcept, StaticDigraph>(); + } + { // Checking FullDigraph + checkConcept(); + } +} + +template +void checkDigraphValidity() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + Digraph g; + + Node + n1 = g.addNode(), + n2 = g.addNode(), + n3 = g.addNode(); + + Arc + e1 = g.addArc(n1, n2), + e2 = g.addArc(n2, n3); + + check(g.valid(n1), "Wrong validity check"); + check(g.valid(e1), "Wrong validity check"); + + check(!g.valid(g.nodeFromId(-1)), "Wrong validity check"); + check(!g.valid(g.arcFromId(-1)), "Wrong validity check"); +} + +template +void checkDigraphValidityErase() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + Digraph g; + + Node + n1 = g.addNode(), + n2 = g.addNode(), + n3 = g.addNode(); + + Arc + e1 = g.addArc(n1, n2), + e2 = g.addArc(n2, n3); + + check(g.valid(n1), "Wrong validity check"); + check(g.valid(e1), "Wrong validity check"); + + g.erase(n1); + + check(!g.valid(n1), "Wrong validity check"); + check(g.valid(n2), "Wrong validity check"); + check(g.valid(n3), "Wrong validity check"); + check(!g.valid(e1), "Wrong validity check"); + check(g.valid(e2), "Wrong validity check"); + + check(!g.valid(g.nodeFromId(-1)), "Wrong validity check"); + check(!g.valid(g.arcFromId(-1)), "Wrong validity check"); +} + +void checkStaticDigraph() { + SmartDigraph g; + SmartDigraph::NodeMap nref(g); + SmartDigraph::ArcMap aref(g); + + StaticDigraph G; + + checkGraphNodeList(G, 0); + checkGraphArcList(G, 0); + + G.build(g, nref, aref); + + checkGraphNodeList(G, 0); + checkGraphArcList(G, 0); + + SmartDigraph::Node + n1 = g.addNode(), + n2 = g.addNode(), + n3 = g.addNode(); + + G.build(g, nref, aref); + + checkGraphNodeList(G, 3); + checkGraphArcList(G, 0); + + SmartDigraph::Arc a1 = g.addArc(n1, n2); + + G.build(g, nref, aref); + + check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2], + "Wrong arc or wrong references"); + checkGraphNodeList(G, 3); + checkGraphArcList(G, 1); + + checkGraphOutArcList(G, nref[n1], 1); + checkGraphOutArcList(G, nref[n2], 0); + checkGraphOutArcList(G, nref[n3], 0); + + checkGraphInArcList(G, nref[n1], 0); + checkGraphInArcList(G, nref[n2], 1); + checkGraphInArcList(G, nref[n3], 0); + + checkGraphConArcList(G, 1); + + SmartDigraph::Arc + a2 = g.addArc(n2, n1), + a3 = g.addArc(n2, n3), + a4 = g.addArc(n2, n3); + + digraphCopy(g, G).nodeRef(nref).run(); + + checkGraphNodeList(G, 3); + checkGraphArcList(G, 4); + + checkGraphOutArcList(G, nref[n1], 1); + checkGraphOutArcList(G, nref[n2], 3); + checkGraphOutArcList(G, nref[n3], 0); + + checkGraphInArcList(G, nref[n1], 1); + checkGraphInArcList(G, nref[n2], 1); + checkGraphInArcList(G, nref[n3], 2); + + checkGraphConArcList(G, 4); + + std::vector > arcs; + arcs.push_back(std::make_pair(0,1)); + arcs.push_back(std::make_pair(0,2)); + arcs.push_back(std::make_pair(1,3)); + arcs.push_back(std::make_pair(1,2)); + arcs.push_back(std::make_pair(3,0)); + arcs.push_back(std::make_pair(3,3)); + arcs.push_back(std::make_pair(4,2)); + arcs.push_back(std::make_pair(4,3)); + arcs.push_back(std::make_pair(4,1)); + + G.build(6, arcs.begin(), arcs.end()); + + checkGraphNodeList(G, 6); + checkGraphArcList(G, 9); + + checkGraphOutArcList(G, G.node(0), 2); + checkGraphOutArcList(G, G.node(1), 2); + checkGraphOutArcList(G, G.node(2), 0); + checkGraphOutArcList(G, G.node(3), 2); + checkGraphOutArcList(G, G.node(4), 3); + checkGraphOutArcList(G, G.node(5), 0); + + checkGraphInArcList(G, G.node(0), 1); + checkGraphInArcList(G, G.node(1), 2); + checkGraphInArcList(G, G.node(2), 3); + checkGraphInArcList(G, G.node(3), 3); + checkGraphInArcList(G, G.node(4), 0); + checkGraphInArcList(G, G.node(5), 0); + + checkGraphConArcList(G, 9); + + checkNodeIds(G); + checkArcIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); + + int n = G.nodeNum(); + int m = G.arcNum(); + check(G.index(G.node(n-1)) == n-1, "Wrong index."); + check(G.index(G.arc(m-1)) == m-1, "Wrong index."); +} + +void checkFullDigraph(int num) { + typedef FullDigraph Digraph; + DIGRAPH_TYPEDEFS(Digraph); + + Digraph G(num); + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size"); + + G.resize(num); + check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size"); + + checkGraphNodeList(G, num); + checkGraphArcList(G, num * num); + + for (NodeIt n(G); n != INVALID; ++n) { + checkGraphOutArcList(G, n, num); + checkGraphInArcList(G, n, num); + } + + checkGraphConArcList(G, num * num); + + checkNodeIds(G); + checkArcIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); + + for (int i = 0; i < G.nodeNum(); ++i) { + check(G.index(G(i)) == i, "Wrong index"); + } + + for (NodeIt s(G); s != INVALID; ++s) { + for (NodeIt t(G); t != INVALID; ++t) { + Arc a = G.arc(s, t); + check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup"); + } + } +} + +void checkDigraphs() { + { // Checking ListDigraph + checkDigraphBuild(); + checkDigraphSplit(); + checkDigraphAlter(); + checkDigraphErase(); + checkDigraphSnapshot(); + checkDigraphValidityErase(); + } + { // Checking SmartDigraph + checkDigraphBuild(); + checkDigraphSplit(); + checkDigraphSnapshot(); + checkDigraphValidity(); + } + { // Checking StaticDigraph + checkStaticDigraph(); + } + { // Checking FullDigraph + checkFullDigraph(8); + } +} + +int main() { + checkDigraphs(); + checkConcepts(); + return 0; +} diff --git a/lemon/test/dijkstra_test.cc b/lemon/test/dijkstra_test.cc new file mode 100644 index 0000000..c0fbf0b --- /dev/null +++ b/lemon/test/dijkstra_test.cc @@ -0,0 +1,242 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "graph_test.h" +#include "test_tools.h" + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "@arcs\n" + " label length\n" + "0 1 0 1\n" + "1 2 1 1\n" + "2 3 2 1\n" + "0 3 4 5\n" + "0 3 5 10\n" + "0 3 6 7\n" + "4 2 7 1\n" + "@attributes\n" + "source 0\n" + "target 3\n"; + +void checkDijkstraCompile() +{ + typedef int VType; + typedef concepts::Digraph Digraph; + typedef concepts::ReadMap LengthMap; + typedef Dijkstra DType; + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + + Digraph G; + Node s, t, n; + Arc e; + VType l; + int i; + bool b; + DType::DistMap d(G); + DType::PredMap p(G); + LengthMap length; + Path pp; + concepts::ReadMap nm; + + { + DType dijkstra_test(G,length); + const DType& const_dijkstra_test = dijkstra_test; + + dijkstra_test.run(s); + dijkstra_test.run(s,t); + + dijkstra_test.init(); + dijkstra_test.addSource(s); + dijkstra_test.addSource(s, 1); + n = dijkstra_test.processNextNode(); + n = const_dijkstra_test.nextNode(); + b = const_dijkstra_test.emptyQueue(); + i = const_dijkstra_test.queueSize(); + + dijkstra_test.start(); + dijkstra_test.start(t); + dijkstra_test.start(nm); + + l = const_dijkstra_test.dist(t); + e = const_dijkstra_test.predArc(t); + s = const_dijkstra_test.predNode(t); + b = const_dijkstra_test.reached(t); + b = const_dijkstra_test.processed(t); + d = const_dijkstra_test.distMap(); + p = const_dijkstra_test.predMap(); + pp = const_dijkstra_test.path(t); + l = const_dijkstra_test.currentDist(t); + } + { + DType + ::SetPredMap > + ::SetDistMap > + ::SetStandardProcessedMap + ::SetProcessedMap > + ::SetOperationTraits > + ::SetHeap > > + ::SetStandardHeap > > + ::SetHeap >, + concepts::ReadWriteMap > + ::Create dijkstra_test(G,length); + + LengthMap length_map; + concepts::ReadWriteMap pred_map; + concepts::ReadWriteMap dist_map; + concepts::WriteMap processed_map; + concepts::ReadWriteMap heap_cross_ref; + BinHeap > heap(heap_cross_ref); + + dijkstra_test + .lengthMap(length_map) + .predMap(pred_map) + .distMap(dist_map) + .processedMap(processed_map) + .heap(heap, heap_cross_ref); + + dijkstra_test.run(s); + dijkstra_test.run(s,t); + + dijkstra_test.addSource(s); + dijkstra_test.addSource(s, 1); + n = dijkstra_test.processNextNode(); + n = dijkstra_test.nextNode(); + b = dijkstra_test.emptyQueue(); + i = dijkstra_test.queueSize(); + + dijkstra_test.start(); + dijkstra_test.start(t); + dijkstra_test.start(nm); + + l = dijkstra_test.dist(t); + e = dijkstra_test.predArc(t); + s = dijkstra_test.predNode(t); + b = dijkstra_test.reached(t); + b = dijkstra_test.processed(t); + pp = dijkstra_test.path(t); + l = dijkstra_test.currentDist(t); + } + +} + +void checkDijkstraFunctionCompile() +{ + typedef int VType; + typedef concepts::Digraph Digraph; + typedef Digraph::Arc Arc; + typedef Digraph::Node Node; + typedef concepts::ReadMap LengthMap; + + Digraph g; + bool b; + dijkstra(g,LengthMap()).run(Node()); + b=dijkstra(g,LengthMap()).run(Node(),Node()); + dijkstra(g,LengthMap()) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .run(Node()); + b=dijkstra(g,LengthMap()) + .predMap(concepts::ReadWriteMap()) + .distMap(concepts::ReadWriteMap()) + .processedMap(concepts::WriteMap()) + .path(concepts::Path()) + .dist(VType()) + .run(Node(),Node()); +} + +template +void checkDijkstra() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + typedef typename Digraph::template ArcMap LengthMap; + + Digraph G; + Node s, t; + LengthMap length(G); + + std::istringstream input(test_lgf); + digraphReader(G, input). + arcMap("length", length). + node("source", s). + node("target", t). + run(); + + Dijkstra + dijkstra_test(G, length); + dijkstra_test.run(s); + + check(dijkstra_test.dist(t)==3,"Dijkstra found a wrong path."); + + Path p = dijkstra_test.path(t); + check(p.length()==3,"path() found a wrong path."); + check(checkPath(G, p),"path() found a wrong path."); + check(pathSource(G, p) == s,"path() found a wrong path."); + check(pathTarget(G, p) == t,"path() found a wrong path."); + + for(ArcIt e(G); e!=INVALID; ++e) { + Node u=G.source(e); + Node v=G.target(e); + check( !dijkstra_test.reached(u) || + (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= length[e]), + "Wrong output. dist(target)-dist(source)-arc_length=" << + dijkstra_test.dist(v) - dijkstra_test.dist(u) - length[e]); + } + + for(NodeIt v(G); v!=INVALID; ++v) { + if (dijkstra_test.reached(v)) { + check(v==s || dijkstra_test.predArc(v)!=INVALID, "Wrong tree."); + if (dijkstra_test.predArc(v)!=INVALID ) { + Arc e=dijkstra_test.predArc(v); + Node u=G.source(e); + check(u==dijkstra_test.predNode(v),"Wrong tree."); + check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == length[e], + "Wrong distance! Difference: " << + std::abs(dijkstra_test.dist(v)-dijkstra_test.dist(u)-length[e])); + } + } + } + + { + NullMap myPredMap; + dijkstra(G,length).predMap(myPredMap).run(s); + } +} + +int main() { + checkDijkstra(); + checkDijkstra(); + return 0; +} diff --git a/lemon/test/dim_test.cc b/lemon/test/dim_test.cc new file mode 100644 index 0000000..0b2b925 --- /dev/null +++ b/lemon/test/dim_test.cc @@ -0,0 +1,87 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include "test_tools.h" + +using namespace std; +using namespace lemon; + +int main() +{ + typedef dim2::Point Point; + + Point p; + check(p.size()==2, "Wrong dim2::Point initialization."); + + Point a(1,2); + Point b(3,4); + check(a[0]==1 && a[1]==2, "Wrong dim2::Point initialization."); + + p = a+b; + check(p.x==4 && p.y==6, "Wrong dim2::Point addition."); + + p = a-b; + check(p.x==-2 && p.y==-2, "Wrong dim2::Point subtraction."); + + check(a.normSquare()==5,"Wrong dim2::Point norm calculation."); + check(a*b==11, "Wrong dim2::Point scalar product."); + + int l=2; + p = a*l; + check(p.x==2 && p.y==4, "Wrong dim2::Point multiplication by a scalar."); + + p = b/l; + check(p.x==1 && p.y==2, "Wrong dim2::Point division by a scalar."); + + typedef dim2::Box Box; + Box box1; + check(box1.empty(), "Wrong empty() in dim2::Box."); + + box1.add(a); + check(!box1.empty(), "Wrong empty() in dim2::Box."); + box1.add(b); + + check(box1.left()==1 && box1.bottom()==2 && + box1.right()==3 && box1.top()==4, + "Wrong addition of points to dim2::Box."); + + check(box1.inside(Point(2,3)), "Wrong inside() in dim2::Box."); + check(box1.inside(Point(1,3)), "Wrong inside() in dim2::Box."); + check(!box1.inside(Point(0,3)), "Wrong inside() in dim2::Box."); + + Box box2(Point(2,2)); + check(!box2.empty(), "Wrong empty() in dim2::Box."); + + box2.bottomLeft(Point(2,0)); + box2.topRight(Point(5,3)); + Box box3 = box1 & box2; + check(!box3.empty() && + box3.left()==2 && box3.bottom()==2 && + box3.right()==3 && box3.top()==3, + "Wrong intersection of two dim2::Box objects."); + + box1.add(box2); + check(!box1.empty() && + box1.left()==1 && box1.bottom()==0 && + box1.right()==5 && box1.top()==4, + "Wrong addition of two dim2::Box objects."); + + return 0; +} diff --git a/lemon/test/edge_set_test.cc b/lemon/test/edge_set_test.cc new file mode 100644 index 0000000..afe1098 --- /dev/null +++ b/lemon/test/edge_set_test.cc @@ -0,0 +1,380 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include +#include + +#include + +#include + +#include "graph_test.h" +#include "test_tools.h" + +using namespace lemon; + +void checkSmartArcSet() { + checkConcept >(); + + typedef ListDigraph Digraph; + typedef SmartArcSet ArcSet; + + Digraph digraph; + Digraph::Node + n1 = digraph.addNode(), + n2 = digraph.addNode(); + + Digraph::Arc ga1 = digraph.addArc(n1, n2); + + ArcSet arc_set(digraph); + + Digraph::Arc ga2 = digraph.addArc(n2, n1); + + checkGraphNodeList(arc_set, 2); + checkGraphArcList(arc_set, 0); + + Digraph::Node + n3 = digraph.addNode(); + checkGraphNodeList(arc_set, 3); + checkGraphArcList(arc_set, 0); + + ArcSet::Arc a1 = arc_set.addArc(n1, n2); + check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc"); + checkGraphNodeList(arc_set, 3); + checkGraphArcList(arc_set, 1); + + checkGraphOutArcList(arc_set, n1, 1); + checkGraphOutArcList(arc_set, n2, 0); + checkGraphOutArcList(arc_set, n3, 0); + + checkGraphInArcList(arc_set, n1, 0); + checkGraphInArcList(arc_set, n2, 1); + checkGraphInArcList(arc_set, n3, 0); + + checkGraphConArcList(arc_set, 1); + + ArcSet::Arc a2 = arc_set.addArc(n2, n1), + a3 = arc_set.addArc(n2, n3), + a4 = arc_set.addArc(n2, n3); + checkGraphNodeList(arc_set, 3); + checkGraphArcList(arc_set, 4); + + checkGraphOutArcList(arc_set, n1, 1); + checkGraphOutArcList(arc_set, n2, 3); + checkGraphOutArcList(arc_set, n3, 0); + + checkGraphInArcList(arc_set, n1, 1); + checkGraphInArcList(arc_set, n2, 1); + checkGraphInArcList(arc_set, n3, 2); + + checkGraphConArcList(arc_set, 4); + + checkNodeIds(arc_set); + checkArcIds(arc_set); + checkGraphNodeMap(arc_set); + checkGraphArcMap(arc_set); + + check(arc_set.valid(), "Wrong validity"); + digraph.erase(n1); + check(!arc_set.valid(), "Wrong validity"); +} + +void checkListArcSet() { + checkConcept >(); + + typedef ListDigraph Digraph; + typedef ListArcSet ArcSet; + + Digraph digraph; + Digraph::Node + n1 = digraph.addNode(), + n2 = digraph.addNode(); + + Digraph::Arc ga1 = digraph.addArc(n1, n2); + + ArcSet arc_set(digraph); + + Digraph::Arc ga2 = digraph.addArc(n2, n1); + + checkGraphNodeList(arc_set, 2); + checkGraphArcList(arc_set, 0); + + Digraph::Node + n3 = digraph.addNode(); + checkGraphNodeList(arc_set, 3); + checkGraphArcList(arc_set, 0); + + ArcSet::Arc a1 = arc_set.addArc(n1, n2); + check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc"); + checkGraphNodeList(arc_set, 3); + checkGraphArcList(arc_set, 1); + + checkGraphOutArcList(arc_set, n1, 1); + checkGraphOutArcList(arc_set, n2, 0); + checkGraphOutArcList(arc_set, n3, 0); + + checkGraphInArcList(arc_set, n1, 0); + checkGraphInArcList(arc_set, n2, 1); + checkGraphInArcList(arc_set, n3, 0); + + checkGraphConArcList(arc_set, 1); + + ArcSet::Arc a2 = arc_set.addArc(n2, n1), + a3 = arc_set.addArc(n2, n3), + a4 = arc_set.addArc(n2, n3); + checkGraphNodeList(arc_set, 3); + checkGraphArcList(arc_set, 4); + + checkGraphOutArcList(arc_set, n1, 1); + checkGraphOutArcList(arc_set, n2, 3); + checkGraphOutArcList(arc_set, n3, 0); + + checkGraphInArcList(arc_set, n1, 1); + checkGraphInArcList(arc_set, n2, 1); + checkGraphInArcList(arc_set, n3, 2); + + checkGraphConArcList(arc_set, 4); + + checkNodeIds(arc_set); + checkArcIds(arc_set); + checkGraphNodeMap(arc_set); + checkGraphArcMap(arc_set); + + digraph.erase(n1); + + checkGraphNodeList(arc_set, 2); + checkGraphArcList(arc_set, 2); + + checkGraphOutArcList(arc_set, n2, 2); + checkGraphOutArcList(arc_set, n3, 0); + + checkGraphInArcList(arc_set, n2, 0); + checkGraphInArcList(arc_set, n3, 2); + + checkNodeIds(arc_set); + checkArcIds(arc_set); + checkGraphNodeMap(arc_set); + checkGraphArcMap(arc_set); + + checkGraphConArcList(arc_set, 2); +} + +void checkSmartEdgeSet() { + checkConcept >(); + + typedef ListDigraph Digraph; + typedef SmartEdgeSet EdgeSet; + + Digraph digraph; + Digraph::Node + n1 = digraph.addNode(), + n2 = digraph.addNode(); + + Digraph::Arc ga1 = digraph.addArc(n1, n2); + + EdgeSet edge_set(digraph); + + Digraph::Arc ga2 = digraph.addArc(n2, n1); + + checkGraphNodeList(edge_set, 2); + checkGraphArcList(edge_set, 0); + checkGraphEdgeList(edge_set, 0); + + Digraph::Node + n3 = digraph.addNode(); + checkGraphNodeList(edge_set, 3); + checkGraphArcList(edge_set, 0); + checkGraphEdgeList(edge_set, 0); + + EdgeSet::Edge e1 = edge_set.addEdge(n1, n2); + check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) || + (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge"); + checkGraphNodeList(edge_set, 3); + checkGraphArcList(edge_set, 2); + checkGraphEdgeList(edge_set, 1); + + checkGraphOutArcList(edge_set, n1, 1); + checkGraphOutArcList(edge_set, n2, 1); + checkGraphOutArcList(edge_set, n3, 0); + + checkGraphInArcList(edge_set, n1, 1); + checkGraphInArcList(edge_set, n2, 1); + checkGraphInArcList(edge_set, n3, 0); + + checkGraphIncEdgeList(edge_set, n1, 1); + checkGraphIncEdgeList(edge_set, n2, 1); + checkGraphIncEdgeList(edge_set, n3, 0); + + checkGraphConEdgeList(edge_set, 1); + checkGraphConArcList(edge_set, 2); + + EdgeSet::Edge e2 = edge_set.addEdge(n2, n1), + e3 = edge_set.addEdge(n2, n3), + e4 = edge_set.addEdge(n2, n3); + checkGraphNodeList(edge_set, 3); + checkGraphEdgeList(edge_set, 4); + + checkGraphOutArcList(edge_set, n1, 2); + checkGraphOutArcList(edge_set, n2, 4); + checkGraphOutArcList(edge_set, n3, 2); + + checkGraphInArcList(edge_set, n1, 2); + checkGraphInArcList(edge_set, n2, 4); + checkGraphInArcList(edge_set, n3, 2); + + checkGraphIncEdgeList(edge_set, n1, 2); + checkGraphIncEdgeList(edge_set, n2, 4); + checkGraphIncEdgeList(edge_set, n3, 2); + + checkGraphConEdgeList(edge_set, 4); + checkGraphConArcList(edge_set, 8); + + checkArcDirections(edge_set); + + checkNodeIds(edge_set); + checkArcIds(edge_set); + checkEdgeIds(edge_set); + checkGraphNodeMap(edge_set); + checkGraphArcMap(edge_set); + checkGraphEdgeMap(edge_set); + + check(edge_set.valid(), "Wrong validity"); + digraph.erase(n1); + check(!edge_set.valid(), "Wrong validity"); +} + +void checkListEdgeSet() { + checkConcept >(); + + typedef ListDigraph Digraph; + typedef ListEdgeSet EdgeSet; + + Digraph digraph; + Digraph::Node + n1 = digraph.addNode(), + n2 = digraph.addNode(); + + Digraph::Arc ga1 = digraph.addArc(n1, n2); + + EdgeSet edge_set(digraph); + + Digraph::Arc ga2 = digraph.addArc(n2, n1); + + checkGraphNodeList(edge_set, 2); + checkGraphArcList(edge_set, 0); + checkGraphEdgeList(edge_set, 0); + + Digraph::Node + n3 = digraph.addNode(); + checkGraphNodeList(edge_set, 3); + checkGraphArcList(edge_set, 0); + checkGraphEdgeList(edge_set, 0); + + EdgeSet::Edge e1 = edge_set.addEdge(n1, n2); + check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) || + (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge"); + checkGraphNodeList(edge_set, 3); + checkGraphArcList(edge_set, 2); + checkGraphEdgeList(edge_set, 1); + + checkGraphOutArcList(edge_set, n1, 1); + checkGraphOutArcList(edge_set, n2, 1); + checkGraphOutArcList(edge_set, n3, 0); + + checkGraphInArcList(edge_set, n1, 1); + checkGraphInArcList(edge_set, n2, 1); + checkGraphInArcList(edge_set, n3, 0); + + checkGraphIncEdgeList(edge_set, n1, 1); + checkGraphIncEdgeList(edge_set, n2, 1); + checkGraphIncEdgeList(edge_set, n3, 0); + + checkGraphConEdgeList(edge_set, 1); + checkGraphConArcList(edge_set, 2); + + EdgeSet::Edge e2 = edge_set.addEdge(n2, n1), + e3 = edge_set.addEdge(n2, n3), + e4 = edge_set.addEdge(n2, n3); + checkGraphNodeList(edge_set, 3); + checkGraphEdgeList(edge_set, 4); + + checkGraphOutArcList(edge_set, n1, 2); + checkGraphOutArcList(edge_set, n2, 4); + checkGraphOutArcList(edge_set, n3, 2); + + checkGraphInArcList(edge_set, n1, 2); + checkGraphInArcList(edge_set, n2, 4); + checkGraphInArcList(edge_set, n3, 2); + + checkGraphIncEdgeList(edge_set, n1, 2); + checkGraphIncEdgeList(edge_set, n2, 4); + checkGraphIncEdgeList(edge_set, n3, 2); + + checkGraphConEdgeList(edge_set, 4); + checkGraphConArcList(edge_set, 8); + + checkArcDirections(edge_set); + + checkNodeIds(edge_set); + checkArcIds(edge_set); + checkEdgeIds(edge_set); + checkGraphNodeMap(edge_set); + checkGraphArcMap(edge_set); + checkGraphEdgeMap(edge_set); + + digraph.erase(n1); + + checkGraphNodeList(edge_set, 2); + checkGraphArcList(edge_set, 4); + checkGraphEdgeList(edge_set, 2); + + checkGraphOutArcList(edge_set, n2, 2); + checkGraphOutArcList(edge_set, n3, 2); + + checkGraphInArcList(edge_set, n2, 2); + checkGraphInArcList(edge_set, n3, 2); + + checkGraphIncEdgeList(edge_set, n2, 2); + checkGraphIncEdgeList(edge_set, n3, 2); + + checkNodeIds(edge_set); + checkArcIds(edge_set); + checkEdgeIds(edge_set); + checkGraphNodeMap(edge_set); + checkGraphArcMap(edge_set); + checkGraphEdgeMap(edge_set); + + checkGraphConEdgeList(edge_set, 2); + checkGraphConArcList(edge_set, 4); + +} + + +int main() { + + checkSmartArcSet(); + checkListArcSet(); + checkSmartEdgeSet(); + checkListEdgeSet(); + + return 0; +} diff --git a/lemon/test/error_test.cc b/lemon/test/error_test.cc new file mode 100644 index 0000000..1527519 --- /dev/null +++ b/lemon/test/error_test.cc @@ -0,0 +1,90 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include +#include "test_tools.h" + +using namespace lemon; + +#ifdef LEMON_ENABLE_ASSERTS +#undef LEMON_ENABLE_ASSERTS +#endif + +#ifdef LEMON_DISABLE_ASSERTS +#undef LEMON_DISABLE_ASSERTS +#endif + +#ifdef NDEBUG +#undef NDEBUG +#endif + +//checking disabled asserts +#define LEMON_DISABLE_ASSERTS +#include + +void no_assertion_text_disable() { + LEMON_ASSERT(true, "This is a fault message"); +} + +void assertion_text_disable() { + LEMON_ASSERT(false, "This is a fault message"); +} + +void check_assertion_disable() { + no_assertion_text_disable(); + assertion_text_disable(); +} +#undef LEMON_DISABLE_ASSERTS + +//checking custom assert handler +#define LEMON_ASSERT_CUSTOM + +static int cnt = 0; +void my_assert_handler(const char*, int, const char*, + const char*, const char*) { + ++cnt; +} + +#define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler +#include + +void no_assertion_text_custom() { + LEMON_ASSERT(true, "This is a fault message"); +} + +void assertion_text_custom() { + LEMON_ASSERT(false, "This is a fault message"); +} + +void check_assertion_custom() { + no_assertion_text_custom(); + assertion_text_custom(); + check(cnt == 1, "The custom assert handler does not work"); +} + +#undef LEMON_ASSERT_CUSTOM + + +int main() { + check_assertion_disable(); + check_assertion_custom(); + + return 0; +} diff --git a/lemon/test/euler_test.cc b/lemon/test/euler_test.cc new file mode 100644 index 0000000..3f134b6 --- /dev/null +++ b/lemon/test/euler_test.cc @@ -0,0 +1,223 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include "test_tools.h" + +using namespace lemon; + +template +void checkDiEulerIt(const Digraph& g, + const typename Digraph::Node& start = INVALID) +{ + typename Digraph::template ArcMap visitationNumber(g, 0); + + DiEulerIt e(g, start); + if (e == INVALID) return; + typename Digraph::Node firstNode = g.source(e); + typename Digraph::Node lastNode = g.target(e); + if (start != INVALID) { + check(firstNode == start, "checkDiEulerIt: Wrong first node"); + } + + for (; e != INVALID; ++e) { + if (e != INVALID) lastNode = g.target(e); + ++visitationNumber[e]; + } + + check(firstNode == lastNode, + "checkDiEulerIt: First and last nodes are not the same"); + + for (typename Digraph::ArcIt a(g); a != INVALID; ++a) + { + check(visitationNumber[a] == 1, + "checkDiEulerIt: Not visited or multiple times visited arc found"); + } +} + +template +void checkEulerIt(const Graph& g, + const typename Graph::Node& start = INVALID) +{ + typename Graph::template EdgeMap visitationNumber(g, 0); + + EulerIt e(g, start); + if (e == INVALID) return; + typename Graph::Node firstNode = g.source(typename Graph::Arc(e)); + typename Graph::Node lastNode = g.target(typename Graph::Arc(e)); + if (start != INVALID) { + check(firstNode == start, "checkEulerIt: Wrong first node"); + } + + for (; e != INVALID; ++e) { + if (e != INVALID) lastNode = g.target(typename Graph::Arc(e)); + ++visitationNumber[e]; + } + + check(firstNode == lastNode, + "checkEulerIt: First and last nodes are not the same"); + + for (typename Graph::EdgeIt e(g); e != INVALID; ++e) + { + check(visitationNumber[e] == 1, + "checkEulerIt: Not visited or multiple times visited edge found"); + } +} + +int main() +{ + typedef ListDigraph Digraph; + typedef Undirector Graph; + + { + Digraph d; + Graph g(d); + + checkDiEulerIt(d); + checkDiEulerIt(g); + checkEulerIt(g); + + check(eulerian(d), "This graph is Eulerian"); + check(eulerian(g), "This graph is Eulerian"); + } + { + Digraph d; + Graph g(d); + Digraph::Node n = d.addNode(); + + checkDiEulerIt(d); + checkDiEulerIt(g); + checkEulerIt(g); + + check(eulerian(d), "This graph is Eulerian"); + check(eulerian(g), "This graph is Eulerian"); + } + { + Digraph d; + Graph g(d); + Digraph::Node n = d.addNode(); + d.addArc(n, n); + + checkDiEulerIt(d); + checkDiEulerIt(g); + checkEulerIt(g); + + check(eulerian(d), "This graph is Eulerian"); + check(eulerian(g), "This graph is Eulerian"); + } + { + Digraph d; + Graph g(d); + Digraph::Node n1 = d.addNode(); + Digraph::Node n2 = d.addNode(); + Digraph::Node n3 = d.addNode(); + + d.addArc(n1, n2); + d.addArc(n2, n1); + d.addArc(n2, n3); + d.addArc(n3, n2); + + checkDiEulerIt(d); + checkDiEulerIt(d, n2); + checkDiEulerIt(g); + checkDiEulerIt(g, n2); + checkEulerIt(g); + checkEulerIt(g, n2); + + check(eulerian(d), "This graph is Eulerian"); + check(eulerian(g), "This graph is Eulerian"); + } + { + Digraph d; + Graph g(d); + Digraph::Node n1 = d.addNode(); + Digraph::Node n2 = d.addNode(); + Digraph::Node n3 = d.addNode(); + Digraph::Node n4 = d.addNode(); + Digraph::Node n5 = d.addNode(); + Digraph::Node n6 = d.addNode(); + + d.addArc(n1, n2); + d.addArc(n2, n4); + d.addArc(n1, n3); + d.addArc(n3, n4); + d.addArc(n4, n1); + d.addArc(n3, n5); + d.addArc(n5, n2); + d.addArc(n4, n6); + d.addArc(n2, n6); + d.addArc(n6, n1); + d.addArc(n6, n3); + + checkDiEulerIt(d); + checkDiEulerIt(d, n1); + checkDiEulerIt(d, n5); + + checkDiEulerIt(g); + checkDiEulerIt(g, n1); + checkDiEulerIt(g, n5); + checkEulerIt(g); + checkEulerIt(g, n1); + checkEulerIt(g, n5); + + check(eulerian(d), "This graph is Eulerian"); + check(eulerian(g), "This graph is Eulerian"); + } + { + Digraph d; + Graph g(d); + Digraph::Node n0 = d.addNode(); + Digraph::Node n1 = d.addNode(); + Digraph::Node n2 = d.addNode(); + Digraph::Node n3 = d.addNode(); + Digraph::Node n4 = d.addNode(); + Digraph::Node n5 = d.addNode(); + + d.addArc(n1, n2); + d.addArc(n2, n3); + d.addArc(n3, n1); + + checkDiEulerIt(d); + checkDiEulerIt(d, n2); + + checkDiEulerIt(g); + checkDiEulerIt(g, n2); + checkEulerIt(g); + checkEulerIt(g, n2); + + check(!eulerian(d), "This graph is not Eulerian"); + check(!eulerian(g), "This graph is not Eulerian"); + } + { + Digraph d; + Graph g(d); + Digraph::Node n1 = d.addNode(); + Digraph::Node n2 = d.addNode(); + Digraph::Node n3 = d.addNode(); + + d.addArc(n1, n2); + d.addArc(n2, n3); + + check(!eulerian(d), "This graph is not Eulerian"); + check(!eulerian(g), "This graph is not Eulerian"); + } + + return 0; +} diff --git a/lemon/test/fractional_matching_test.cc b/lemon/test/fractional_matching_test.cc new file mode 100644 index 0000000..14316a3 --- /dev/null +++ b/lemon/test/fractional_matching_test.cc @@ -0,0 +1,525 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace std; +using namespace lemon; + +GRAPH_TYPEDEFS(SmartGraph); + + +const int lgfn = 4; +const std::string lgf[lgfn] = { + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "@edges\n" + " label weight\n" + "7 4 0 984\n" + "0 7 1 73\n" + "7 1 2 204\n" + "2 3 3 583\n" + "2 7 4 565\n" + "2 1 5 582\n" + "0 4 6 551\n" + "2 5 7 385\n" + "1 5 8 561\n" + "5 3 9 484\n" + "7 5 10 904\n" + "3 6 11 47\n" + "7 6 12 888\n" + "3 0 13 747\n" + "6 1 14 310\n", + + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "@edges\n" + " label weight\n" + "2 5 0 710\n" + "0 5 1 241\n" + "2 4 2 856\n" + "2 6 3 762\n" + "4 1 4 747\n" + "6 1 5 962\n" + "4 7 6 723\n" + "1 7 7 661\n" + "2 3 8 376\n" + "1 0 9 416\n" + "6 7 10 391\n", + + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "@edges\n" + " label weight\n" + "6 2 0 553\n" + "0 7 1 653\n" + "6 3 2 22\n" + "4 7 3 846\n" + "7 2 4 981\n" + "7 6 5 250\n" + "5 2 6 539\n", + + "@nodes\n" + "label\n" + "0\n" + "@edges\n" + " label weight\n" + "0 0 0 100\n" +}; + +void checkMaxFractionalMatchingCompile() +{ + typedef concepts::Graph Graph; + typedef Graph::Node Node; + typedef Graph::Edge Edge; + + Graph g; + Node n; + Edge e; + + MaxFractionalMatching mat_test(g); + const MaxFractionalMatching& + const_mat_test = mat_test; + + mat_test.init(); + mat_test.start(); + mat_test.start(true); + mat_test.startPerfect(); + mat_test.startPerfect(true); + mat_test.run(); + mat_test.run(true); + mat_test.runPerfect(); + mat_test.runPerfect(true); + + const_mat_test.matchingSize(); + const_mat_test.matching(e); + const_mat_test.matching(n); + const MaxFractionalMatching::MatchingMap& mmap = + const_mat_test.matchingMap(); + e = mmap[n]; + + const_mat_test.barrier(n); +} + +void checkMaxWeightedFractionalMatchingCompile() +{ + typedef concepts::Graph Graph; + typedef Graph::Node Node; + typedef Graph::Edge Edge; + typedef Graph::EdgeMap WeightMap; + + Graph g; + Node n; + Edge e; + WeightMap w(g); + + MaxWeightedFractionalMatching mat_test(g, w); + const MaxWeightedFractionalMatching& + const_mat_test = mat_test; + + mat_test.init(); + mat_test.start(); + mat_test.run(); + + const_mat_test.matchingWeight(); + const_mat_test.matchingSize(); + const_mat_test.matching(e); + const_mat_test.matching(n); + const MaxWeightedFractionalMatching::MatchingMap& mmap = + const_mat_test.matchingMap(); + e = mmap[n]; + + const_mat_test.dualValue(); + const_mat_test.nodeValue(n); +} + +void checkMaxWeightedPerfectFractionalMatchingCompile() +{ + typedef concepts::Graph Graph; + typedef Graph::Node Node; + typedef Graph::Edge Edge; + typedef Graph::EdgeMap WeightMap; + + Graph g; + Node n; + Edge e; + WeightMap w(g); + + MaxWeightedPerfectFractionalMatching mat_test(g, w); + const MaxWeightedPerfectFractionalMatching& + const_mat_test = mat_test; + + mat_test.init(); + mat_test.start(); + mat_test.run(); + + const_mat_test.matchingWeight(); + const_mat_test.matching(e); + const_mat_test.matching(n); + const MaxWeightedPerfectFractionalMatching::MatchingMap& mmap = + const_mat_test.matchingMap(); + e = mmap[n]; + + const_mat_test.dualValue(); + const_mat_test.nodeValue(n); +} + +void checkFractionalMatching(const SmartGraph& graph, + const MaxFractionalMatching& mfm, + bool allow_loops = true) { + int pv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + int indeg = 0; + for (InArcIt a(graph, n); a != INVALID; ++a) { + if (mfm.matching(graph.source(a)) == a) { + ++indeg; + } + } + if (mfm.matching(n) != INVALID) { + check(indeg == 1, "Invalid matching"); + ++pv; + } else { + check(indeg == 0, "Invalid matching"); + } + } + check(pv == mfm.matchingSize(), "Wrong matching size"); + + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + check((e == mfm.matching(graph.u(e)) ? 1 : 0) + + (e == mfm.matching(graph.v(e)) ? 1 : 0) == + mfm.matching(e), "Invalid matching"); + } + + SmartGraph::NodeMap processed(graph, false); + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + if (processed[n]) continue; + processed[n] = true; + if (mfm.matching(n) == INVALID) continue; + int num = 1; + Node v = graph.target(mfm.matching(n)); + while (v != n) { + processed[v] = true; + ++num; + v = graph.target(mfm.matching(v)); + } + check(num == 2 || num % 2 == 1, "Wrong cycle size"); + check(allow_loops || num != 1, "Wrong cycle size"); + } + + int anum = 0, bnum = 0; + SmartGraph::NodeMap neighbours(graph, false); + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + if (!mfm.barrier(n)) continue; + ++anum; + for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) { + Node u = graph.source(a); + if (!allow_loops && u == n) continue; + if (!neighbours[u]) { + neighbours[u] = true; + ++bnum; + } + } + } + check(anum - bnum + mfm.matchingSize() == countNodes(graph), + "Wrong barrier"); +} + +void checkPerfectFractionalMatching(const SmartGraph& graph, + const MaxFractionalMatching& mfm, + bool perfect, bool allow_loops = true) { + if (perfect) { + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + int indeg = 0; + for (InArcIt a(graph, n); a != INVALID; ++a) { + if (mfm.matching(graph.source(a)) == a) { + ++indeg; + } + } + check(mfm.matching(n) != INVALID, "Invalid matching"); + check(indeg == 1, "Invalid matching"); + } + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + check((e == mfm.matching(graph.u(e)) ? 1 : 0) + + (e == mfm.matching(graph.v(e)) ? 1 : 0) == + mfm.matching(e), "Invalid matching"); + } + } else { + int anum = 0, bnum = 0; + SmartGraph::NodeMap neighbours(graph, false); + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + if (!mfm.barrier(n)) continue; + ++anum; + for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) { + Node u = graph.source(a); + if (!allow_loops && u == n) continue; + if (!neighbours[u]) { + neighbours[u] = true; + ++bnum; + } + } + } + check(anum - bnum > 0, "Wrong barrier"); + } +} + +void checkWeightedFractionalMatching(const SmartGraph& graph, + const SmartGraph::EdgeMap& weight, + const MaxWeightedFractionalMatching& mwfm, + bool allow_loops = true) { + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + if (graph.u(e) == graph.v(e) && !allow_loops) continue; + int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e)) + - weight[e] * mwfm.dualScale; + + check(rw >= 0, "Negative reduced weight"); + check(rw == 0 || !mwfm.matching(e), + "Non-zero reduced weight on matching edge"); + } + + int pv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + int indeg = 0; + for (InArcIt a(graph, n); a != INVALID; ++a) { + if (mwfm.matching(graph.source(a)) == a) { + ++indeg; + } + } + check(indeg <= 1, "Invalid matching"); + if (mwfm.matching(n) != INVALID) { + check(mwfm.nodeValue(n) >= 0, "Invalid node value"); + check(indeg == 1, "Invalid matching"); + pv += weight[mwfm.matching(n)]; + SmartGraph::Node o = graph.target(mwfm.matching(n)); + } else { + check(mwfm.nodeValue(n) == 0, "Invalid matching"); + check(indeg == 0, "Invalid matching"); + } + } + + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + check((e == mwfm.matching(graph.u(e)) ? 1 : 0) + + (e == mwfm.matching(graph.v(e)) ? 1 : 0) == + mwfm.matching(e), "Invalid matching"); + } + + int dv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + dv += mwfm.nodeValue(n); + } + + check(pv * mwfm.dualScale == dv * 2, "Wrong duality"); + + SmartGraph::NodeMap processed(graph, false); + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + if (processed[n]) continue; + processed[n] = true; + if (mwfm.matching(n) == INVALID) continue; + int num = 1; + Node v = graph.target(mwfm.matching(n)); + while (v != n) { + processed[v] = true; + ++num; + v = graph.target(mwfm.matching(v)); + } + check(num == 2 || num % 2 == 1, "Wrong cycle size"); + check(allow_loops || num != 1, "Wrong cycle size"); + } + + return; +} + +void checkWeightedPerfectFractionalMatching(const SmartGraph& graph, + const SmartGraph::EdgeMap& weight, + const MaxWeightedPerfectFractionalMatching& mwpfm, + bool allow_loops = true) { + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + if (graph.u(e) == graph.v(e) && !allow_loops) continue; + int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e)) + - weight[e] * mwpfm.dualScale; + + check(rw >= 0, "Negative reduced weight"); + check(rw == 0 || !mwpfm.matching(e), + "Non-zero reduced weight on matching edge"); + } + + int pv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + int indeg = 0; + for (InArcIt a(graph, n); a != INVALID; ++a) { + if (mwpfm.matching(graph.source(a)) == a) { + ++indeg; + } + } + check(mwpfm.matching(n) != INVALID, "Invalid perfect matching"); + check(indeg == 1, "Invalid perfect matching"); + pv += weight[mwpfm.matching(n)]; + SmartGraph::Node o = graph.target(mwpfm.matching(n)); + } + + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) + + (e == mwpfm.matching(graph.v(e)) ? 1 : 0) == + mwpfm.matching(e), "Invalid matching"); + } + + int dv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + dv += mwpfm.nodeValue(n); + } + + check(pv * mwpfm.dualScale == dv * 2, "Wrong duality"); + + SmartGraph::NodeMap processed(graph, false); + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + if (processed[n]) continue; + processed[n] = true; + if (mwpfm.matching(n) == INVALID) continue; + int num = 1; + Node v = graph.target(mwpfm.matching(n)); + while (v != n) { + processed[v] = true; + ++num; + v = graph.target(mwpfm.matching(v)); + } + check(num == 2 || num % 2 == 1, "Wrong cycle size"); + check(allow_loops || num != 1, "Wrong cycle size"); + } + + return; +} + + +int main() { + + for (int i = 0; i < lgfn; ++i) { + SmartGraph graph; + SmartGraph::EdgeMap weight(graph); + + istringstream lgfs(lgf[i]); + graphReader(graph, lgfs). + edgeMap("weight", weight).run(); + + bool perfect_with_loops; + { + MaxFractionalMatching mfm(graph, true); + mfm.run(); + checkFractionalMatching(graph, mfm, true); + perfect_with_loops = mfm.matchingSize() == countNodes(graph); + } + + bool perfect_without_loops; + { + MaxFractionalMatching mfm(graph, false); + mfm.run(); + checkFractionalMatching(graph, mfm, false); + perfect_without_loops = mfm.matchingSize() == countNodes(graph); + } + + { + MaxFractionalMatching mfm(graph, true); + bool result = mfm.runPerfect(); + checkPerfectFractionalMatching(graph, mfm, result, true); + check(result == perfect_with_loops, "Wrong perfect matching"); + } + + { + MaxFractionalMatching mfm(graph, false); + bool result = mfm.runPerfect(); + checkPerfectFractionalMatching(graph, mfm, result, false); + check(result == perfect_without_loops, "Wrong perfect matching"); + } + + { + MaxWeightedFractionalMatching mwfm(graph, weight, true); + mwfm.run(); + checkWeightedFractionalMatching(graph, weight, mwfm, true); + } + + { + MaxWeightedFractionalMatching mwfm(graph, weight, false); + mwfm.run(); + checkWeightedFractionalMatching(graph, weight, mwfm, false); + } + + { + MaxWeightedPerfectFractionalMatching mwpfm(graph, weight, + true); + bool perfect = mwpfm.run(); + check(perfect == (mwpfm.matchingSize() == countNodes(graph)), + "Perfect matching found"); + check(perfect == perfect_with_loops, "Wrong perfect matching"); + + if (perfect) { + checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true); + } + } + + { + MaxWeightedPerfectFractionalMatching mwpfm(graph, weight, + false); + bool perfect = mwpfm.run(); + check(perfect == (mwpfm.matchingSize() == countNodes(graph)), + "Perfect matching found"); + check(perfect == perfect_without_loops, "Wrong perfect matching"); + + if (perfect) { + checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false); + } + } + + } + + return 0; +} diff --git a/lemon/test/gomory_hu_test.cc b/lemon/test/gomory_hu_test.cc new file mode 100644 index 0000000..c35f2e3 --- /dev/null +++ b/lemon/test/gomory_hu_test.cc @@ -0,0 +1,141 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include "test_tools.h" +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace lemon; + +typedef SmartGraph Graph; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "@arcs\n" + " label capacity\n" + "0 1 0 1\n" + "1 2 1 1\n" + "2 3 2 1\n" + "0 3 4 5\n" + "0 3 5 10\n" + "0 3 6 7\n" + "4 2 7 1\n" + "@attributes\n" + "source 0\n" + "target 3\n"; + +void checkGomoryHuCompile() +{ + typedef int Value; + typedef concepts::Graph Graph; + + typedef Graph::Node Node; + typedef Graph::Edge Edge; + typedef concepts::ReadMap CapMap; + typedef concepts::ReadWriteMap CutMap; + + Graph g; + Node n; + CapMap cap; + CutMap cut; + Value v; + int d; + + GomoryHu gh_test(g, cap); + const GomoryHu& + const_gh_test = gh_test; + + gh_test.run(); + + n = const_gh_test.predNode(n); + v = const_gh_test.predValue(n); + d = const_gh_test.rootDist(n); + v = const_gh_test.minCutValue(n, n); + v = const_gh_test.minCutMap(n, n, cut); +} + +GRAPH_TYPEDEFS(Graph); +typedef Graph::EdgeMap IntEdgeMap; +typedef Graph::NodeMap BoolNodeMap; + +int cutValue(const Graph& graph, const BoolNodeMap& cut, + const IntEdgeMap& capacity) { + + int sum = 0; + for (EdgeIt e(graph); e != INVALID; ++e) { + Node s = graph.u(e); + Node t = graph.v(e); + + if (cut[s] != cut[t]) { + sum += capacity[e]; + } + } + return sum; +} + + +int main() { + Graph graph; + IntEdgeMap capacity(graph); + + std::istringstream input(test_lgf); + GraphReader(graph, input). + edgeMap("capacity", capacity).run(); + + GomoryHu ght(graph, capacity); + ght.run(); + + for (NodeIt u(graph); u != INVALID; ++u) { + for (NodeIt v(graph); v != u; ++v) { + Preflow pf(graph, capacity, u, v); + pf.runMinCut(); + BoolNodeMap cm(graph); + ght.minCutMap(u, v, cm); + check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1"); + check(cm[u] != cm[v], "Wrong cut 2"); + check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3"); + + int sum=0; + for(GomoryHu::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a) + sum+=capacity[a]; + check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt"); + + sum=0; + for(GomoryHu::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n) + sum++; + for(GomoryHu::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n) + sum++; + check(sum == countNodes(graph), "Problem with MinCutNodeIt"); + } + } + + return 0; +} diff --git a/lemon/test/graph_copy_test.cc b/lemon/test/graph_copy_test.cc new file mode 100644 index 0000000..1fb2200 --- /dev/null +++ b/lemon/test/graph_copy_test.cc @@ -0,0 +1,215 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace std; +using namespace lemon; + +void digraph_copy_test() { + const int nn = 10; + + // Build a digraph + SmartDigraph from; + SmartDigraph::NodeMap fnm(from); + SmartDigraph::ArcMap fam(from); + SmartDigraph::Node fn = INVALID; + SmartDigraph::Arc fa = INVALID; + + std::vector fnv; + for (int i = 0; i < nn; ++i) { + SmartDigraph::Node node = from.addNode(); + fnv.push_back(node); + fnm[node] = i * i; + if (i == 0) fn = node; + } + + for (int i = 0; i < nn; ++i) { + for (int j = 0; j < nn; ++j) { + SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]); + fam[arc] = i + j * j; + if (i == 0 && j == 0) fa = arc; + } + } + + // Test digraph copy + ListDigraph to; + ListDigraph::NodeMap tnm(to); + ListDigraph::ArcMap tam(to); + ListDigraph::Node tn; + ListDigraph::Arc ta; + + SmartDigraph::NodeMap nr(from); + SmartDigraph::ArcMap er(from); + + ListDigraph::NodeMap ncr(to); + ListDigraph::ArcMap ecr(to); + + digraphCopy(from, to). + nodeMap(fnm, tnm).arcMap(fam, tam). + nodeRef(nr).arcRef(er). + nodeCrossRef(ncr).arcCrossRef(ecr). + node(fn, tn).arc(fa, ta).run(); + + check(countNodes(from) == countNodes(to), "Wrong copy."); + check(countArcs(from) == countArcs(to), "Wrong copy."); + + for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) { + check(ncr[nr[it]] == it, "Wrong copy."); + check(fnm[it] == tnm[nr[it]], "Wrong copy."); + } + + for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) { + check(ecr[er[it]] == it, "Wrong copy."); + check(fam[it] == tam[er[it]], "Wrong copy."); + check(nr[from.source(it)] == to.source(er[it]), "Wrong copy."); + check(nr[from.target(it)] == to.target(er[it]), "Wrong copy."); + } + + for (ListDigraph::NodeIt it(to); it != INVALID; ++it) { + check(nr[ncr[it]] == it, "Wrong copy."); + } + + for (ListDigraph::ArcIt it(to); it != INVALID; ++it) { + check(er[ecr[it]] == it, "Wrong copy."); + } + check(tn == nr[fn], "Wrong copy."); + check(ta == er[fa], "Wrong copy."); + + // Test repeated copy + digraphCopy(from, to).run(); + + check(countNodes(from) == countNodes(to), "Wrong copy."); + check(countArcs(from) == countArcs(to), "Wrong copy."); +} + +void graph_copy_test() { + const int nn = 10; + + // Build a graph + SmartGraph from; + SmartGraph::NodeMap fnm(from); + SmartGraph::ArcMap fam(from); + SmartGraph::EdgeMap fem(from); + SmartGraph::Node fn = INVALID; + SmartGraph::Arc fa = INVALID; + SmartGraph::Edge fe = INVALID; + + std::vector fnv; + for (int i = 0; i < nn; ++i) { + SmartGraph::Node node = from.addNode(); + fnv.push_back(node); + fnm[node] = i * i; + if (i == 0) fn = node; + } + + for (int i = 0; i < nn; ++i) { + for (int j = 0; j < nn; ++j) { + SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]); + fem[edge] = i * i + j * j; + fam[from.direct(edge, true)] = i + j * j; + fam[from.direct(edge, false)] = i * i + j; + if (i == 0 && j == 0) fa = from.direct(edge, true); + if (i == 0 && j == 0) fe = edge; + } + } + + // Test graph copy + ListGraph to; + ListGraph::NodeMap tnm(to); + ListGraph::ArcMap tam(to); + ListGraph::EdgeMap tem(to); + ListGraph::Node tn; + ListGraph::Arc ta; + ListGraph::Edge te; + + SmartGraph::NodeMap nr(from); + SmartGraph::ArcMap ar(from); + SmartGraph::EdgeMap er(from); + + ListGraph::NodeMap ncr(to); + ListGraph::ArcMap acr(to); + ListGraph::EdgeMap ecr(to); + + graphCopy(from, to). + nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem). + nodeRef(nr).arcRef(ar).edgeRef(er). + nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr). + node(fn, tn).arc(fa, ta).edge(fe, te).run(); + + check(countNodes(from) == countNodes(to), "Wrong copy."); + check(countEdges(from) == countEdges(to), "Wrong copy."); + check(countArcs(from) == countArcs(to), "Wrong copy."); + + for (SmartGraph::NodeIt it(from); it != INVALID; ++it) { + check(ncr[nr[it]] == it, "Wrong copy."); + check(fnm[it] == tnm[nr[it]], "Wrong copy."); + } + + for (SmartGraph::ArcIt it(from); it != INVALID; ++it) { + check(acr[ar[it]] == it, "Wrong copy."); + check(fam[it] == tam[ar[it]], "Wrong copy."); + check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy."); + check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy."); + } + + for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) { + check(ecr[er[it]] == it, "Wrong copy."); + check(fem[it] == tem[er[it]], "Wrong copy."); + check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]), + "Wrong copy."); + check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]), + "Wrong copy."); + check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])), + "Wrong copy."); + } + + for (ListGraph::NodeIt it(to); it != INVALID; ++it) { + check(nr[ncr[it]] == it, "Wrong copy."); + } + + for (ListGraph::ArcIt it(to); it != INVALID; ++it) { + check(ar[acr[it]] == it, "Wrong copy."); + } + for (ListGraph::EdgeIt it(to); it != INVALID; ++it) { + check(er[ecr[it]] == it, "Wrong copy."); + } + check(tn == nr[fn], "Wrong copy."); + check(ta == ar[fa], "Wrong copy."); + check(te == er[fe], "Wrong copy."); + + // Test repeated copy + graphCopy(from, to).run(); + + check(countNodes(from) == countNodes(to), "Wrong copy."); + check(countEdges(from) == countEdges(to), "Wrong copy."); + check(countArcs(from) == countArcs(to), "Wrong copy."); +} + + +int main() { + digraph_copy_test(); + graph_copy_test(); + + return 0; +} diff --git a/lemon/test/graph_test.cc b/lemon/test/graph_test.cc new file mode 100644 index 0000000..e383f9d --- /dev/null +++ b/lemon/test/graph_test.cc @@ -0,0 +1,597 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "test_tools.h" +#include "graph_test.h" + +using namespace lemon; +using namespace lemon::concepts; + +template +void checkGraphBuild() { + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + Graph G; + checkGraphNodeList(G, 0); + checkGraphEdgeList(G, 0); + checkGraphArcList(G, 0); + + G.reserveNode(3); + G.reserveEdge(3); + + Node + n1 = G.addNode(), + n2 = G.addNode(), + n3 = G.addNode(); + checkGraphNodeList(G, 3); + checkGraphEdgeList(G, 0); + checkGraphArcList(G, 0); + + Edge e1 = G.addEdge(n1, n2); + check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1), + "Wrong edge"); + + checkGraphNodeList(G, 3); + checkGraphEdgeList(G, 1); + checkGraphArcList(G, 2); + + checkGraphIncEdgeArcLists(G, n1, 1); + checkGraphIncEdgeArcLists(G, n2, 1); + checkGraphIncEdgeArcLists(G, n3, 0); + + checkGraphConEdgeList(G, 1); + checkGraphConArcList(G, 2); + + Edge e2 = G.addEdge(n2, n1), + e3 = G.addEdge(n2, n3); + + checkGraphNodeList(G, 3); + checkGraphEdgeList(G, 3); + checkGraphArcList(G, 6); + + checkGraphIncEdgeArcLists(G, n1, 2); + checkGraphIncEdgeArcLists(G, n2, 3); + checkGraphIncEdgeArcLists(G, n3, 1); + + checkGraphConEdgeList(G, 3); + checkGraphConArcList(G, 6); + + checkArcDirections(G); + + checkNodeIds(G); + checkArcIds(G); + checkEdgeIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); + checkGraphEdgeMap(G); +} + +template +void checkGraphAlter() { + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + Graph G; + Node n1 = G.addNode(), n2 = G.addNode(), + n3 = G.addNode(), n4 = G.addNode(); + Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1), + e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4), + e5 = G.addEdge(n4, n3); + + checkGraphNodeList(G, 4); + checkGraphEdgeList(G, 5); + checkGraphArcList(G, 10); + + // Check changeU() and changeV() + if (G.u(e2) == n2) { + G.changeU(e2, n3); + } else { + G.changeV(e2, n3); + } + + checkGraphNodeList(G, 4); + checkGraphEdgeList(G, 5); + checkGraphArcList(G, 10); + + checkGraphIncEdgeArcLists(G, n1, 3); + checkGraphIncEdgeArcLists(G, n2, 2); + checkGraphIncEdgeArcLists(G, n3, 3); + checkGraphIncEdgeArcLists(G, n4, 2); + + checkGraphConEdgeList(G, 5); + checkGraphConArcList(G, 10); + + if (G.u(e2) == n1) { + G.changeU(e2, n2); + } else { + G.changeV(e2, n2); + } + + checkGraphNodeList(G, 4); + checkGraphEdgeList(G, 5); + checkGraphArcList(G, 10); + + checkGraphIncEdgeArcLists(G, n1, 2); + checkGraphIncEdgeArcLists(G, n2, 3); + checkGraphIncEdgeArcLists(G, n3, 3); + checkGraphIncEdgeArcLists(G, n4, 2); + + checkGraphConEdgeList(G, 5); + checkGraphConArcList(G, 10); + + // Check contract() + G.contract(n1, n4, false); + + checkGraphNodeList(G, 3); + checkGraphEdgeList(G, 5); + checkGraphArcList(G, 10); + + checkGraphIncEdgeArcLists(G, n1, 4); + checkGraphIncEdgeArcLists(G, n2, 3); + checkGraphIncEdgeArcLists(G, n3, 3); + + checkGraphConEdgeList(G, 5); + checkGraphConArcList(G, 10); + + G.contract(n2, n3); + + checkGraphNodeList(G, 2); + checkGraphEdgeList(G, 3); + checkGraphArcList(G, 6); + + checkGraphIncEdgeArcLists(G, n1, 4); + checkGraphIncEdgeArcLists(G, n2, 2); + + checkGraphConEdgeList(G, 3); + checkGraphConArcList(G, 6); +} + +template +void checkGraphErase() { + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + Graph G; + Node n1 = G.addNode(), n2 = G.addNode(), + n3 = G.addNode(), n4 = G.addNode(); + Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1), + e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4), + e5 = G.addEdge(n4, n3); + + // Check edge deletion + G.erase(e2); + + checkGraphNodeList(G, 4); + checkGraphEdgeList(G, 4); + checkGraphArcList(G, 8); + + checkGraphIncEdgeArcLists(G, n1, 2); + checkGraphIncEdgeArcLists(G, n2, 2); + checkGraphIncEdgeArcLists(G, n3, 2); + checkGraphIncEdgeArcLists(G, n4, 2); + + checkGraphConEdgeList(G, 4); + checkGraphConArcList(G, 8); + + // Check node deletion + G.erase(n3); + + checkGraphNodeList(G, 3); + checkGraphEdgeList(G, 2); + checkGraphArcList(G, 4); + + checkGraphIncEdgeArcLists(G, n1, 2); + checkGraphIncEdgeArcLists(G, n2, 1); + checkGraphIncEdgeArcLists(G, n4, 1); + + checkGraphConEdgeList(G, 2); + checkGraphConArcList(G, 4); +} + + +template +void checkGraphSnapshot() { + TEMPLATE_GRAPH_TYPEDEFS(Graph); + + Graph G; + Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode(); + Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1), + e3 = G.addEdge(n2, n3); + + checkGraphNodeList(G, 3); + checkGraphEdgeList(G, 3); + checkGraphArcList(G, 6); + + typename Graph::Snapshot snapshot(G); + + Node n = G.addNode(); + G.addEdge(n3, n); + G.addEdge(n, n3); + G.addEdge(n3, n2); + + checkGraphNodeList(G, 4); + checkGraphEdgeList(G, 6); + checkGraphArcList(G, 12); + + snapshot.restore(); + + checkGraphNodeList(G, 3); + checkGraphEdgeList(G, 3); + checkGraphArcList(G, 6); + + checkGraphIncEdgeArcLists(G, n1, 2); + checkGraphIncEdgeArcLists(G, n2, 3); + checkGraphIncEdgeArcLists(G, n3, 1); + + checkGraphConEdgeList(G, 3); + checkGraphConArcList(G, 6); + + checkNodeIds(G); + checkEdgeIds(G); + checkArcIds(G); + checkGraphNodeMap(G); + checkGraphEdgeMap(G); + checkGraphArcMap(G); + + G.addNode(); + snapshot.save(G); + + G.addEdge(G.addNode(), G.addNode()); + + snapshot.restore(); + snapshot.save(G); + + checkGraphNodeList(G, 4); + checkGraphEdgeList(G, 3); + checkGraphArcList(G, 6); + + G.addEdge(G.addNode(), G.addNode()); + + snapshot.restore(); + + checkGraphNodeList(G, 4); + checkGraphEdgeList(G, 3); + checkGraphArcList(G, 6); +} + +void checkFullGraph(int num) { + typedef FullGraph Graph; + GRAPH_TYPEDEFS(Graph); + + Graph G(num); + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2, + "Wrong size"); + + G.resize(num); + check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2, + "Wrong size"); + + checkGraphNodeList(G, num); + checkGraphEdgeList(G, num * (num - 1) / 2); + + for (NodeIt n(G); n != INVALID; ++n) { + checkGraphOutArcList(G, n, num - 1); + checkGraphInArcList(G, n, num - 1); + checkGraphIncEdgeList(G, n, num - 1); + } + + checkGraphConArcList(G, num * (num - 1)); + checkGraphConEdgeList(G, num * (num - 1) / 2); + + checkArcDirections(G); + + checkNodeIds(G); + checkArcIds(G); + checkEdgeIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); + checkGraphEdgeMap(G); + + + for (int i = 0; i < G.nodeNum(); ++i) { + check(G.index(G(i)) == i, "Wrong index"); + } + + for (NodeIt u(G); u != INVALID; ++u) { + for (NodeIt v(G); v != INVALID; ++v) { + Edge e = G.edge(u, v); + Arc a = G.arc(u, v); + if (u == v) { + check(e == INVALID, "Wrong edge lookup"); + check(a == INVALID, "Wrong arc lookup"); + } else { + check((G.u(e) == u && G.v(e) == v) || + (G.u(e) == v && G.v(e) == u), "Wrong edge lookup"); + check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup"); + } + } + } +} + +void checkConcepts() { + { // Checking graph components + checkConcept(); + + checkConcept, + IDableGraphComponent<> >(); + + checkConcept, + IterableGraphComponent<> >(); + + checkConcept, + MappableGraphComponent<> >(); + } + { // Checking skeleton graph + checkConcept(); + } + { // Checking ListGraph + checkConcept(); + checkConcept, ListGraph>(); + checkConcept, ListGraph>(); + checkConcept, ListGraph>(); + checkConcept, ListGraph>(); + } + { // Checking SmartGraph + checkConcept(); + checkConcept, SmartGraph>(); + checkConcept, SmartGraph>(); + checkConcept, SmartGraph>(); + } + { // Checking FullGraph + checkConcept(); + } + { // Checking GridGraph + checkConcept(); + } + { // Checking HypercubeGraph + checkConcept(); + } +} + +template +void checkGraphValidity() { + TEMPLATE_GRAPH_TYPEDEFS(Graph); + Graph g; + + Node + n1 = g.addNode(), + n2 = g.addNode(), + n3 = g.addNode(); + + Edge + e1 = g.addEdge(n1, n2), + e2 = g.addEdge(n2, n3); + + check(g.valid(n1), "Wrong validity check"); + check(g.valid(e1), "Wrong validity check"); + check(g.valid(g.direct(e1, true)), "Wrong validity check"); + + check(!g.valid(g.nodeFromId(-1)), "Wrong validity check"); + check(!g.valid(g.edgeFromId(-1)), "Wrong validity check"); + check(!g.valid(g.arcFromId(-1)), "Wrong validity check"); +} + +template +void checkGraphValidityErase() { + TEMPLATE_GRAPH_TYPEDEFS(Graph); + Graph g; + + Node + n1 = g.addNode(), + n2 = g.addNode(), + n3 = g.addNode(); + + Edge + e1 = g.addEdge(n1, n2), + e2 = g.addEdge(n2, n3); + + check(g.valid(n1), "Wrong validity check"); + check(g.valid(e1), "Wrong validity check"); + check(g.valid(g.direct(e1, true)), "Wrong validity check"); + + g.erase(n1); + + check(!g.valid(n1), "Wrong validity check"); + check(g.valid(n2), "Wrong validity check"); + check(g.valid(n3), "Wrong validity check"); + check(!g.valid(e1), "Wrong validity check"); + check(g.valid(e2), "Wrong validity check"); + + check(!g.valid(g.nodeFromId(-1)), "Wrong validity check"); + check(!g.valid(g.edgeFromId(-1)), "Wrong validity check"); + check(!g.valid(g.arcFromId(-1)), "Wrong validity check"); +} + +void checkGridGraph(int width, int height) { + typedef GridGraph Graph; + GRAPH_TYPEDEFS(Graph); + Graph G(width, height); + + check(G.width() == width, "Wrong column number"); + check(G.height() == height, "Wrong row number"); + + G.resize(width, height); + check(G.width() == width, "Wrong column number"); + check(G.height() == height, "Wrong row number"); + + for (int i = 0; i < width; ++i) { + for (int j = 0; j < height; ++j) { + check(G.col(G(i, j)) == i, "Wrong column"); + check(G.row(G(i, j)) == j, "Wrong row"); + check(G.pos(G(i, j)).x == i, "Wrong column"); + check(G.pos(G(i, j)).y == j, "Wrong row"); + } + } + + for (int j = 0; j < height; ++j) { + for (int i = 0; i < width - 1; ++i) { + check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right"); + check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right"); + } + check(G.right(G(width - 1, j)) == INVALID, "Wrong right"); + } + + for (int j = 0; j < height; ++j) { + for (int i = 1; i < width; ++i) { + check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left"); + check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left"); + } + check(G.left(G(0, j)) == INVALID, "Wrong left"); + } + + for (int i = 0; i < width; ++i) { + for (int j = 0; j < height - 1; ++j) { + check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up"); + check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up"); + } + check(G.up(G(i, height - 1)) == INVALID, "Wrong up"); + } + + for (int i = 0; i < width; ++i) { + for (int j = 1; j < height; ++j) { + check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down"); + check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down"); + } + check(G.down(G(i, 0)) == INVALID, "Wrong down"); + } + + checkGraphNodeList(G, width * height); + checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height); + checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height)); + + for (NodeIt n(G); n != INVALID; ++n) { + int nb = 4; + if (G.col(n) == 0) --nb; + if (G.col(n) == width - 1) --nb; + if (G.row(n) == 0) --nb; + if (G.row(n) == height - 1) --nb; + + checkGraphOutArcList(G, n, nb); + checkGraphInArcList(G, n, nb); + checkGraphIncEdgeList(G, n, nb); + } + + checkArcDirections(G); + + checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height)); + checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height); + + checkNodeIds(G); + checkArcIds(G); + checkEdgeIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); + checkGraphEdgeMap(G); + +} + +void checkHypercubeGraph(int dim) { + GRAPH_TYPEDEFS(HypercubeGraph); + + HypercubeGraph G(dim); + check(G.dimension() == dim, "Wrong dimension"); + + G.resize(dim); + check(G.dimension() == dim, "Wrong dimension"); + + checkGraphNodeList(G, 1 << dim); + checkGraphEdgeList(G, dim * (1 << (dim-1))); + checkGraphArcList(G, dim * (1 << dim)); + + Node n = G.nodeFromId(dim); + + for (NodeIt n(G); n != INVALID; ++n) { + checkGraphIncEdgeList(G, n, dim); + for (IncEdgeIt e(G, n); e != INVALID; ++e) { + check( (G.u(e) == n && + G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) || + (G.v(e) == n && + G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))), + "Wrong edge or wrong dimension"); + } + + checkGraphOutArcList(G, n, dim); + for (OutArcIt a(G, n); a != INVALID; ++a) { + check(G.source(a) == n && + G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))), + "Wrong arc or wrong dimension"); + } + + checkGraphInArcList(G, n, dim); + for (InArcIt a(G, n); a != INVALID; ++a) { + check(G.target(a) == n && + G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))), + "Wrong arc or wrong dimension"); + } + } + + checkGraphConArcList(G, (1 << dim) * dim); + checkGraphConEdgeList(G, dim * (1 << (dim-1))); + + checkArcDirections(G); + + checkNodeIds(G); + checkArcIds(G); + checkEdgeIds(G); + checkGraphNodeMap(G); + checkGraphArcMap(G); + checkGraphEdgeMap(G); +} + +void checkGraphs() { + { // Checking ListGraph + checkGraphBuild(); + checkGraphAlter(); + checkGraphErase(); + checkGraphSnapshot(); + checkGraphValidityErase(); + } + { // Checking SmartGraph + checkGraphBuild(); + checkGraphSnapshot(); + checkGraphValidity(); + } + { // Checking FullGraph + checkFullGraph(7); + checkFullGraph(8); + } + { // Checking GridGraph + checkGridGraph(5, 8); + checkGridGraph(8, 5); + checkGridGraph(5, 5); + checkGridGraph(0, 0); + checkGridGraph(1, 1); + } + { // Checking HypercubeGraph + checkHypercubeGraph(1); + checkHypercubeGraph(2); + checkHypercubeGraph(3); + checkHypercubeGraph(4); + } +} + +int main() { + checkConcepts(); + checkGraphs(); + return 0; +} diff --git a/lemon/test/graph_test.h b/lemon/test/graph_test.h new file mode 100644 index 0000000..352319a --- /dev/null +++ b/lemon/test/graph_test.h @@ -0,0 +1,293 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_TEST_GRAPH_TEST_H +#define LEMON_TEST_GRAPH_TEST_H + +#include + +#include +#include + +#include "test_tools.h" + +namespace lemon { + + template + void checkGraphNodeList(const Graph &G, int cnt) + { + typename Graph::NodeIt n(G); + for(int i=0;i + void checkGraphArcList(const Graph &G, int cnt) + { + typename Graph::ArcIt e(G); + for(int i=0;i + void checkGraphOutArcList(const Graph &G, typename Graph::Node n, int cnt) + { + typename Graph::OutArcIt e(G,n); + for(int i=0;i + void checkGraphInArcList(const Graph &G, typename Graph::Node n, int cnt) + { + typename Graph::InArcIt e(G,n); + for(int i=0;i + void checkGraphEdgeList(const Graph &G, int cnt) + { + typename Graph::EdgeIt e(G); + for(int i=0;i + void checkGraphIncEdgeList(const Graph &G, typename Graph::Node n, int cnt) + { + typename Graph::IncEdgeIt e(G,n); + for(int i=0;i + void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n, + int cnt) + { + checkGraphIncEdgeList(G, n, cnt); + checkGraphOutArcList(G, n, cnt); + checkGraphInArcList(G, n, cnt); + } + + template + void checkGraphConArcList(const Graph &G, int cnt) { + int i = 0; + for (typename Graph::NodeIt u(G); u != INVALID; ++u) { + for (typename Graph::NodeIt v(G); v != INVALID; ++v) { + for (ConArcIt a(G, u, v); a != INVALID; ++a) { + check(G.source(a) == u, "Wrong iterator."); + check(G.target(a) == v, "Wrong iterator."); + ++i; + } + } + } + check(cnt == i, "Wrong iterator."); + } + + template + void checkGraphConEdgeList(const Graph &G, int cnt) { + int i = 0; + for (typename Graph::NodeIt u(G); u != INVALID; ++u) { + for (typename Graph::NodeIt v(G); v != INVALID; ++v) { + for (ConEdgeIt e(G, u, v); e != INVALID; ++e) { + check((G.u(e) == u && G.v(e) == v) || + (G.u(e) == v && G.v(e) == u), "Wrong iterator."); + i += u == v ? 2 : 1; + } + } + } + check(2 * cnt == i, "Wrong iterator."); + } + + template + void checkArcDirections(const Graph& G) { + for (typename Graph::ArcIt a(G); a != INVALID; ++a) { + check(G.source(a) == G.target(G.oppositeArc(a)), "Wrong direction"); + check(G.target(a) == G.source(G.oppositeArc(a)), "Wrong direction"); + check(G.direct(a, G.direction(a)) == a, "Wrong direction"); + } + } + + template + void checkNodeIds(const Graph& G) { + std::set values; + for (typename Graph::NodeIt n(G); n != INVALID; ++n) { + check(G.nodeFromId(G.id(n)) == n, "Wrong id"); + check(values.find(G.id(n)) == values.end(), "Wrong id"); + check(G.id(n) <= G.maxNodeId(), "Wrong maximum id"); + values.insert(G.id(n)); + } + } + + template + void checkArcIds(const Graph& G) { + std::set values; + for (typename Graph::ArcIt a(G); a != INVALID; ++a) { + check(G.arcFromId(G.id(a)) == a, "Wrong id"); + check(values.find(G.id(a)) == values.end(), "Wrong id"); + check(G.id(a) <= G.maxArcId(), "Wrong maximum id"); + values.insert(G.id(a)); + } + } + + template + void checkEdgeIds(const Graph& G) { + std::set values; + for (typename Graph::EdgeIt e(G); e != INVALID; ++e) { + check(G.edgeFromId(G.id(e)) == e, "Wrong id"); + check(values.find(G.id(e)) == values.end(), "Wrong id"); + check(G.id(e) <= G.maxEdgeId(), "Wrong maximum id"); + values.insert(G.id(e)); + } + } + + template + void checkGraphNodeMap(const Graph& G) { + typedef typename Graph::Node Node; + typedef typename Graph::NodeIt NodeIt; + + typedef typename Graph::template NodeMap IntNodeMap; + IntNodeMap map(G, 42); + for (NodeIt it(G); it != INVALID; ++it) { + check(map[it] == 42, "Wrong map constructor."); + } + int s = 0; + for (NodeIt it(G); it != INVALID; ++it) { + map[it] = 0; + check(map[it] == 0, "Wrong operator[]."); + map.set(it, s); + check(map[it] == s, "Wrong set."); + ++s; + } + s = s * (s - 1) / 2; + for (NodeIt it(G); it != INVALID; ++it) { + s -= map[it]; + } + check(s == 0, "Wrong sum."); + + // map = constMap(12); + // for (NodeIt it(G); it != INVALID; ++it) { + // check(map[it] == 12, "Wrong operator[]."); + // } + } + + template + void checkGraphArcMap(const Graph& G) { + typedef typename Graph::Arc Arc; + typedef typename Graph::ArcIt ArcIt; + + typedef typename Graph::template ArcMap IntArcMap; + IntArcMap map(G, 42); + for (ArcIt it(G); it != INVALID; ++it) { + check(map[it] == 42, "Wrong map constructor."); + } + int s = 0; + for (ArcIt it(G); it != INVALID; ++it) { + map[it] = 0; + check(map[it] == 0, "Wrong operator[]."); + map.set(it, s); + check(map[it] == s, "Wrong set."); + ++s; + } + s = s * (s - 1) / 2; + for (ArcIt it(G); it != INVALID; ++it) { + s -= map[it]; + } + check(s == 0, "Wrong sum."); + + // map = constMap(12); + // for (ArcIt it(G); it != INVALID; ++it) { + // check(map[it] == 12, "Wrong operator[]."); + // } + } + + template + void checkGraphEdgeMap(const Graph& G) { + typedef typename Graph::Edge Edge; + typedef typename Graph::EdgeIt EdgeIt; + + typedef typename Graph::template EdgeMap IntEdgeMap; + IntEdgeMap map(G, 42); + for (EdgeIt it(G); it != INVALID; ++it) { + check(map[it] == 42, "Wrong map constructor."); + } + int s = 0; + for (EdgeIt it(G); it != INVALID; ++it) { + map[it] = 0; + check(map[it] == 0, "Wrong operator[]."); + map.set(it, s); + check(map[it] == s, "Wrong set."); + ++s; + } + s = s * (s - 1) / 2; + for (EdgeIt it(G); it != INVALID; ++it) { + s -= map[it]; + } + check(s == 0, "Wrong sum."); + + // map = constMap(12); + // for (EdgeIt it(G); it != INVALID; ++it) { + // check(map[it] == 12, "Wrong operator[]."); + // } + } + + +} //namespace lemon + +#endif diff --git a/lemon/test/graph_utils_test.cc b/lemon/test/graph_utils_test.cc new file mode 100644 index 0000000..19a934a --- /dev/null +++ b/lemon/test/graph_utils_test.cc @@ -0,0 +1,217 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "graph_test.h" +#include "test_tools.h" + +using namespace lemon; + +template +void checkFindArcs() { + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + { + Digraph digraph; + for (int i = 0; i < 10; ++i) { + digraph.addNode(); + } + RangeIdMap nodes(digraph); + typename RangeIdMap::InverseMap invNodes(nodes); + for (int i = 0; i < 100; ++i) { + int src = rnd[invNodes.size()]; + int trg = rnd[invNodes.size()]; + digraph.addArc(invNodes[src], invNodes[trg]); + } + typename Digraph::template ArcMap found(digraph, false); + RangeIdMap arcs(digraph); + for (NodeIt src(digraph); src != INVALID; ++src) { + for (NodeIt trg(digraph); trg != INVALID; ++trg) { + for (ConArcIt con(digraph, src, trg); con != INVALID; ++con) { + check(digraph.source(con) == src, "Wrong source."); + check(digraph.target(con) == trg, "Wrong target."); + check(found[con] == false, "The arc found already."); + found[con] = true; + } + } + } + for (ArcIt it(digraph); it != INVALID; ++it) { + check(found[it] == true, "The arc is not found."); + } + } + + { + int num = 5; + Digraph fg; + std::vector nodes; + for (int i = 0; i < num; ++i) { + nodes.push_back(fg.addNode()); + } + for (int i = 0; i < num * num; ++i) { + fg.addArc(nodes[i / num], nodes[i % num]); + } + check(countNodes(fg) == num, "Wrong node number."); + check(countArcs(fg) == num*num, "Wrong arc number."); + for (NodeIt src(fg); src != INVALID; ++src) { + for (NodeIt trg(fg); trg != INVALID; ++trg) { + ConArcIt con(fg, src, trg); + check(con != INVALID, "There is no connecting arc."); + check(fg.source(con) == src, "Wrong source."); + check(fg.target(con) == trg, "Wrong target."); + check(++con == INVALID, "There is more connecting arc."); + } + } + ArcLookUp al1(fg); + DynArcLookUp al2(fg); + AllArcLookUp al3(fg); + for (NodeIt src(fg); src != INVALID; ++src) { + for (NodeIt trg(fg); trg != INVALID; ++trg) { + Arc con1 = al1(src, trg); + Arc con2 = al2(src, trg); + Arc con3 = al3(src, trg); + Arc con4 = findArc(fg, src, trg); + check(con1 == con2 && con2 == con3 && con3 == con4, + "Different results.") + check(con1 != INVALID, "There is no connecting arc."); + check(fg.source(con1) == src, "Wrong source."); + check(fg.target(con1) == trg, "Wrong target."); + check(al3(src, trg, con3) == INVALID, + "There is more connecting arc."); + check(findArc(fg, src, trg, con4) == INVALID, + "There is more connecting arc."); + } + } + } +} + +template +void checkFindEdges() { + TEMPLATE_GRAPH_TYPEDEFS(Graph); + Graph graph; + for (int i = 0; i < 10; ++i) { + graph.addNode(); + } + RangeIdMap nodes(graph); + typename RangeIdMap::InverseMap invNodes(nodes); + for (int i = 0; i < 100; ++i) { + int src = rnd[invNodes.size()]; + int trg = rnd[invNodes.size()]; + graph.addEdge(invNodes[src], invNodes[trg]); + } + typename Graph::template EdgeMap found(graph, 0); + RangeIdMap edges(graph); + for (NodeIt src(graph); src != INVALID; ++src) { + for (NodeIt trg(graph); trg != INVALID; ++trg) { + for (ConEdgeIt con(graph, src, trg); con != INVALID; ++con) { + check( (graph.u(con) == src && graph.v(con) == trg) || + (graph.v(con) == src && graph.u(con) == trg), + "Wrong end nodes."); + ++found[con]; + check(found[con] <= 2, "The edge found more than twice."); + } + } + } + for (EdgeIt it(graph); it != INVALID; ++it) { + check( (graph.u(it) != graph.v(it) && found[it] == 2) || + (graph.u(it) == graph.v(it) && found[it] == 1), + "The edge is not found correctly."); + } +} + +template +void checkDeg() +{ + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + const int nodeNum = 10; + const int arcNum = 100; + Digraph digraph; + InDegMap inDeg(digraph); + OutDegMap outDeg(digraph); + std::vector nodes(nodeNum); + for (int i = 0; i < nodeNum; ++i) { + nodes[i] = digraph.addNode(); + } + std::vector arcs(arcNum); + for (int i = 0; i < arcNum; ++i) { + arcs[i] = digraph.addArc(nodes[rnd[nodeNum]], nodes[rnd[nodeNum]]); + } + for (int i = 0; i < nodeNum; ++i) { + check(inDeg[nodes[i]] == countInArcs(digraph, nodes[i]), + "Wrong in degree map"); + } + for (int i = 0; i < nodeNum; ++i) { + check(outDeg[nodes[i]] == countOutArcs(digraph, nodes[i]), + "Wrong out degree map"); + } +} + +template +void checkSnapDeg() +{ + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + + Digraph g; + Node n1=g.addNode(); + Node n2=g.addNode(); + + InDegMap ind(g); + + g.addArc(n1,n2); + + typename Digraph::Snapshot snap(g); + + OutDegMap outd(g); + + check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value."); + check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value."); + + g.addArc(n1,n2); + g.addArc(n2,n1); + + check(ind[n1]==1 && ind[n2]==2, "Wrong InDegMap value."); + check(outd[n1]==2 && outd[n2]==1, "Wrong OutDegMap value."); + + snap.restore(); + + check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value."); + check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value."); +} + +int main() { + // Checking ConArcIt, ConEdgeIt, ArcLookUp, AllArcLookUp, and DynArcLookUp + checkFindArcs(); + checkFindArcs(); + checkFindEdges(); + checkFindEdges(); + + // Checking In/OutDegMap (and Snapshot feature) + checkDeg(); + checkDeg(); + checkSnapDeg(); + checkSnapDeg(); + + return 0; +} diff --git a/lemon/test/hao_orlin_test.cc b/lemon/test/hao_orlin_test.cc new file mode 100644 index 0000000..bdd3968 --- /dev/null +++ b/lemon/test/hao_orlin_test.cc @@ -0,0 +1,163 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; +using namespace std; + +const std::string lgf = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "@edges\n" + " cap1 cap2 cap3\n" + "0 1 1 1 1 \n" + "0 2 2 2 4 \n" + "1 2 4 4 4 \n" + "3 4 1 1 1 \n" + "3 5 2 2 4 \n" + "4 5 4 4 4 \n" + "5 4 4 4 4 \n" + "2 3 1 6 6 \n" + "4 0 1 6 6 \n"; + +void checkHaoOrlinCompile() +{ + typedef int Value; + typedef concepts::Digraph Digraph; + + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + typedef concepts::ReadMap CapMap; + typedef concepts::WriteMap CutMap; + + Digraph g; + Node n; + CapMap cap; + CutMap cut; + Value v; + + HaoOrlin ho_test(g, cap); + const HaoOrlin& + const_ho_test = ho_test; + + ho_test.init(); + ho_test.init(n); + ho_test.calculateOut(); + ho_test.calculateIn(); + ho_test.run(); + ho_test.run(n); + + v = const_ho_test.minCutValue(); + v = const_ho_test.minCutMap(cut); +} + +template +typename CapMap::Value + cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut) +{ + typename CapMap::Value sum = 0; + for (typename Graph::ArcIt a(graph); a != INVALID; ++a) { + if (cut[graph.source(a)] && !cut[graph.target(a)]) + sum += cap[a]; + } + return sum; +} + +int main() { + SmartDigraph graph; + SmartDigraph::ArcMap cap1(graph), cap2(graph), cap3(graph); + SmartDigraph::NodeMap cut(graph); + + istringstream input(lgf); + digraphReader(graph, input) + .arcMap("cap1", cap1) + .arcMap("cap2", cap2) + .arcMap("cap3", cap3) + .run(); + + { + HaoOrlin ho(graph, cap1); + ho.run(); + ho.minCutMap(cut); + + check(ho.minCutValue() == 1, "Wrong cut value"); + check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value"); + } + { + HaoOrlin ho(graph, cap2); + ho.run(); + ho.minCutMap(cut); + + check(ho.minCutValue() == 1, "Wrong cut value"); + check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value"); + } + { + HaoOrlin ho(graph, cap3); + ho.run(); + ho.minCutMap(cut); + + check(ho.minCutValue() == 1, "Wrong cut value"); + check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value"); + } + + typedef Undirector UGraph; + UGraph ugraph(graph); + + { + HaoOrlin > ho(ugraph, cap1); + ho.run(); + ho.minCutMap(cut); + + check(ho.minCutValue() == 2, "Wrong cut value"); + check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value"); + } + { + HaoOrlin > ho(ugraph, cap2); + ho.run(); + ho.minCutMap(cut); + + check(ho.minCutValue() == 5, "Wrong cut value"); + check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value"); + } + { + HaoOrlin > ho(ugraph, cap3); + ho.run(); + ho.minCutMap(cut); + + check(ho.minCutValue() == 5, "Wrong cut value"); + check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value"); + } + + return 0; +} diff --git a/lemon/test/heap_test.cc b/lemon/test/heap_test.cc new file mode 100644 index 0000000..4839043 --- /dev/null +++ b/lemon/test/heap_test.cc @@ -0,0 +1,310 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; +using namespace lemon::concepts; + +typedef ListDigraph Digraph; +DIGRAPH_TYPEDEFS(Digraph); + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "8\n" + "9\n" + "@arcs\n" + " label capacity\n" + "0 5 0 94\n" + "3 9 1 11\n" + "8 7 2 83\n" + "1 2 3 94\n" + "5 7 4 35\n" + "7 4 5 84\n" + "9 5 6 38\n" + "0 4 7 96\n" + "6 7 8 6\n" + "3 1 9 27\n" + "5 2 10 77\n" + "5 6 11 69\n" + "6 5 12 41\n" + "4 6 13 70\n" + "3 2 14 45\n" + "7 9 15 93\n" + "5 9 16 50\n" + "9 0 17 94\n" + "9 6 18 67\n" + "0 9 19 86\n" + "@attributes\n" + "source 3\n"; + +int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26, 1, 9, 4, 34}; +int test_inc[] = {20, 28, 34, 16, 0, 46, 44, 0, 42, 32, 14, 8, 6, 37}; + +int test_len = sizeof(test_seq) / sizeof(test_seq[0]); + +template +void heapSortTest() { + RangeMap map(test_len, -1); + Heap heap(map); + + std::vector v(test_len); + for (int i = 0; i < test_len; ++i) { + v[i] = test_seq[i]; + heap.push(i, v[i]); + } + std::sort(v.begin(), v.end()); + for (int i = 0; i < test_len; ++i) { + check(v[i] == heap.prio(), "Wrong order in heap sort."); + heap.pop(); + } +} + +template +void heapIncreaseTest() { + RangeMap map(test_len, -1); + + Heap heap(map); + + std::vector v(test_len); + for (int i = 0; i < test_len; ++i) { + v[i] = test_seq[i]; + heap.push(i, v[i]); + } + for (int i = 0; i < test_len; ++i) { + v[i] += test_inc[i]; + heap.increase(i, v[i]); + } + std::sort(v.begin(), v.end()); + for (int i = 0; i < test_len; ++i) { + check(v[i] == heap.prio(), "Wrong order in heap increase test."); + heap.pop(); + } +} + +template +void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length, + Node source) { + + typename Dijkstra::template SetStandardHeap:: + Create dijkstra(digraph, length); + + dijkstra.run(source); + + for(ArcIt a(digraph); a != INVALID; ++a) { + Node s = digraph.source(a); + Node t = digraph.target(a); + if (dijkstra.reached(s)) { + check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a], + "Error in shortest path tree."); + } + } + + for(NodeIt n(digraph); n != INVALID; ++n) { + if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) { + Arc a = dijkstra.predArc(n); + Node s = digraph.source(a); + check( dijkstra.dist(n) - dijkstra.dist(s) == length[a], + "Error in shortest path tree."); + } + } + +} + +int main() { + + typedef int Item; + typedef int Prio; + typedef RangeMap ItemIntMap; + + Digraph digraph; + IntArcMap length(digraph); + Node source; + + std::istringstream input(test_lgf); + digraphReader(digraph, input). + arcMap("capacity", length). + node("source", source). + run(); + + // BinHeap + { + typedef BinHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef BinHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + // QuadHeap + { + typedef QuadHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef QuadHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + // DHeap + { + typedef DHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef DHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + // FibHeap + { + typedef FibHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef FibHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + // PairingHeap + { + typedef PairingHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef PairingHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + // RadixHeap + { + typedef RadixHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef RadixHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + // BinomialHeap + { + typedef BinomialHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef BinomialHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + // BucketHeap, SimpleBucketHeap + { + typedef BucketHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef BucketHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + + typedef SimpleBucketHeap SimpleIntHeap; + heapSortTest(); + } + + { + typedef FibHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef FibHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + { + typedef RadixHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef RadixHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + { + typedef BucketHeap IntHeap; + checkConcept, IntHeap>(); + heapSortTest(); + heapIncreaseTest(); + + typedef BucketHeap NodeHeap; + checkConcept, NodeHeap>(); + dijkstraHeapTest(digraph, length, source); + } + + + return 0; +} diff --git a/lemon/test/kruskal_test.cc b/lemon/test/kruskal_test.cc new file mode 100644 index 0000000..af36c72 --- /dev/null +++ b/lemon/test/kruskal_test.cc @@ -0,0 +1,147 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include "test_tools.h" +#include +#include +#include + +#include +#include +#include + +using namespace std; +using namespace lemon; + +void checkCompileKruskal() +{ + concepts::WriteMap w; + concepts::WriteMap uw; + + concepts::ReadMap r; + concepts::ReadMap ur; + + concepts::Digraph g; + concepts::Graph ug; + + kruskal(g, r, w); + kruskal(ug, ur, uw); + + std::vector > rs; + std::vector > urs; + + kruskal(g, rs, w); + kruskal(ug, urs, uw); + + std::vector ws; + std::vector uws; + + kruskal(g, r, ws.begin()); + kruskal(ug, ur, uws.begin()); +} + +int main() { + + typedef ListGraph::Node Node; + typedef ListGraph::Edge Edge; + typedef ListGraph::NodeIt NodeIt; + typedef ListGraph::ArcIt ArcIt; + + ListGraph G; + + Node s=G.addNode(); + Node v1=G.addNode(); + Node v2=G.addNode(); + Node v3=G.addNode(); + Node v4=G.addNode(); + Node t=G.addNode(); + + Edge e1 = G.addEdge(s, v1); + Edge e2 = G.addEdge(s, v2); + Edge e3 = G.addEdge(v1, v2); + Edge e4 = G.addEdge(v2, v1); + Edge e5 = G.addEdge(v1, v3); + Edge e6 = G.addEdge(v3, v2); + Edge e7 = G.addEdge(v2, v4); + Edge e8 = G.addEdge(v4, v3); + Edge e9 = G.addEdge(v3, t); + Edge e10 = G.addEdge(v4, t); + + typedef ListGraph::EdgeMap ECostMap; + typedef ListGraph::EdgeMap EBoolMap; + + ECostMap edge_cost_map(G, 2); + EBoolMap tree_map(G); + + + //Test with const map. + check(kruskal(G, ConstMap(2), tree_map)==10, + "Total cost should be 10"); + //Test with an edge map (filled with uniform costs). + check(kruskal(G, edge_cost_map, tree_map)==10, + "Total cost should be 10"); + + edge_cost_map[e1] = -10; + edge_cost_map[e2] = -9; + edge_cost_map[e3] = -8; + edge_cost_map[e4] = -7; + edge_cost_map[e5] = -6; + edge_cost_map[e6] = -5; + edge_cost_map[e7] = -4; + edge_cost_map[e8] = -3; + edge_cost_map[e9] = -2; + edge_cost_map[e10] = -1; + + vector tree_edge_vec(5); + + //Test with a edge map and inserter. + check(kruskal(G, edge_cost_map, + tree_edge_vec.begin()) + ==-31, + "Total cost should be -31."); + + tree_edge_vec.clear(); + + check(kruskal(G, edge_cost_map, + back_inserter(tree_edge_vec)) + ==-31, + "Total cost should be -31."); + +// tree_edge_vec.clear(); + +// //The above test could also be coded like this: +// check(kruskal(G, +// makeKruskalMapInput(G, edge_cost_map), +// makeKruskalSequenceOutput(back_inserter(tree_edge_vec))) +// ==-31, +// "Total cost should be -31."); + + check(tree_edge_vec.size()==5,"The tree should have 5 edges."); + + check(tree_edge_vec[0]==e1 && + tree_edge_vec[1]==e2 && + tree_edge_vec[2]==e5 && + tree_edge_vec[3]==e7 && + tree_edge_vec[4]==e9, + "Wrong tree."); + + return 0; +} diff --git a/lemon/test/lgf_test.cc b/lemon/test/lgf_test.cc new file mode 100644 index 0000000..c1f373a --- /dev/null +++ b/lemon/test/lgf_test.cc @@ -0,0 +1,169 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include "test_tools.h" + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "@arcs\n" + " label\n" + "0 1 0\n" + "1 0 1\n" + "@attributes\n" + "source 0\n" + "target 1\n"; + +char test_lgf_nomap[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "@arcs\n" + " -\n" + "0 1\n"; + +char test_lgf_bad1[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "@arcs\n" + " - another\n" + "0 1\n"; + +char test_lgf_bad2[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "@arcs\n" + " label -\n" + "0 1\n"; + + +int main() +{ + { + ListDigraph d; + ListDigraph::Node s,t; + ListDigraph::ArcMap label(d); + std::istringstream input(test_lgf); + digraphReader(d, input). + node("source", s). + node("target", t). + arcMap("label", label). + run(); + check(countNodes(d) == 2,"There should be 2 nodes"); + check(countArcs(d) == 2,"There should be 2 arcs"); + } + { + ListGraph g; + ListGraph::Node s,t; + ListGraph::EdgeMap label(g); + std::istringstream input(test_lgf); + graphReader(g, input). + node("source", s). + node("target", t). + edgeMap("label", label). + run(); + check(countNodes(g) == 2,"There should be 2 nodes"); + check(countEdges(g) == 2,"There should be 2 arcs"); + } + + { + ListDigraph d; + std::istringstream input(test_lgf_nomap); + digraphReader(d, input). + run(); + check(countNodes(d) == 2,"There should be 2 nodes"); + check(countArcs(d) == 1,"There should be 1 arc"); + } + { + ListGraph g; + std::istringstream input(test_lgf_nomap); + graphReader(g, input). + run(); + check(countNodes(g) == 2,"There should be 2 nodes"); + check(countEdges(g) == 1,"There should be 1 edge"); + } + + { + ListDigraph d; + std::istringstream input(test_lgf_bad1); + bool ok=false; + try { + digraphReader(d, input). + run(); + } + catch (FormatError&) + { + ok = true; + } + check(ok,"FormatError exception should have occured"); + } + { + ListGraph g; + std::istringstream input(test_lgf_bad1); + bool ok=false; + try { + graphReader(g, input). + run(); + } + catch (FormatError&) + { + ok = true; + } + check(ok,"FormatError exception should have occured"); + } + + { + ListDigraph d; + std::istringstream input(test_lgf_bad2); + bool ok=false; + try { + digraphReader(d, input). + run(); + } + catch (FormatError&) + { + ok = true; + } + check(ok,"FormatError exception should have occured"); + } + { + ListGraph g; + std::istringstream input(test_lgf_bad2); + bool ok=false; + try { + graphReader(g, input). + run(); + } + catch (FormatError&) + { + ok = true; + } + check(ok,"FormatError exception should have occured"); + } +} diff --git a/lemon/test/lp_test.cc b/lemon/test/lp_test.cc new file mode 100644 index 0000000..125a909 --- /dev/null +++ b/lemon/test/lp_test.cc @@ -0,0 +1,427 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include "test_tools.h" +#include + +#include + +#ifdef LEMON_HAVE_GLPK +#include +#endif + +#ifdef LEMON_HAVE_CPLEX +#include +#endif + +#ifdef LEMON_HAVE_SOPLEX +#include +#endif + +#ifdef LEMON_HAVE_CLP +#include +#endif + +using namespace lemon; + +void lpTest(LpSolver& lp) +{ + + typedef LpSolver LP; + + std::vector x(10); + // for(int i=0;i<10;i++) x.push_back(lp.addCol()); + lp.addColSet(x); + lp.colLowerBound(x,1); + lp.colUpperBound(x,1); + lp.colBounds(x,1,2); + + std::vector y(10); + lp.addColSet(y); + + lp.colLowerBound(y,1); + lp.colUpperBound(y,1); + lp.colBounds(y,1,2); + + std::map z; + + z.insert(std::make_pair(12,INVALID)); + z.insert(std::make_pair(2,INVALID)); + z.insert(std::make_pair(7,INVALID)); + z.insert(std::make_pair(5,INVALID)); + + lp.addColSet(z); + + lp.colLowerBound(z,1); + lp.colUpperBound(z,1); + lp.colBounds(z,1,2); + + { + LP::Expr e,f,g; + LP::Col p1,p2,p3,p4,p5; + LP::Constr c; + + p1=lp.addCol(); + p2=lp.addCol(); + p3=lp.addCol(); + p4=lp.addCol(); + p5=lp.addCol(); + + e[p1]=2; + *e=12; + e[p1]+=2; + *e+=12; + e[p1]-=2; + *e-=12; + + e=2; + e=2.2; + e=p1; + e=f; + + e+=2; + e+=2.2; + e+=p1; + e+=f; + + e-=2; + e-=2.2; + e-=p1; + e-=f; + + e*=2; + e*=2.2; + e/=2; + e/=2.2; + + e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+ + (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+ + (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+ + 2.2*f+f*2.2+f/2.2+ + 2*f+f*2+f/2+ + 2.2*p1+p1*2.2+p1/2.2+ + 2*p1+p1*2+p1/2 + ); + + + c = (e <= f ); + c = (e <= 2.2); + c = (e <= 2 ); + c = (e <= p1 ); + c = (2.2<= f ); + c = (2 <= f ); + c = (p1 <= f ); + c = (p1 <= p2 ); + c = (p1 <= 2.2); + c = (p1 <= 2 ); + c = (2.2<= p2 ); + c = (2 <= p2 ); + + c = (e >= f ); + c = (e >= 2.2); + c = (e >= 2 ); + c = (e >= p1 ); + c = (2.2>= f ); + c = (2 >= f ); + c = (p1 >= f ); + c = (p1 >= p2 ); + c = (p1 >= 2.2); + c = (p1 >= 2 ); + c = (2.2>= p2 ); + c = (2 >= p2 ); + + c = (e == f ); + c = (e == 2.2); + c = (e == 2 ); + c = (e == p1 ); + c = (2.2== f ); + c = (2 == f ); + c = (p1 == f ); + //c = (p1 == p2 ); + c = (p1 == 2.2); + c = (p1 == 2 ); + c = (2.2== p2 ); + c = (2 == p2 ); + + c = ((2 <= e) <= 3); + c = ((2 <= p1) <= 3); + + c = ((2 >= e) >= 3); + c = ((2 >= p1) >= 3); + + { //Tests for #430 + LP::Col v=lp.addCol(); + LP::Constr c = v >= -3; + c = c <= 4; + LP::Constr c2; + c2 = -3 <= v <= 4; + } + + e[x[3]]=2; + e[x[3]]=4; + e[x[3]]=1; + *e=12; + + lp.addRow(-LP::INF,e,23); + lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23); + lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23); + + lp.addRow(x[1]+x[3]<=x[5]-3); + lp.addRow((-7<=x[1]+x[3]-12)<=3); + lp.addRow(x[1]<=x[5]); + + std::ostringstream buf; + + + e=((p1+p2)+(p1-0.99*p2)); + //e.prettyPrint(std::cout); + //(e<=2).prettyPrint(std::cout); + double tolerance=0.001; + e.simplify(tolerance); + buf << "Coeff. of p2 should be 0.01"; + check(e[p2]>0, buf.str()); + + tolerance=0.02; + e.simplify(tolerance); + buf << "Coeff. of p2 should be 0"; + check(const_cast(e)[p2]==0, buf.str()); + + //Test for clone/new + LP* lpnew = lp.newSolver(); + LP* lpclone = lp.cloneSolver(); + delete lpnew; + delete lpclone; + + } + + { + LP::DualExpr e,f,g; + LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID, + p4 = INVALID, p5 = INVALID; + + e[p1]=2; + e[p1]+=2; + e[p1]-=2; + + e=p1; + e=f; + + e+=p1; + e+=f; + + e-=p1; + e-=f; + + e*=2; + e*=2.2; + e/=2; + e/=2.2; + + e=((p1+p2)+(p1-p2)+ + (p1+f)+(f+p1)+(f+g)+ + (p1-f)+(f-p1)+(f-g)+ + 2.2*f+f*2.2+f/2.2+ + 2*f+f*2+f/2+ + 2.2*p1+p1*2.2+p1/2.2+ + 2*p1+p1*2+p1/2 + ); + } + +} + +void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat, + double exp_opt) { + using std::string; + lp.solve(); + + std::ostringstream buf; + buf << "PrimalType should be: " << int(stat) << int(lp.primalType()); + + check(lp.primalType()==stat, buf.str()); + + if (stat == LpSolver::OPTIMAL) { + std::ostringstream sbuf; + sbuf << "Wrong optimal value (" << lp.primal() <<") with " + << lp.solverName() <<"\n the right optimum is " << exp_opt; + check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str()); + } +} + +void aTest(LpSolver & lp) +{ + typedef LpSolver LP; + + //The following example is very simple + + typedef LpSolver::Row Row; + typedef LpSolver::Col Col; + + + Col x1 = lp.addCol(); + Col x2 = lp.addCol(); + + + //Constraints + Row upright=lp.addRow(x1+2*x2 <=1); + lp.addRow(x1+x2 >=-1); + lp.addRow(x1-x2 <=1); + lp.addRow(x1-x2 >=-1); + //Nonnegativity of the variables + lp.colLowerBound(x1, 0); + lp.colLowerBound(x2, 0); + //Objective function + lp.obj(x1+x2); + + lp.sense(lp.MAX); + + //Testing the problem retrieving routines + check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!"); + check(lp.sense() == lp.MAX,"This is a maximization!"); + check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!"); + check(lp.colLowerBound(x1)==0, + "The lower bound for variable x1 should be 0."); + check(lp.colUpperBound(x1)==LpSolver::INF, + "The upper bound for variable x1 should be infty."); + check(lp.rowLowerBound(upright) == -LpSolver::INF, + "The lower bound for the first row should be -infty."); + check(lp.rowUpperBound(upright)==1, + "The upper bound for the first row should be 1."); + LpSolver::Expr e = lp.row(upright); + check(e[x1] == 1, "The first coefficient should 1."); + check(e[x2] == 2, "The second coefficient should 1."); + + lp.row(upright, x1+x2 <=1); + e = lp.row(upright); + check(e[x1] == 1, "The first coefficient should 1."); + check(e[x2] == 1, "The second coefficient should 1."); + + LpSolver::DualExpr de = lp.col(x1); + check( de[upright] == 1, "The first coefficient should 1."); + + LpSolver* clp = lp.cloneSolver(); + + //Testing the problem retrieving routines + check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!"); + check(clp->sense() == clp->MAX,"This is a maximization!"); + check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!"); + // std::cout<colLowerBound(x1)==0, + "The lower bound for variable x1 should be 0."); + check(clp->colUpperBound(x1)==LpSolver::INF, + "The upper bound for variable x1 should be infty."); + + check(lp.rowLowerBound(upright)==-LpSolver::INF, + "The lower bound for the first row should be -infty."); + check(lp.rowUpperBound(upright)==1, + "The upper bound for the first row should be 1."); + e = clp->row(upright); + check(e[x1] == 1, "The first coefficient should 1."); + check(e[x2] == 1, "The second coefficient should 1."); + + de = clp->col(x1); + check(de[upright] == 1, "The first coefficient should 1."); + + delete clp; + + //Maximization of x1+x2 + //over the triangle with vertices (0,0) (0,1) (1,0) + double expected_opt=1; + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt); + + //Minimization + lp.sense(lp.MIN); + expected_opt=0; + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt); + + //Vertex (-1,0) instead of (0,0) + lp.colLowerBound(x1, -LpSolver::INF); + expected_opt=-1; + solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt); + + //Erase one constraint and return to maximization + lp.erase(upright); + lp.sense(lp.MAX); + expected_opt=LpSolver::INF; + solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt); + + //Infeasibilty + lp.addRow(x1+x2 <=-2); + solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt); + +} + +template +void cloneTest() +{ + //Test for clone/new + + LP* lp = new LP(); + LP* lpnew = lp->newSolver(); + LP* lpclone = lp->cloneSolver(); + delete lp; + delete lpnew; + delete lpclone; +} + +int main() +{ + LpSkeleton lp_skel; + lpTest(lp_skel); + +#ifdef LEMON_HAVE_GLPK + { + GlpkLp lp_glpk1,lp_glpk2; + lpTest(lp_glpk1); + aTest(lp_glpk2); + cloneTest(); + } +#endif + +#ifdef LEMON_HAVE_CPLEX + try { + CplexLp lp_cplex1,lp_cplex2; + lpTest(lp_cplex1); + aTest(lp_cplex2); + cloneTest(); + } catch (CplexEnv::LicenseError& error) { + check(false, error.what()); + } +#endif + +#ifdef LEMON_HAVE_SOPLEX + { + SoplexLp lp_soplex1,lp_soplex2; + lpTest(lp_soplex1); + aTest(lp_soplex2); + cloneTest(); + } +#endif + +#ifdef LEMON_HAVE_CLP + { + ClpLp lp_clp1,lp_clp2; + lpTest(lp_clp1); + aTest(lp_clp2); + cloneTest(); + } +#endif + + return 0; +} diff --git a/lemon/test/maps_test.cc b/lemon/test/maps_test.cc new file mode 100644 index 0000000..4b11bf3 --- /dev/null +++ b/lemon/test/maps_test.cc @@ -0,0 +1,1003 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; +using namespace lemon::concepts; + +struct A {}; +inline bool operator<(A, A) { return true; } +struct B {}; + +class C { + int _x; +public: + C(int x) : _x(x) {} + int get() const { return _x; } +}; +inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); } +inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); } + +C createC(int x) { return C(x); } + +template +class Less { + T _t; +public: + Less(T t): _t(t) {} + bool operator()(const T& t) const { return t < _t; } +}; + +class F { +public: + typedef A argument_type; + typedef B result_type; + + B operator()(const A&) const { return B(); } +private: + F& operator=(const F&); +}; + +int func(A) { return 3; } + +int binc(int a, B) { return a+1; } + +template +class Sum { + T& _sum; +public: + Sum(T& sum) : _sum(sum) {} + void operator()(const T& t) { _sum += t; } +}; + +typedef ReadMap DoubleMap; +typedef ReadWriteMap DoubleWriteMap; +typedef ReferenceMap DoubleRefMap; + +typedef ReadMap BoolMap; +typedef ReadWriteMap BoolWriteMap; +typedef ReferenceMap BoolRefMap; + +int main() +{ + // Map concepts + checkConcept, ReadMap >(); + checkConcept, ReadMap >(); + checkConcept, WriteMap >(); + checkConcept, WriteMap >(); + checkConcept, ReadWriteMap >(); + checkConcept, ReadWriteMap >(); + checkConcept, ReferenceMap >(); + checkConcept, ReferenceMap >(); + + // NullMap + { + checkConcept, NullMap >(); + NullMap map1; + NullMap map2 = map1; + map1 = nullMap(); + } + + // ConstMap + { + checkConcept, ConstMap >(); + checkConcept, ConstMap >(); + ConstMap map1; + ConstMap map2 = B(); + ConstMap map3 = map1; + map1 = constMap(B()); + map1 = constMap(); + map1.setAll(B()); + ConstMap map4(C(1)); + ConstMap map5 = map4; + map4 = constMap(C(2)); + map4.setAll(C(3)); + + checkConcept, ConstMap >(); + check(constMap(10)[A()] == 10, "Something is wrong with ConstMap"); + + checkConcept, ConstMap > >(); + ConstMap > map6; + ConstMap > map7 = map6; + map6 = constMap(); + map7 = constMap >(); + check(map6[A()] == 10 && map7[A()] == 10, + "Something is wrong with ConstMap"); + } + + // IdentityMap + { + checkConcept, IdentityMap >(); + IdentityMap map1; + IdentityMap map2 = map1; + map1 = identityMap(); + + checkConcept, IdentityMap >(); + check(identityMap()[1.0] == 1.0 && + identityMap()[3.14] == 3.14, + "Something is wrong with IdentityMap"); + } + + // RangeMap + { + checkConcept, RangeMap >(); + RangeMap map1; + RangeMap map2(10); + RangeMap map3(10,B()); + RangeMap map4 = map1; + RangeMap map5 = rangeMap(); + RangeMap map6 = rangeMap(10); + RangeMap map7 = rangeMap(10,B()); + + checkConcept< ReferenceMap, + RangeMap >(); + std::vector v(10, 0); + v[5] = 100; + RangeMap map8(v); + RangeMap map9 = rangeMap(v); + check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100, + "Something is wrong with RangeMap"); + } + + // SparseMap + { + checkConcept, SparseMap >(); + SparseMap map1; + SparseMap map2 = B(); + SparseMap map3 = sparseMap(); + SparseMap map4 = sparseMap(B()); + + checkConcept< ReferenceMap, + SparseMap >(); + std::map m; + SparseMap map5(m); + SparseMap map6(m,10); + SparseMap map7 = sparseMap(m); + SparseMap map8 = sparseMap(m,10); + + check(map5[1.0] == 0 && map5[3.14] == 0 && + map6[1.0] == 10 && map6[3.14] == 10, + "Something is wrong with SparseMap"); + map5[1.0] = map6[3.14] = 100; + check(map5[1.0] == 100 && map5[3.14] == 0 && + map6[1.0] == 10 && map6[3.14] == 100, + "Something is wrong with SparseMap"); + } + + // ComposeMap + { + typedef ComposeMap > CompMap; + checkConcept, CompMap>(); + CompMap map1 = CompMap(DoubleMap(),ReadMap()); + CompMap map2 = composeMap(DoubleMap(), ReadMap()); + + SparseMap m1(false); m1[3.14] = true; + RangeMap m2(2); m2[0] = 3.0; m2[1] = 3.14; + check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1], + "Something is wrong with ComposeMap") + } + + // CombineMap + { + typedef CombineMap > CombMap; + checkConcept, CombMap>(); + CombMap map1 = CombMap(DoubleMap(), DoubleMap()); + CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus()); + + check(combineMap(constMap(), identityMap(), &binc)[B()] == 3, + "Something is wrong with CombineMap"); + } + + // FunctorToMap, MapToFunctor + { + checkConcept, FunctorToMap >(); + checkConcept, FunctorToMap >(); + FunctorToMap map1; + FunctorToMap map2 = FunctorToMap(F()); + B b = functorToMap(F())[A()]; + + checkConcept, MapToFunctor > >(); + MapToFunctor > map = + MapToFunctor >(ReadMap()); + + check(functorToMap(&func)[A()] == 3, + "Something is wrong with FunctorToMap"); + check(mapToFunctor(constMap(2))(A()) == 2, + "Something is wrong with MapToFunctor"); + check(mapToFunctor(functorToMap(&func))(A()) == 3 && + mapToFunctor(functorToMap(&func))[A()] == 3, + "Something is wrong with FunctorToMap or MapToFunctor"); + check(functorToMap(mapToFunctor(constMap(2)))[A()] == 2, + "Something is wrong with FunctorToMap or MapToFunctor"); + } + + // ConvertMap + { + checkConcept, + ConvertMap, double> >(); + ConvertMap, int> map1(rangeMap(1, true)); + ConvertMap, int> map2 = convertMap(rangeMap(2, false)); + } + + // ForkMap + { + checkConcept >(); + + typedef RangeMap RM; + typedef SparseMap SM; + RM m1(10, -1); + SM m2(-1); + checkConcept, ForkMap >(); + checkConcept, ForkMap >(); + ForkMap map1(m1,m2); + ForkMap map2 = forkMap(m2,m1); + map2.set(5, 10); + check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 && + m2[5] == 10 && map2[1] == -1 && map2[5] == 10, + "Something is wrong with ForkMap"); + } + + // Arithmetic maps: + // - AddMap, SubMap, MulMap, DivMap + // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap + // - NegMap, NegWriteMap, AbsMap + { + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + + ConstMap c1(1.0), c2(3.14); + IdentityMap im; + ConvertMap, double> id(im); + check(addMap(c1,id)[0] == 1.0 && addMap(c1,id)[10] == 11.0, + "Something is wrong with AddMap"); + check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0, + "Something is wrong with SubMap"); + check(mulMap(id,c2)[0] == 0 && mulMap(id,c2)[2] == 6.28, + "Something is wrong with MulMap"); + check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2] == 1.57, + "Something is wrong with DivMap"); + + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + + check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0, + "Something is wrong with ShiftMap"); + check(shiftWriteMap(id, 2.0)[1] == 3.0 && + shiftWriteMap(id, 2.0)[10] == 12.0, + "Something is wrong with ShiftWriteMap"); + check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0, + "Something is wrong with ScaleMap"); + check(scaleWriteMap(id, 2.0)[1] == 2.0 && + scaleWriteMap(id, 2.0)[10] == 20.0, + "Something is wrong with ScaleWriteMap"); + check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0, + "Something is wrong with NegMap"); + check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0, + "Something is wrong with NegWriteMap"); + check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0, + "Something is wrong with AbsMap"); + } + + // Logical maps: + // - TrueMap, FalseMap + // - AndMap, OrMap + // - NotMap, NotWriteMap + // - EqualMap, LessMap + { + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + checkConcept >(); + + TrueMap tm; + FalseMap fm; + RangeMap rm(2); + rm[0] = true; rm[1] = false; + check(andMap(tm,rm)[0] && !andMap(tm,rm)[1] && + !andMap(fm,rm)[0] && !andMap(fm,rm)[1], + "Something is wrong with AndMap"); + check(orMap(tm,rm)[0] && orMap(tm,rm)[1] && + orMap(fm,rm)[0] && !orMap(fm,rm)[1], + "Something is wrong with OrMap"); + check(!notMap(rm)[0] && notMap(rm)[1], + "Something is wrong with NotMap"); + check(!notWriteMap(rm)[0] && notWriteMap(rm)[1], + "Something is wrong with NotWriteMap"); + + ConstMap cm(2.0); + IdentityMap im; + ConvertMap, double> id(im); + check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3], + "Something is wrong with LessMap"); + check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3], + "Something is wrong with EqualMap"); + } + + // LoggerBoolMap + { + typedef std::vector vec; + checkConcept, LoggerBoolMap >(); + checkConcept, + LoggerBoolMap > >(); + + vec v1; + vec v2(10); + LoggerBoolMap > + map1(std::back_inserter(v1)); + LoggerBoolMap map2(v2.begin()); + map1.set(10, false); + map1.set(20, true); map2.set(20, true); + map1.set(30, false); map2.set(40, false); + map1.set(50, true); map2.set(50, true); + map1.set(60, true); map2.set(60, true); + check(v1.size() == 3 && v2.size() == 10 && + v1[0]==20 && v1[1]==50 && v1[2]==60 && + v2[0]==20 && v2[1]==50 && v2[2]==60, + "Something is wrong with LoggerBoolMap"); + + int i = 0; + for ( LoggerBoolMap::Iterator it = map2.begin(); + it != map2.end(); ++it ) + check(v1[i++] == *it, "Something is wrong with LoggerBoolMap"); + + typedef ListDigraph Graph; + DIGRAPH_TYPEDEFS(Graph); + Graph gr; + + Node n0 = gr.addNode(); + Node n1 = gr.addNode(); + Node n2 = gr.addNode(); + Node n3 = gr.addNode(); + + gr.addArc(n3, n0); + gr.addArc(n3, n2); + gr.addArc(n0, n2); + gr.addArc(n2, n1); + gr.addArc(n0, n1); + + { + std::vector v; + dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run(); + + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3, + "Something is wrong with LoggerBoolMap"); + } + { + std::vector v(countNodes(gr)); + dfs(gr).processedMap(loggerBoolMap(v.begin())).run(); + + check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3, + "Something is wrong with LoggerBoolMap"); + } + } + + // IdMap, RangeIdMap + { + typedef ListDigraph Graph; + DIGRAPH_TYPEDEFS(Graph); + + checkConcept, IdMap >(); + checkConcept, IdMap >(); + checkConcept, RangeIdMap >(); + checkConcept, RangeIdMap >(); + + Graph gr; + IdMap nmap(gr); + IdMap amap(gr); + RangeIdMap nrmap(gr); + RangeIdMap armap(gr); + + Node n0 = gr.addNode(); + Node n1 = gr.addNode(); + Node n2 = gr.addNode(); + + Arc a0 = gr.addArc(n0, n1); + Arc a1 = gr.addArc(n0, n2); + Arc a2 = gr.addArc(n2, n1); + Arc a3 = gr.addArc(n2, n0); + + check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap"); + check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap"); + check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap"); + + check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap"); + check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap"); + check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap"); + check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap"); + + check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap"); + check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap"); + + check(nrmap.size() == 3 && armap.size() == 4, + "Wrong RangeIdMap::size()"); + + check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap"); + check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap"); + check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap"); + + check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap"); + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap"); + check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap"); + check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap"); + + check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap"); + check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap"); + + gr.erase(n1); + + if (nrmap[n0] == 1) nrmap.swap(n0, n2); + nrmap.swap(n2, n0); + if (armap[a1] == 1) armap.swap(a1, a3); + armap.swap(a3, a1); + + check(nrmap.size() == 2 && armap.size() == 2, + "Wrong RangeIdMap::size()"); + + check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap"); + check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap"); + + check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap"); + check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap"); + + check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap"); + check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap"); + } + + // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap + { + typedef ListGraph Graph; + GRAPH_TYPEDEFS(Graph); + + checkConcept, SourceMap >(); + checkConcept, TargetMap >(); + checkConcept, ForwardMap >(); + checkConcept, BackwardMap >(); + checkConcept, InDegMap >(); + checkConcept, OutDegMap >(); + + Graph gr; + Node n0 = gr.addNode(); + Node n1 = gr.addNode(); + Node n2 = gr.addNode(); + + gr.addEdge(n0,n1); + gr.addEdge(n1,n2); + gr.addEdge(n0,n2); + gr.addEdge(n2,n1); + gr.addEdge(n1,n2); + gr.addEdge(n0,n1); + + for (EdgeIt e(gr); e != INVALID; ++e) { + check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap"); + check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap"); + } + + check(mapCompare(gr, + sourceMap(orienter(gr, constMap(true))), + targetMap(orienter(gr, constMap(false)))), + "Wrong SourceMap or TargetMap"); + + typedef Orienter > Digraph; + Digraph dgr(gr, constMap(true)); + OutDegMap odm(dgr); + InDegMap idm(dgr); + + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap"); + check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap"); + + gr.addEdge(n2, n0); + + check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap"); + check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap"); + } + + // CrossRefMap + { + typedef ListDigraph Graph; + DIGRAPH_TYPEDEFS(Graph); + + checkConcept, + CrossRefMap >(); + checkConcept, + CrossRefMap >(); + checkConcept, + CrossRefMap >(); + + Graph gr; + typedef CrossRefMap CRMap; + CRMap map(gr); + + Node n0 = gr.addNode(); + Node n1 = gr.addNode(); + Node n2 = gr.addNode(); + + map.set(n0, 'A'); + map.set(n1, 'B'); + map.set(n2, 'C'); + + check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0, + "Wrong CrossRefMap"); + check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1, + "Wrong CrossRefMap"); + check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2, + "Wrong CrossRefMap"); + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1, + "Wrong CrossRefMap::count()"); + + CRMap::ValueIt it = map.beginValue(); + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' && + it == map.endValue(), "Wrong value iterator"); + + map.set(n2, 'A'); + + check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A', + "Wrong CrossRefMap"); + check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap"); + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap"); + check(map('C') == INVALID && map.inverse()['C'] == INVALID, + "Wrong CrossRefMap"); + check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0, + "Wrong CrossRefMap::count()"); + + it = map.beginValue(); + check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' && + it == map.endValue(), "Wrong value iterator"); + + map.set(n0, 'C'); + + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A', + "Wrong CrossRefMap"); + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap"); + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap"); + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap"); + check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1, + "Wrong CrossRefMap::count()"); + + it = map.beginValue(); + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' && + it == map.endValue(), "Wrong value iterator"); + } + + // CrossRefMap + { + typedef SmartDigraph Graph; + DIGRAPH_TYPEDEFS(Graph); + + checkConcept, + CrossRefMap >(); + + Graph gr; + typedef CrossRefMap CRMap; + typedef CRMap::ValueIterator ValueIt; + CRMap map(gr); + + Node n0 = gr.addNode(); + Node n1 = gr.addNode(); + Node n2 = gr.addNode(); + + map.set(n0, 'A'); + map.set(n1, 'B'); + map.set(n2, 'C'); + map.set(n2, 'A'); + map.set(n0, 'C'); + + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A', + "Wrong CrossRefMap"); + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap"); + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap"); + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap"); + + ValueIt it = map.beginValue(); + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' && + it == map.endValue(), "Wrong value iterator"); + } + + // Iterable bool map + { + typedef SmartGraph Graph; + typedef SmartGraph::Node Item; + + typedef IterableBoolMap Ibm; + checkConcept, Ibm>(); + + const int num = 10; + Graph g; + Ibm map0(g, true); + std::vector items; + for (int i = 0; i < num; ++i) { + items.push_back(g.addNode()); + } + + Ibm map1(g, true); + int n = 0; + for (Ibm::TrueIt it(map1); it != INVALID; ++it) { + check(map1[static_cast(it)], "Wrong TrueIt"); + ++n; + } + check(n == num, "Wrong number"); + + n = 0; + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) { + check(map1[static_cast(it)], "Wrong ItemIt for true"); + ++n; + } + check(n == num, "Wrong number"); + check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt"); + check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false"); + + map1[items[5]] = true; + + n = 0; + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) { + check(map1[static_cast(it)], "Wrong ItemIt for true"); + ++n; + } + check(n == num, "Wrong number"); + + map1[items[num / 2]] = false; + check(map1[items[num / 2]] == false, "Wrong map value"); + + n = 0; + for (Ibm::TrueIt it(map1); it != INVALID; ++it) { + check(map1[static_cast(it)], "Wrong TrueIt for true"); + ++n; + } + check(n == num - 1, "Wrong number"); + + n = 0; + for (Ibm::FalseIt it(map1); it != INVALID; ++it) { + check(!map1[static_cast(it)], "Wrong FalseIt for true"); + ++n; + } + check(n == 1, "Wrong number"); + + map1[items[0]] = false; + check(map1[items[0]] == false, "Wrong map value"); + + map1[items[num - 1]] = false; + check(map1[items[num - 1]] == false, "Wrong map value"); + + n = 0; + for (Ibm::TrueIt it(map1); it != INVALID; ++it) { + check(map1[static_cast(it)], "Wrong TrueIt for true"); + ++n; + } + check(n == num - 3, "Wrong number"); + check(map1.trueNum() == num - 3, "Wrong number"); + + n = 0; + for (Ibm::FalseIt it(map1); it != INVALID; ++it) { + check(!map1[static_cast(it)], "Wrong FalseIt for true"); + ++n; + } + check(n == 3, "Wrong number"); + check(map1.falseNum() == 3, "Wrong number"); + } + + // Iterable int map + { + typedef SmartGraph Graph; + typedef SmartGraph::Node Item; + typedef IterableIntMap Iim; + + checkConcept, Iim>(); + + const int num = 10; + Graph g; + Iim map0(g, 0); + std::vector items; + for (int i = 0; i < num; ++i) { + items.push_back(g.addNode()); + } + + Iim map1(g); + check(map1.size() == 0, "Wrong size"); + + for (int i = 0; i < num; ++i) { + map1[items[i]] = i; + } + check(map1.size() == num, "Wrong size"); + + for (int i = 0; i < num; ++i) { + Iim::ItemIt it(map1, i); + check(static_cast(it) == items[i], "Wrong value"); + ++it; + check(static_cast(it) == INVALID, "Wrong value"); + } + + for (int i = 0; i < num; ++i) { + map1[items[i]] = i % 2; + } + check(map1.size() == 2, "Wrong size"); + + int n = 0; + for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) { + check(map1[static_cast(it)] == 0, "Wrong value"); + ++n; + } + check(n == (num + 1) / 2, "Wrong number"); + + for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) { + check(map1[static_cast(it)] == 1, "Wrong value"); + ++n; + } + check(n == num, "Wrong number"); + + } + + // Iterable value map + { + typedef SmartGraph Graph; + typedef SmartGraph::Node Item; + typedef IterableValueMap Ivm; + + checkConcept, Ivm>(); + + const int num = 10; + Graph g; + Ivm map0(g, 0.0); + std::vector items; + for (int i = 0; i < num; ++i) { + items.push_back(g.addNode()); + } + + Ivm map1(g, 0.0); + check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size"); + check(*map1.beginValue() == 0.0, "Wrong value"); + + for (int i = 0; i < num; ++i) { + map1.set(items[i], static_cast(i)); + } + check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size"); + + for (int i = 0; i < num; ++i) { + Ivm::ItemIt it(map1, static_cast(i)); + check(static_cast(it) == items[i], "Wrong value"); + ++it; + check(static_cast(it) == INVALID, "Wrong value"); + } + + for (Ivm::ValueIt vit = map1.beginValue(); + vit != map1.endValue(); ++vit) { + check(map1[static_cast(Ivm::ItemIt(map1, *vit))] == *vit, + "Wrong ValueIt"); + } + + for (int i = 0; i < num; ++i) { + map1.set(items[i], static_cast(i % 2)); + } + check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size"); + + int n = 0; + for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) { + check(map1[static_cast(it)] == 0.0, "Wrong value"); + ++n; + } + check(n == (num + 1) / 2, "Wrong number"); + + for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) { + check(map1[static_cast(it)] == 1.0, "Wrong value"); + ++n; + } + check(n == num, "Wrong number"); + + } + + // Graph map utilities: + // mapMin(), mapMax(), mapMinValue(), mapMaxValue() + // mapFind(), mapFindIf(), mapCount(), mapCountIf() + // mapCopy(), mapCompare(), mapFill() + { + DIGRAPH_TYPEDEFS(SmartDigraph); + + SmartDigraph g; + Node n1 = g.addNode(); + Node n2 = g.addNode(); + Node n3 = g.addNode(); + + SmartDigraph::NodeMap map1(g); + SmartDigraph::ArcMap map2(g); + ConstMap cmap1 = A(); + ConstMap cmap2 = C(0); + + map1[n1] = 10; + map1[n2] = 5; + map1[n3] = 12; + + // mapMin(), mapMax(), mapMinValue(), mapMaxValue() + check(mapMin(g, map1) == n2, "Wrong mapMin()"); + check(mapMax(g, map1) == n3, "Wrong mapMax()"); + check(mapMin(g, map1, std::greater()) == n3, "Wrong mapMin()"); + check(mapMax(g, map1, std::greater()) == n2, "Wrong mapMax()"); + check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()"); + check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()"); + + check(mapMin(g, map2) == INVALID, "Wrong mapMin()"); + check(mapMax(g, map2) == INVALID, "Wrong mapMax()"); + + check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()"); + check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()"); + + Arc a1 = g.addArc(n1, n2); + Arc a2 = g.addArc(n1, n3); + Arc a3 = g.addArc(n2, n3); + Arc a4 = g.addArc(n3, n1); + + map2[a1] = 'b'; + map2[a2] = 'a'; + map2[a3] = 'b'; + map2[a4] = 'c'; + + // mapMin(), mapMax(), mapMinValue(), mapMaxValue() + check(mapMin(g, map2) == a2, "Wrong mapMin()"); + check(mapMax(g, map2) == a4, "Wrong mapMax()"); + check(mapMin(g, map2, std::greater()) == a4, "Wrong mapMin()"); + check(mapMax(g, map2, std::greater()) == a2, "Wrong mapMax()"); + check(mapMinValue(g, map2, std::greater()) == 'c', + "Wrong mapMinValue()"); + check(mapMaxValue(g, map2, std::greater()) == 'a', + "Wrong mapMaxValue()"); + + check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()"); + check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()"); + check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()"); + + check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2, + "Wrong mapMin()"); + check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4, + "Wrong mapMax()"); + check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'), + "Wrong mapMinValue()"); + check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'), + "Wrong mapMaxValue()"); + + // mapFind(), mapFindIf() + check(mapFind(g, map1, 5) == n2, "Wrong mapFind()"); + check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()"); + check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()"); + check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()"); + check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()"); + check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()"); + + check(mapFindIf(g, map1, Less(7)) == n2, + "Wrong mapFindIf()"); + check(mapFindIf(g, map1, Less(5)) == INVALID, + "Wrong mapFindIf()"); + check(mapFindIf(g, map2, Less('d')) == ArcIt(g), + "Wrong mapFindIf()"); + check(mapFindIf(g, map2, Less('a')) == INVALID, + "Wrong mapFindIf()"); + + // mapCount(), mapCountIf() + check(mapCount(g, map1, 5) == 1, "Wrong mapCount()"); + check(mapCount(g, map1, 6) == 0, "Wrong mapCount()"); + check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()"); + check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()"); + check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()"); + check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()"); + check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()"); + + check(mapCountIf(g, map1, Less(11)) == 2, + "Wrong mapCountIf()"); + check(mapCountIf(g, map1, Less(13)) == 3, + "Wrong mapCountIf()"); + check(mapCountIf(g, map1, Less(5)) == 0, + "Wrong mapCountIf()"); + check(mapCountIf(g, map2, Less('d')) == 4, + "Wrong mapCountIf()"); + check(mapCountIf(g, map2, Less('c')) == 3, + "Wrong mapCountIf()"); + check(mapCountIf(g, map2, Less('a')) == 0, + "Wrong mapCountIf()"); + + // MapIt, ConstMapIt +/* +These tests can be used after applying bugfix #330 + typedef SmartDigraph::NodeMap::MapIt MapIt; + typedef SmartDigraph::NodeMap::ConstMapIt ConstMapIt; + check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5, + "Wrong NodeMap<>::MapIt"); + check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12, + "Wrong NodeMap<>::MapIt"); + + int sum = 0; + std::for_each(MapIt(map1), MapIt(INVALID), Sum(sum)); + check(sum == 27, "Wrong NodeMap<>::MapIt"); + std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum(sum)); + check(sum == 54, "Wrong NodeMap<>::ConstMapIt"); +*/ + + // mapCopy(), mapCompare(), mapFill() + check(mapCompare(g, map1, map1), "Wrong mapCompare()"); + check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()"); + check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()"); + check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()"); + check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()"); + + SmartDigraph::NodeMap map3(g, 0); + SmartDigraph::ArcMap map4(g, 'a'); + + check(!mapCompare(g, map1, map3), "Wrong mapCompare()"); + check(!mapCompare(g, map2, map4), "Wrong mapCompare()"); + + mapCopy(g, map1, map3); + mapCopy(g, map2, map4); + + check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()"); + check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()"); + + Undirector ug(g); + Undirector::EdgeMap umap1(ug, 'x'); + Undirector::ArcMap umap2(ug, 3.14); + + check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()"); + check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()"); + check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()"); + check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()"); + + mapCopy(g, map2, umap1); + + check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()"); + check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()"); + check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()"); + check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()"); + + mapCopy(g, map2, umap1); + mapCopy(g, umap1, map2); + mapCopy(ug, map2, umap1); + mapCopy(ug, umap1, map2); + + check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()"); + mapCopy(ug, umap1, umap2); + check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()"); + + check(!mapCompare(g, map1, constMap(2)), "Wrong mapCompare()"); + mapFill(g, map1, 2); + check(mapCompare(g, constMap(2), map1), "Wrong mapFill()"); + + check(!mapCompare(g, map2, constMap('z')), "Wrong mapCompare()"); + mapCopy(g, constMap('z'), map2); + check(mapCompare(g, constMap('z'), map2), "Wrong mapCopy()"); + } + + return 0; +} diff --git a/lemon/test/matching_test.cc b/lemon/test/matching_test.cc new file mode 100644 index 0000000..7386057 --- /dev/null +++ b/lemon/test/matching_test.cc @@ -0,0 +1,448 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace std; +using namespace lemon; + +GRAPH_TYPEDEFS(SmartGraph); + + +const int lgfn = 3; +const std::string lgf[lgfn] = { + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "@edges\n" + " label weight\n" + "7 4 0 984\n" + "0 7 1 73\n" + "7 1 2 204\n" + "2 3 3 583\n" + "2 7 4 565\n" + "2 1 5 582\n" + "0 4 6 551\n" + "2 5 7 385\n" + "1 5 8 561\n" + "5 3 9 484\n" + "7 5 10 904\n" + "3 6 11 47\n" + "7 6 12 888\n" + "3 0 13 747\n" + "6 1 14 310\n", + + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "@edges\n" + " label weight\n" + "2 5 0 710\n" + "0 5 1 241\n" + "2 4 2 856\n" + "2 6 3 762\n" + "4 1 4 747\n" + "6 1 5 962\n" + "4 7 6 723\n" + "1 7 7 661\n" + "2 3 8 376\n" + "1 0 9 416\n" + "6 7 10 391\n", + + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "@edges\n" + " label weight\n" + "6 2 0 553\n" + "0 7 1 653\n" + "6 3 2 22\n" + "4 7 3 846\n" + "7 2 4 981\n" + "7 6 5 250\n" + "5 2 6 539\n", +}; + +void checkMaxMatchingCompile() +{ + typedef concepts::Graph Graph; + typedef Graph::Node Node; + typedef Graph::Edge Edge; + typedef Graph::EdgeMap MatMap; + + Graph g; + Node n; + Edge e; + MatMap mat(g); + + MaxMatching mat_test(g); + const MaxMatching& + const_mat_test = mat_test; + + mat_test.init(); + mat_test.greedyInit(); + mat_test.matchingInit(mat); + mat_test.startSparse(); + mat_test.startDense(); + mat_test.run(); + + const_mat_test.matchingSize(); + const_mat_test.matching(e); + const_mat_test.matching(n); + const MaxMatching::MatchingMap& mmap = + const_mat_test.matchingMap(); + e = mmap[n]; + const_mat_test.mate(n); + + MaxMatching::Status stat = + const_mat_test.status(n); + const MaxMatching::StatusMap& smap = + const_mat_test.statusMap(); + stat = smap[n]; + const_mat_test.barrier(n); +} + +void checkMaxWeightedMatchingCompile() +{ + typedef concepts::Graph Graph; + typedef Graph::Node Node; + typedef Graph::Edge Edge; + typedef Graph::EdgeMap WeightMap; + + Graph g; + Node n; + Edge e; + WeightMap w(g); + + MaxWeightedMatching mat_test(g, w); + const MaxWeightedMatching& + const_mat_test = mat_test; + + mat_test.init(); + mat_test.start(); + mat_test.run(); + + const_mat_test.matchingWeight(); + const_mat_test.matchingSize(); + const_mat_test.matching(e); + const_mat_test.matching(n); + const MaxWeightedMatching::MatchingMap& mmap = + const_mat_test.matchingMap(); + e = mmap[n]; + const_mat_test.mate(n); + + int k = 0; + const_mat_test.dualValue(); + const_mat_test.nodeValue(n); + const_mat_test.blossomNum(); + const_mat_test.blossomSize(k); + const_mat_test.blossomValue(k); +} + +void checkMaxWeightedPerfectMatchingCompile() +{ + typedef concepts::Graph Graph; + typedef Graph::Node Node; + typedef Graph::Edge Edge; + typedef Graph::EdgeMap WeightMap; + + Graph g; + Node n; + Edge e; + WeightMap w(g); + + MaxWeightedPerfectMatching mat_test(g, w); + const MaxWeightedPerfectMatching& + const_mat_test = mat_test; + + mat_test.init(); + mat_test.start(); + mat_test.run(); + + const_mat_test.matchingWeight(); + const_mat_test.matching(e); + const_mat_test.matching(n); + const MaxWeightedPerfectMatching::MatchingMap& mmap = + const_mat_test.matchingMap(); + e = mmap[n]; + const_mat_test.mate(n); + + int k = 0; + const_mat_test.dualValue(); + const_mat_test.nodeValue(n); + const_mat_test.blossomNum(); + const_mat_test.blossomSize(k); + const_mat_test.blossomValue(k); +} + +void checkMatching(const SmartGraph& graph, + const MaxMatching& mm) { + int num = 0; + + IntNodeMap comp_index(graph); + UnionFind comp(comp_index); + + int barrier_num = 0; + + for (NodeIt n(graph); n != INVALID; ++n) { + check(mm.status(n) == MaxMatching::EVEN || + mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition"); + if (mm.status(n) == MaxMatching::ODD) { + ++barrier_num; + } else { + comp.insert(n); + } + } + + for (EdgeIt e(graph); e != INVALID; ++e) { + if (mm.matching(e)) { + check(e == mm.matching(graph.u(e)), "Wrong matching"); + check(e == mm.matching(graph.v(e)), "Wrong matching"); + ++num; + } + check(mm.status(graph.u(e)) != MaxMatching::EVEN || + mm.status(graph.v(e)) != MaxMatching::MATCHED, + "Wrong Gallai-Edmonds decomposition"); + + check(mm.status(graph.v(e)) != MaxMatching::EVEN || + mm.status(graph.u(e)) != MaxMatching::MATCHED, + "Wrong Gallai-Edmonds decomposition"); + + if (mm.status(graph.u(e)) != MaxMatching::ODD && + mm.status(graph.v(e)) != MaxMatching::ODD) { + comp.join(graph.u(e), graph.v(e)); + } + } + + std::set comp_root; + int odd_comp_num = 0; + for (NodeIt n(graph); n != INVALID; ++n) { + if (mm.status(n) != MaxMatching::ODD) { + int root = comp.find(n); + if (comp_root.find(root) == comp_root.end()) { + comp_root.insert(root); + if (comp.size(n) % 2 == 1) { + ++odd_comp_num; + } + } + } + } + + check(mm.matchingSize() == num, "Wrong matching"); + check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num), + "Wrong matching"); + return; +} + +void checkWeightedMatching(const SmartGraph& graph, + const SmartGraph::EdgeMap& weight, + const MaxWeightedMatching& mwm) { + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + if (graph.u(e) == graph.v(e)) continue; + int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e)); + + for (int i = 0; i < mwm.blossomNum(); ++i) { + bool s = false, t = false; + for (MaxWeightedMatching::BlossomIt n(mwm, i); + n != INVALID; ++n) { + if (graph.u(e) == n) s = true; + if (graph.v(e) == n) t = true; + } + if (s == true && t == true) { + rw += mwm.blossomValue(i); + } + } + rw -= weight[e] * mwm.dualScale; + + check(rw >= 0, "Negative reduced weight"); + check(rw == 0 || !mwm.matching(e), + "Non-zero reduced weight on matching edge"); + } + + int pv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + if (mwm.matching(n) != INVALID) { + check(mwm.nodeValue(n) >= 0, "Invalid node value"); + pv += weight[mwm.matching(n)]; + SmartGraph::Node o = graph.target(mwm.matching(n)); + check(mwm.mate(n) == o, "Invalid matching"); + check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)), + "Invalid matching"); + } else { + check(mwm.mate(n) == INVALID, "Invalid matching"); + check(mwm.nodeValue(n) == 0, "Invalid matching"); + } + } + + int dv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + dv += mwm.nodeValue(n); + } + + for (int i = 0; i < mwm.blossomNum(); ++i) { + check(mwm.blossomValue(i) >= 0, "Invalid blossom value"); + check(mwm.blossomSize(i) % 2 == 1, "Even blossom size"); + dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2); + } + + check(pv * mwm.dualScale == dv * 2, "Wrong duality"); + + return; +} + +void checkWeightedPerfectMatching(const SmartGraph& graph, + const SmartGraph::EdgeMap& weight, + const MaxWeightedPerfectMatching& mwpm) { + for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) { + if (graph.u(e) == graph.v(e)) continue; + int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e)); + + for (int i = 0; i < mwpm.blossomNum(); ++i) { + bool s = false, t = false; + for (MaxWeightedPerfectMatching::BlossomIt n(mwpm, i); + n != INVALID; ++n) { + if (graph.u(e) == n) s = true; + if (graph.v(e) == n) t = true; + } + if (s == true && t == true) { + rw += mwpm.blossomValue(i); + } + } + rw -= weight[e] * mwpm.dualScale; + + check(rw >= 0, "Negative reduced weight"); + check(rw == 0 || !mwpm.matching(e), + "Non-zero reduced weight on matching edge"); + } + + int pv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + check(mwpm.matching(n) != INVALID, "Non perfect"); + pv += weight[mwpm.matching(n)]; + SmartGraph::Node o = graph.target(mwpm.matching(n)); + check(mwpm.mate(n) == o, "Invalid matching"); + check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)), + "Invalid matching"); + } + + int dv = 0; + for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) { + dv += mwpm.nodeValue(n); + } + + for (int i = 0; i < mwpm.blossomNum(); ++i) { + check(mwpm.blossomValue(i) >= 0, "Invalid blossom value"); + check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size"); + dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2); + } + + check(pv * mwpm.dualScale == dv * 2, "Wrong duality"); + + return; +} + + +int main() { + + for (int i = 0; i < lgfn; ++i) { + SmartGraph graph; + SmartGraph::EdgeMap weight(graph); + + istringstream lgfs(lgf[i]); + graphReader(graph, lgfs). + edgeMap("weight", weight).run(); + + bool perfect; + { + MaxMatching mm(graph); + mm.run(); + checkMatching(graph, mm); + perfect = 2 * mm.matchingSize() == countNodes(graph); + } + + { + MaxWeightedMatching mwm(graph, weight); + mwm.run(); + checkWeightedMatching(graph, weight, mwm); + } + + { + MaxWeightedMatching mwm(graph, weight); + mwm.init(); + mwm.start(); + checkWeightedMatching(graph, weight, mwm); + } + + { + MaxWeightedPerfectMatching mwpm(graph, weight); + bool result = mwpm.run(); + + check(result == perfect, "Perfect matching found"); + if (perfect) { + checkWeightedPerfectMatching(graph, weight, mwpm); + } + } + + { + MaxWeightedPerfectMatching mwpm(graph, weight); + mwpm.init(); + bool result = mwpm.start(); + + check(result == perfect, "Perfect matching found"); + if (perfect) { + checkWeightedPerfectMatching(graph, weight, mwpm); + } + } + } + + return 0; +} diff --git a/lemon/test/min_cost_arborescence_test.cc b/lemon/test/min_cost_arborescence_test.cc new file mode 100644 index 0000000..5bcba83 --- /dev/null +++ b/lemon/test/min_cost_arborescence_test.cc @@ -0,0 +1,206 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; +using namespace std; + +const char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "8\n" + "9\n" + "@arcs\n" + " label cost\n" + "1 8 0 107\n" + "0 3 1 70\n" + "2 1 2 46\n" + "4 1 3 28\n" + "4 4 4 91\n" + "3 9 5 76\n" + "9 8 6 61\n" + "8 1 7 39\n" + "9 8 8 74\n" + "8 0 9 39\n" + "4 3 10 45\n" + "2 2 11 34\n" + "0 1 12 100\n" + "6 3 13 95\n" + "4 1 14 22\n" + "1 1 15 31\n" + "7 2 16 51\n" + "2 6 17 29\n" + "8 3 18 115\n" + "6 9 19 32\n" + "1 1 20 60\n" + "0 3 21 40\n" + "@attributes\n" + "source 0\n"; + + +void checkMinCostArborescenceCompile() +{ + typedef double VType; + typedef concepts::Digraph Digraph; + typedef concepts::ReadMap CostMap; + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + typedef concepts::WriteMap ArbMap; + typedef concepts::ReadWriteMap PredMap; + + typedef MinCostArborescence:: + SetArborescenceMap:: + SetPredMap::Create MinCostArbType; + + Digraph g; + Node s, n; + Arc e; + VType c; + bool b; + int i; + CostMap cost; + ArbMap arb; + PredMap pred; + + MinCostArbType mcarb_test(g, cost); + const MinCostArbType& const_mcarb_test = mcarb_test; + + mcarb_test + .arborescenceMap(arb) + .predMap(pred) + .run(s); + + mcarb_test.init(); + mcarb_test.addSource(s); + mcarb_test.start(); + n = mcarb_test.processNextNode(); + b = const_mcarb_test.emptyQueue(); + i = const_mcarb_test.queueSize(); + + c = const_mcarb_test.arborescenceCost(); + b = const_mcarb_test.arborescence(e); + e = const_mcarb_test.pred(n); + const MinCostArbType::ArborescenceMap &am = + const_mcarb_test.arborescenceMap(); + const MinCostArbType::PredMap &pm = + const_mcarb_test.predMap(); + b = const_mcarb_test.reached(n); + b = const_mcarb_test.processed(n); + + i = const_mcarb_test.dualNum(); + c = const_mcarb_test.dualValue(); + i = const_mcarb_test.dualSize(i); + c = const_mcarb_test.dualValue(i); + + ignore_unused_variable_warning(am); + ignore_unused_variable_warning(pm); +} + +int main() { + typedef SmartDigraph Digraph; + DIGRAPH_TYPEDEFS(Digraph); + + typedef Digraph::ArcMap CostMap; + + Digraph digraph; + CostMap cost(digraph); + Node source; + + std::istringstream is(test_lgf); + digraphReader(digraph, is). + arcMap("cost", cost). + node("source", source).run(); + + MinCostArborescence mca(digraph, cost); + mca.run(source); + + vector > > dualSolution(mca.dualNum()); + + for (int i = 0; i < mca.dualNum(); ++i) { + dualSolution[i].first = mca.dualValue(i); + for (MinCostArborescence::DualIt it(mca, i); + it != INVALID; ++it) { + dualSolution[i].second.insert(it); + } + } + + for (ArcIt it(digraph); it != INVALID; ++it) { + if (mca.reached(digraph.source(it))) { + double sum = 0.0; + for (int i = 0; i < int(dualSolution.size()); ++i) { + if (dualSolution[i].second.find(digraph.target(it)) + != dualSolution[i].second.end() && + dualSolution[i].second.find(digraph.source(it)) + == dualSolution[i].second.end()) { + sum += dualSolution[i].first; + } + } + if (mca.arborescence(it)) { + check(sum == cost[it], "Invalid dual solution"); + } + check(sum <= cost[it], "Invalid dual solution"); + } + } + + + check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution"); + + check(mca.reached(source), "Invalid arborescence"); + for (ArcIt a(digraph); a != INVALID; ++a) { + check(!mca.reached(digraph.source(a)) || + mca.reached(digraph.target(a)), "Invalid arborescence"); + } + + for (NodeIt n(digraph); n != INVALID; ++n) { + if (!mca.reached(n)) continue; + int cnt = 0; + for (InArcIt a(digraph, n); a != INVALID; ++a) { + if (mca.arborescence(a)) { + check(mca.pred(n) == a, "Invalid arborescence"); + ++cnt; + } + } + check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence"); + } + + Digraph::ArcMap arborescence(digraph); + check(mca.arborescenceCost() == + minCostArborescence(digraph, cost, source, arborescence), + "Wrong result of the function interface"); + + return 0; +} diff --git a/lemon/test/min_cost_flow_test.cc b/lemon/test/min_cost_flow_test.cc new file mode 100644 index 0000000..fa975ec --- /dev/null +++ b/lemon/test/min_cost_flow_test.cc @@ -0,0 +1,542 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; + +// Test networks +char test_lgf[] = + "@nodes\n" + "label sup1 sup2 sup3 sup4 sup5 sup6\n" + " 1 20 27 0 30 20 30\n" + " 2 -4 0 0 0 -8 -3\n" + " 3 0 0 0 0 0 0\n" + " 4 0 0 0 0 0 0\n" + " 5 9 0 0 0 6 11\n" + " 6 -6 0 0 0 -5 -6\n" + " 7 0 0 0 0 0 0\n" + " 8 0 0 0 0 0 3\n" + " 9 3 0 0 0 0 0\n" + " 10 -2 0 0 0 -7 -2\n" + " 11 0 0 0 0 -10 0\n" + " 12 -20 -27 0 -30 -30 -20\n" + "\n" + "@arcs\n" + " cost cap low1 low2 low3\n" + " 1 2 70 11 0 8 8\n" + " 1 3 150 3 0 1 0\n" + " 1 4 80 15 0 2 2\n" + " 2 8 80 12 0 0 0\n" + " 3 5 140 5 0 3 1\n" + " 4 6 60 10 0 1 0\n" + " 4 7 80 2 0 0 0\n" + " 4 8 110 3 0 0 0\n" + " 5 7 60 14 0 0 0\n" + " 5 11 120 12 0 0 0\n" + " 6 3 0 3 0 0 0\n" + " 6 9 140 4 0 0 0\n" + " 6 10 90 8 0 0 0\n" + " 7 1 30 5 0 0 -5\n" + " 8 12 60 16 0 4 3\n" + " 9 12 50 6 0 0 0\n" + "10 12 70 13 0 5 2\n" + "10 2 100 7 0 0 0\n" + "10 7 60 10 0 0 -3\n" + "11 10 20 14 0 6 -20\n" + "12 11 30 10 0 0 -10\n" + "\n" + "@attributes\n" + "source 1\n" + "target 12\n"; + +char test_neg1_lgf[] = + "@nodes\n" + "label sup\n" + " 1 100\n" + " 2 0\n" + " 3 0\n" + " 4 -100\n" + " 5 0\n" + " 6 0\n" + " 7 0\n" + "@arcs\n" + " cost low1 low2\n" + "1 2 100 0 0\n" + "1 3 30 0 0\n" + "2 4 20 0 0\n" + "3 4 80 0 0\n" + "3 2 50 0 0\n" + "5 3 10 0 0\n" + "5 6 80 0 1000\n" + "6 7 30 0 -1000\n" + "7 5 -120 0 0\n"; + +char test_neg2_lgf[] = + "@nodes\n" + "label sup\n" + " 1 100\n" + " 2 -300\n" + "@arcs\n" + " cost\n" + "1 2 -1\n"; + + +// Test data +typedef ListDigraph Digraph; +DIGRAPH_TYPEDEFS(ListDigraph); + +Digraph gr; +Digraph::ArcMap c(gr), l1(gr), l2(gr), l3(gr), u(gr); +Digraph::NodeMap s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr); +ConstMap cc(1), cu(std::numeric_limits::max()); +Node v, w; + +Digraph neg1_gr; +Digraph::ArcMap neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr); +ConstMap neg1_u1(std::numeric_limits::max()), neg1_u2(5000); +Digraph::NodeMap neg1_s(neg1_gr); + +Digraph neg2_gr; +Digraph::ArcMap neg2_c(neg2_gr); +ConstMap neg2_l(0), neg2_u(1000); +Digraph::NodeMap neg2_s(neg2_gr); + + +enum SupplyType { + EQ, + GEQ, + LEQ +}; + + +// Check the interface of an MCF algorithm +template +class McfClassConcept +{ +public: + + template + struct Constraints { + void constraints() { + checkConcept(); + + const Constraints& me = *this; + + MCF mcf(me.g); + const MCF& const_mcf = mcf; + + b = mcf.reset().resetParams() + .lowerMap(me.lower) + .upperMap(me.upper) + .costMap(me.cost) + .supplyMap(me.sup) + .stSupply(me.n, me.n, me.k) + .run(); + + c = const_mcf.totalCost(); + x = const_mcf.template totalCost(); + v = const_mcf.flow(me.a); + c = const_mcf.potential(me.n); + const_mcf.flowMap(fm); + const_mcf.potentialMap(pm); + } + + typedef typename GR::Node Node; + typedef typename GR::Arc Arc; + typedef concepts::ReadMap NM; + typedef concepts::ReadMap VAM; + typedef concepts::ReadMap CAM; + typedef concepts::WriteMap FlowMap; + typedef concepts::WriteMap PotMap; + + GR g; + VAM lower; + VAM upper; + CAM cost; + NM sup; + Node n; + Arc a; + Value k; + + FlowMap fm; + PotMap pm; + bool b; + double x; + typename MCF::Value v; + typename MCF::Cost c; + }; + +}; + + +// Check the feasibility of the given flow (primal soluiton) +template < typename GR, typename LM, typename UM, + typename SM, typename FM > +bool checkFlow( const GR& gr, const LM& lower, const UM& upper, + const SM& supply, const FM& flow, + SupplyType type = EQ ) +{ + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + for (ArcIt e(gr); e != INVALID; ++e) { + if (flow[e] < lower[e] || flow[e] > upper[e]) return false; + } + + for (NodeIt n(gr); n != INVALID; ++n) { + typename SM::Value sum = 0; + for (OutArcIt e(gr, n); e != INVALID; ++e) + sum += flow[e]; + for (InArcIt e(gr, n); e != INVALID; ++e) + sum -= flow[e]; + bool b = (type == EQ && sum == supply[n]) || + (type == GEQ && sum >= supply[n]) || + (type == LEQ && sum <= supply[n]); + if (!b) return false; + } + + return true; +} + +// Check the feasibility of the given potentials (dual soluiton) +// using the "Complementary Slackness" optimality condition +template < typename GR, typename LM, typename UM, + typename CM, typename SM, typename FM, typename PM > +bool checkPotential( const GR& gr, const LM& lower, const UM& upper, + const CM& cost, const SM& supply, const FM& flow, + const PM& pi, SupplyType type ) +{ + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + bool opt = true; + for (ArcIt e(gr); opt && e != INVALID; ++e) { + typename CM::Value red_cost = + cost[e] + pi[gr.source(e)] - pi[gr.target(e)]; + opt = red_cost == 0 || + (red_cost > 0 && flow[e] == lower[e]) || + (red_cost < 0 && flow[e] == upper[e]); + } + + for (NodeIt n(gr); opt && n != INVALID; ++n) { + typename SM::Value sum = 0; + for (OutArcIt e(gr, n); e != INVALID; ++e) + sum += flow[e]; + for (InArcIt e(gr, n); e != INVALID; ++e) + sum -= flow[e]; + if (type != LEQ) { + opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0); + } else { + opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0); + } + } + + return opt; +} + +// Check whether the dual cost is equal to the primal cost +template < typename GR, typename LM, typename UM, + typename CM, typename SM, typename PM > +bool checkDualCost( const GR& gr, const LM& lower, const UM& upper, + const CM& cost, const SM& supply, const PM& pi, + typename CM::Value total ) +{ + TEMPLATE_DIGRAPH_TYPEDEFS(GR); + + typename CM::Value dual_cost = 0; + SM red_supply(gr); + for (NodeIt n(gr); n != INVALID; ++n) { + red_supply[n] = supply[n]; + } + for (ArcIt a(gr); a != INVALID; ++a) { + if (lower[a] != 0) { + dual_cost += lower[a] * cost[a]; + red_supply[gr.source(a)] -= lower[a]; + red_supply[gr.target(a)] += lower[a]; + } + } + + for (NodeIt n(gr); n != INVALID; ++n) { + dual_cost -= red_supply[n] * pi[n]; + } + for (ArcIt a(gr); a != INVALID; ++a) { + typename CM::Value red_cost = + cost[a] + pi[gr.source(a)] - pi[gr.target(a)]; + dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0); + } + + return dual_cost == total; +} + +// Run a minimum cost flow algorithm and check the results +template < typename MCF, typename GR, + typename LM, typename UM, + typename CM, typename SM, + typename PT > +void checkMcf( const MCF& mcf, PT mcf_result, + const GR& gr, const LM& lower, const UM& upper, + const CM& cost, const SM& supply, + PT result, bool optimal, typename CM::Value total, + const std::string &test_id = "", + SupplyType type = EQ ) +{ + check(mcf_result == result, "Wrong result " + test_id); + if (optimal) { + typename GR::template ArcMap flow(gr); + typename GR::template NodeMap pi(gr); + mcf.flowMap(flow); + mcf.potentialMap(pi); + check(checkFlow(gr, lower, upper, supply, flow, type), + "The flow is not feasible " + test_id); + check(mcf.totalCost() == total, "The flow is not optimal " + test_id); + check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type), + "Wrong potentials " + test_id); + check(checkDualCost(gr, lower, upper, cost, supply, pi, total), + "Wrong dual cost " + test_id); + } +} + +template < typename MCF, typename Param > +void runMcfGeqTests( Param param, + const std::string &test_str = "", + bool full_neg_cost_support = false ) +{ + MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr); + + // Basic tests + mcf1.upperMap(u).costMap(c).supplyMap(s1); + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1, + mcf1.OPTIMAL, true, 5240, test_str + "-1"); + mcf1.stSupply(v, w, 27); + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2, + mcf1.OPTIMAL, true, 7620, test_str + "-2"); + mcf1.lowerMap(l2).supplyMap(s1); + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1, + mcf1.OPTIMAL, true, 5970, test_str + "-3"); + mcf1.stSupply(v, w, 27); + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2, + mcf1.OPTIMAL, true, 8010, test_str + "-4"); + mcf1.resetParams().supplyMap(s1); + checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1, + mcf1.OPTIMAL, true, 74, test_str + "-5"); + mcf1.lowerMap(l2).stSupply(v, w, 27); + checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2, + mcf1.OPTIMAL, true, 94, test_str + "-6"); + mcf1.reset(); + checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3, + mcf1.OPTIMAL, true, 0, test_str + "-7"); + mcf1.lowerMap(l2).upperMap(u); + checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3, + mcf1.INFEASIBLE, false, 0, test_str + "-8"); + mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4); + checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4, + mcf1.OPTIMAL, true, 6360, test_str + "-9"); + + // Tests for the GEQ form + mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5); + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5, + mcf1.OPTIMAL, true, 3530, test_str + "-10", GEQ); + mcf1.lowerMap(l2); + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5, + mcf1.OPTIMAL, true, 4540, test_str + "-11", GEQ); + mcf1.supplyMap(s6); + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6, + mcf1.INFEASIBLE, false, 0, test_str + "-12", GEQ); + + // Tests with negative costs + mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s); + checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s, + mcf2.UNBOUNDED, false, 0, test_str + "-13"); + mcf2.upperMap(neg1_u2); + checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s, + mcf2.OPTIMAL, true, -40000, test_str + "-14"); + mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s); + checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s, + mcf2.UNBOUNDED, false, 0, test_str + "-15"); + + mcf3.costMap(neg2_c).supplyMap(neg2_s); + if (full_neg_cost_support) { + checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s, + mcf3.OPTIMAL, true, -300, test_str + "-16", GEQ); + } else { + checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s, + mcf3.UNBOUNDED, false, 0, test_str + "-17", GEQ); + } + mcf3.upperMap(neg2_u); + checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s, + mcf3.OPTIMAL, true, -300, test_str + "-18", GEQ); +} + +template < typename MCF, typename Param > +void runMcfLeqTests( Param param, + const std::string &test_str = "" ) +{ + // Tests for the LEQ form + MCF mcf1(gr); + mcf1.supplyType(mcf1.LEQ); + mcf1.upperMap(u).costMap(c).supplyMap(s6); + checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6, + mcf1.OPTIMAL, true, 5080, test_str + "-19", LEQ); + mcf1.lowerMap(l2); + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6, + mcf1.OPTIMAL, true, 5930, test_str + "-20", LEQ); + mcf1.supplyMap(s5); + checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5, + mcf1.INFEASIBLE, false, 0, test_str + "-21", LEQ); +} + + +int main() +{ + // Read the test networks + std::istringstream input(test_lgf); + DigraphReader(gr, input) + .arcMap("cost", c) + .arcMap("cap", u) + .arcMap("low1", l1) + .arcMap("low2", l2) + .arcMap("low3", l3) + .nodeMap("sup1", s1) + .nodeMap("sup2", s2) + .nodeMap("sup3", s3) + .nodeMap("sup4", s4) + .nodeMap("sup5", s5) + .nodeMap("sup6", s6) + .node("source", v) + .node("target", w) + .run(); + + std::istringstream neg_inp1(test_neg1_lgf); + DigraphReader(neg1_gr, neg_inp1) + .arcMap("cost", neg1_c) + .arcMap("low1", neg1_l1) + .arcMap("low2", neg1_l2) + .nodeMap("sup", neg1_s) + .run(); + + std::istringstream neg_inp2(test_neg2_lgf); + DigraphReader(neg2_gr, neg_inp2) + .arcMap("cost", neg2_c) + .nodeMap("sup", neg2_s) + .run(); + + // Check the interface of NetworkSimplex + { + typedef concepts::Digraph GR; + checkConcept< McfClassConcept, + NetworkSimplex >(); + checkConcept< McfClassConcept, + NetworkSimplex >(); + checkConcept< McfClassConcept, + NetworkSimplex >(); + } + + // Check the interface of CapacityScaling + { + typedef concepts::Digraph GR; + checkConcept< McfClassConcept, + CapacityScaling >(); + checkConcept< McfClassConcept, + CapacityScaling >(); + checkConcept< McfClassConcept, + CapacityScaling >(); + typedef CapacityScaling:: + SetHeap > >::Create CAS; + checkConcept< McfClassConcept, CAS >(); + } + + // Check the interface of CostScaling + { + typedef concepts::Digraph GR; + checkConcept< McfClassConcept, + CostScaling >(); + checkConcept< McfClassConcept, + CostScaling >(); + checkConcept< McfClassConcept, + CostScaling >(); + typedef CostScaling:: + SetLargeCost::Create COS; + checkConcept< McfClassConcept, COS >(); + } + + // Check the interface of CycleCanceling + { + typedef concepts::Digraph GR; + checkConcept< McfClassConcept, + CycleCanceling >(); + checkConcept< McfClassConcept, + CycleCanceling >(); + checkConcept< McfClassConcept, + CycleCanceling >(); + } + + // Test NetworkSimplex + { + typedef NetworkSimplex MCF; + runMcfGeqTests(MCF::FIRST_ELIGIBLE, "NS-FE", true); + runMcfLeqTests(MCF::FIRST_ELIGIBLE, "NS-FE"); + runMcfGeqTests(MCF::BEST_ELIGIBLE, "NS-BE", true); + runMcfLeqTests(MCF::BEST_ELIGIBLE, "NS-BE"); + runMcfGeqTests(MCF::BLOCK_SEARCH, "NS-BS", true); + runMcfLeqTests(MCF::BLOCK_SEARCH, "NS-BS"); + runMcfGeqTests(MCF::CANDIDATE_LIST, "NS-CL", true); + runMcfLeqTests(MCF::CANDIDATE_LIST, "NS-CL"); + runMcfGeqTests(MCF::ALTERING_LIST, "NS-AL", true); + runMcfLeqTests(MCF::ALTERING_LIST, "NS-AL"); + } + + // Test CapacityScaling + { + typedef CapacityScaling MCF; + runMcfGeqTests(0, "SSP"); + runMcfGeqTests(2, "CAS"); + } + + // Test CostScaling + { + typedef CostScaling MCF; + runMcfGeqTests(MCF::PUSH, "COS-PR"); + runMcfGeqTests(MCF::AUGMENT, "COS-AR"); + runMcfGeqTests(MCF::PARTIAL_AUGMENT, "COS-PAR"); + } + + // Test CycleCanceling + { + typedef CycleCanceling MCF; + runMcfGeqTests(MCF::SIMPLE_CYCLE_CANCELING, "SCC"); + runMcfGeqTests(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC"); + runMcfGeqTests(MCF::CANCEL_AND_TIGHTEN, "CAT"); + } + + return 0; +} diff --git a/lemon/test/min_mean_cycle_test.cc b/lemon/test/min_mean_cycle_test.cc new file mode 100644 index 0000000..e9fb8da --- /dev/null +++ b/lemon/test/min_mean_cycle_test.cc @@ -0,0 +1,216 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "@arcs\n" + " len1 len2 len3 len4 c1 c2 c3 c4\n" + "1 2 1 1 1 1 0 0 0 0\n" + "2 4 5 5 5 5 1 0 0 0\n" + "2 3 8 8 8 8 0 0 0 0\n" + "3 2 -2 0 0 0 1 0 0 0\n" + "3 4 4 4 4 4 0 0 0 0\n" + "3 7 -4 -4 -4 -4 0 0 0 0\n" + "4 1 2 2 2 2 0 0 0 0\n" + "4 3 3 3 3 3 1 0 0 0\n" + "4 4 3 3 0 0 0 0 1 0\n" + "5 2 4 4 4 4 0 0 0 0\n" + "5 6 3 3 3 3 0 1 0 0\n" + "6 5 2 2 2 2 0 1 0 0\n" + "6 4 -1 -1 -1 -1 0 0 0 0\n" + "6 7 1 1 1 1 0 0 0 0\n" + "7 7 4 4 4 -1 0 0 0 1\n"; + + +// Check the interface of an MMC algorithm +template +struct MmcClassConcept +{ + template + struct Constraints { + void constraints() { + const Constraints& me = *this; + + typedef typename MMC + ::template SetPath > + ::template SetLargeCost + ::Create MmcAlg; + MmcAlg mmc(me.g, me.cost); + const MmcAlg& const_mmc = mmc; + + typename MmcAlg::Tolerance tol = const_mmc.tolerance(); + mmc.tolerance(tol); + + b = mmc.cycle(p).run(); + b = mmc.findCycleMean(); + b = mmc.findCycle(); + + v = const_mmc.cycleCost(); + i = const_mmc.cycleSize(); + d = const_mmc.cycleMean(); + p = const_mmc.cycle(); + } + + typedef concepts::ReadMap CM; + + GR g; + CM cost; + ListPath p; + Cost v; + int i; + double d; + bool b; + }; +}; + +// Perform a test with the given parameters +template +void checkMmcAlg(const SmartDigraph& gr, + const SmartDigraph::ArcMap& lm, + const SmartDigraph::ArcMap& cm, + int cost, int size) { + MMC alg(gr, lm); + alg.findCycleMean(); + check(alg.cycleMean() == static_cast(cost) / size, + "Wrong cycle mean"); + alg.findCycle(); + check(alg.cycleCost() == cost && alg.cycleSize() == size, + "Wrong path"); + SmartDigraph::ArcMap cycle(gr, 0); + for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) { + ++cycle[a]; + } + for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) { + check(cm[a] == cycle[a], "Wrong path"); + } +} + +// Class for comparing types +template +struct IsSameType { + static const int result = 0; +}; + +template +struct IsSameType { + static const int result = 1; +}; + + +int main() { + #ifdef LEMON_HAVE_LONG_LONG + typedef long long long_int; + #else + typedef long long_int; + #endif + + // Check the interface + { + typedef concepts::Digraph GR; + + // KarpMmc + checkConcept< MmcClassConcept, + KarpMmc > >(); + checkConcept< MmcClassConcept, + KarpMmc > >(); + + // HartmannOrlinMmc + checkConcept< MmcClassConcept, + HartmannOrlinMmc > >(); + checkConcept< MmcClassConcept, + HartmannOrlinMmc > >(); + + // HowardMmc + checkConcept< MmcClassConcept, + HowardMmc > >(); + checkConcept< MmcClassConcept, + HowardMmc > >(); + + check((IsSameType > + ::LargeCost, long_int>::result == 1), "Wrong LargeCost type"); + check((IsSameType > + ::LargeCost, double>::result == 1), "Wrong LargeCost type"); + } + + // Run various tests + { + typedef SmartDigraph GR; + DIGRAPH_TYPEDEFS(GR); + + GR gr; + IntArcMap l1(gr), l2(gr), l3(gr), l4(gr); + IntArcMap c1(gr), c2(gr), c3(gr), c4(gr); + + std::istringstream input(test_lgf); + digraphReader(gr, input). + arcMap("len1", l1). + arcMap("len2", l2). + arcMap("len3", l3). + arcMap("len4", l4). + arcMap("c1", c1). + arcMap("c2", c2). + arcMap("c3", c3). + arcMap("c4", c4). + run(); + + // Karp + checkMmcAlg >(gr, l1, c1, 6, 3); + checkMmcAlg >(gr, l2, c2, 5, 2); + checkMmcAlg >(gr, l3, c3, 0, 1); + checkMmcAlg >(gr, l4, c4, -1, 1); + + // HartmannOrlin + checkMmcAlg >(gr, l1, c1, 6, 3); + checkMmcAlg >(gr, l2, c2, 5, 2); + checkMmcAlg >(gr, l3, c3, 0, 1); + checkMmcAlg >(gr, l4, c4, -1, 1); + + // Howard + checkMmcAlg >(gr, l1, c1, 6, 3); + checkMmcAlg >(gr, l2, c2, 5, 2); + checkMmcAlg >(gr, l3, c3, 0, 1); + checkMmcAlg >(gr, l4, c4, -1, 1); + } + + return 0; +} diff --git a/lemon/test/mip_test.cc b/lemon/test/mip_test.cc new file mode 100644 index 0000000..6e99b4e --- /dev/null +++ b/lemon/test/mip_test.cc @@ -0,0 +1,159 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include "test_tools.h" + +#include + +#ifdef LEMON_HAVE_CPLEX +#include +#endif + +#ifdef LEMON_HAVE_GLPK +#include +#endif + +#ifdef LEMON_HAVE_CBC +#include +#endif + + +using namespace lemon; + +void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat, + double exp_opt) { + using std::string; + + mip.solve(); + //int decimal,sign; + std::ostringstream buf; + buf << "Type should be: " << int(stat)<<" and it is "< +void cloneTest() +{ + + MIP* mip = new MIP(); + MIP* mipnew = mip->newSolver(); + MIP* mipclone = mip->cloneSolver(); + delete mip; + delete mipnew; + delete mipclone; +} + +int main() +{ + +#ifdef LEMON_HAVE_GLPK + { + GlpkMip mip1; + aTest(mip1); + cloneTest(); + } +#endif + +#ifdef LEMON_HAVE_CPLEX + try { + CplexMip mip2; + aTest(mip2); + cloneTest(); + } catch (CplexEnv::LicenseError& error) { + check(false, error.what()); + } +#endif + +#ifdef LEMON_HAVE_CBC + { + CbcMip mip1; + aTest(mip1); + cloneTest(); + } +#endif + + return 0; + +} diff --git a/lemon/test/path_test.cc b/lemon/test/path_test.cc new file mode 100644 index 0000000..540dddc --- /dev/null +++ b/lemon/test/path_test.cc @@ -0,0 +1,44 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include +#include + +#include +#include + +#include "test_tools.h" + +using namespace std; +using namespace lemon; + +void check_concepts() { + checkConcept, concepts::Path >(); + checkConcept, Path >(); + checkConcept, SimplePath >(); + checkConcept, StaticPath >(); + checkConcept, ListPath >(); +} + +int main() { + check_concepts(); + return 0; +} diff --git a/lemon/test/planarity_test.cc b/lemon/test/planarity_test.cc new file mode 100644 index 0000000..0ac11ee --- /dev/null +++ b/lemon/test/planarity_test.cc @@ -0,0 +1,262 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include + +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; +using namespace lemon::dim2; + +const int lgfn = 4; +const std::string lgf[lgfn] = { + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "@edges\n" + " label\n" + "0 1 0\n" + "0 2 0\n" + "0 3 0\n" + "0 4 0\n" + "1 2 0\n" + "1 3 0\n" + "1 4 0\n" + "2 3 0\n" + "2 4 0\n" + "3 4 0\n", + + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "@edges\n" + " label\n" + "0 1 0\n" + "0 2 0\n" + "0 3 0\n" + "0 4 0\n" + "1 2 0\n" + "1 3 0\n" + "2 3 0\n" + "2 4 0\n" + "3 4 0\n", + + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "@edges\n" + " label\n" + "0 3 0\n" + "0 4 0\n" + "0 5 0\n" + "1 3 0\n" + "1 4 0\n" + "1 5 0\n" + "2 3 0\n" + "2 4 0\n" + "2 5 0\n", + + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "@edges\n" + " label\n" + "0 3 0\n" + "0 4 0\n" + "0 5 0\n" + "1 3 0\n" + "1 4 0\n" + "1 5 0\n" + "2 3 0\n" + "2 5 0\n" +}; + + + +typedef SmartGraph Graph; +GRAPH_TYPEDEFS(Graph); + +typedef PlanarEmbedding PE; +typedef PlanarDrawing PD; +typedef PlanarColoring PC; + +void checkEmbedding(const Graph& graph, PE& pe) { + int face_num = 0; + + Graph::ArcMap face(graph, -1); + + for (ArcIt a(graph); a != INVALID; ++a) { + if (face[a] == -1) { + Arc b = a; + while (face[b] == -1) { + face[b] = face_num; + b = pe.next(graph.oppositeArc(b)); + } + check(face[b] == face_num, "Wrong face"); + ++face_num; + } + } + check(face_num + countNodes(graph) - countConnectedComponents(graph) == + countEdges(graph) + 1, "Euler test does not passed"); +} + +void checkKuratowski(const Graph& graph, PE& pe) { + std::map degs; + for (NodeIt n(graph); n != INVALID; ++n) { + int deg = 0; + for (IncEdgeIt e(graph, n); e != INVALID; ++e) { + if (pe.kuratowski(e)) { + ++deg; + } + } + ++degs[deg]; + } + for (std::map::iterator it = degs.begin(); it != degs.end(); ++it) { + check(it->first == 0 || it->first == 2 || + (it->first == 3 && it->second == 6) || + (it->first == 4 && it->second == 5), + "Wrong degree in Kuratowski graph"); + } + + // Not full test + check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph"); +} + +bool intersect(Point e1, Point e2, Point f1, Point f2) { + int l, r; + if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false; + if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false; + if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false; + if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false; + + l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x); + r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x); + if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false; + l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x); + r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x); + if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false; + return true; +} + +bool collinear(Point p, Point q, Point r) { + int v; + v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x); + if (v != 0) return false; + v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y); + if (v < 0) return false; + return true; +} + +void checkDrawing(const Graph& graph, PD& pd) { + for (Graph::NodeIt n(graph); n != INVALID; ++n) { + Graph::NodeIt m(n); + for (++m; m != INVALID; ++m) { + check(pd[m] != pd[n], "Two nodes with identical coordinates"); + } + } + + for (Graph::EdgeIt e(graph); e != INVALID; ++e) { + for (Graph::EdgeIt f(e); f != e; ++f) { + Point e1 = pd[graph.u(e)]; + Point e2 = pd[graph.v(e)]; + Point f1 = pd[graph.u(f)]; + Point f2 = pd[graph.v(f)]; + + if (graph.u(e) == graph.u(f)) { + check(!collinear(e1, e2, f2), "Wrong drawing"); + } else if (graph.u(e) == graph.v(f)) { + check(!collinear(e1, e2, f1), "Wrong drawing"); + } else if (graph.v(e) == graph.u(f)) { + check(!collinear(e2, e1, f2), "Wrong drawing"); + } else if (graph.v(e) == graph.v(f)) { + check(!collinear(e2, e1, f1), "Wrong drawing"); + } else { + check(!intersect(e1, e2, f1, f2), "Wrong drawing"); + } + } + } +} + +void checkColoring(const Graph& graph, PC& pc, int num) { + for (NodeIt n(graph); n != INVALID; ++n) { + check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num, + "Wrong coloring"); + } + for (EdgeIt e(graph); e != INVALID; ++e) { + check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)), + "Wrong coloring"); + } +} + +int main() { + + for (int i = 0; i < lgfn; ++i) { + std::istringstream lgfs(lgf[i]); + + SmartGraph graph; + graphReader(graph, lgfs).run(); + + check(simpleGraph(graph), "Test graphs must be simple"); + + PE pe(graph); + bool planar = pe.run(); + check(checkPlanarity(graph) == planar, "Planarity checking failed"); + + if (planar) { + checkEmbedding(graph, pe); + + PlanarDrawing pd(graph); + pd.run(pe.embeddingMap()); + checkDrawing(graph, pd); + + PlanarColoring pc(graph); + pc.runFiveColoring(pe.embeddingMap()); + checkColoring(graph, pc, 5); + + } else { + checkKuratowski(graph, pe); + } + } + + return 0; +} diff --git a/lemon/test/preflow_test.cc b/lemon/test/preflow_test.cc new file mode 100644 index 0000000..edf982d --- /dev/null +++ b/lemon/test/preflow_test.cc @@ -0,0 +1,276 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2011 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include "test_tools.h" +#include +#include +#include +#include +#include +#include + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "0\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "8\n" + "9\n" + "@arcs\n" + " label capacity\n" + "0 1 0 20\n" + "0 2 1 0\n" + "1 1 2 3\n" + "1 2 3 8\n" + "1 3 4 8\n" + "2 5 5 5\n" + "3 2 6 5\n" + "3 5 7 5\n" + "3 6 8 5\n" + "4 3 9 3\n" + "5 7 10 3\n" + "5 6 11 10\n" + "5 8 12 10\n" + "6 8 13 8\n" + "8 9 14 20\n" + "8 1 15 5\n" + "9 5 16 5\n" + "@attributes\n" + "source 1\n" + "target 8\n"; + +void checkPreflowCompile() +{ + typedef int VType; + typedef concepts::Digraph Digraph; + + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + typedef concepts::ReadMap CapMap; + typedef concepts::ReadWriteMap FlowMap; + typedef concepts::WriteMap CutMap; + + typedef Elevator Elev; + typedef LinkedElevator LinkedElev; + + Digraph g; + Node n; + Arc e; + CapMap cap; + FlowMap flow; + CutMap cut; + VType v; + bool b; + + typedef Preflow + ::SetFlowMap + ::SetElevator + ::SetStandardElevator + ::Create PreflowType; + PreflowType preflow_test(g, cap, n, n); + const PreflowType& const_preflow_test = preflow_test; + + const PreflowType::Elevator& elev = const_preflow_test.elevator(); + preflow_test.elevator(const_cast(elev)); + PreflowType::Tolerance tol = const_preflow_test.tolerance(); + preflow_test.tolerance(tol); + + preflow_test + .capacityMap(cap) + .flowMap(flow) + .source(n) + .target(n); + + preflow_test.init(); + preflow_test.init(cap); + preflow_test.startFirstPhase(); + preflow_test.startSecondPhase(); + preflow_test.run(); + preflow_test.runMinCut(); + + v = const_preflow_test.flowValue(); + v = const_preflow_test.flow(e); + const FlowMap& fm = const_preflow_test.flowMap(); + b = const_preflow_test.minCut(n); + const_preflow_test.minCutMap(cut); + + ignore_unused_variable_warning(fm); +} + +int cutValue (const SmartDigraph& g, + const SmartDigraph::NodeMap& cut, + const SmartDigraph::ArcMap& cap) { + + int c=0; + for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) { + if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e]; + } + return c; +} + +bool checkFlow(const SmartDigraph& g, + const SmartDigraph::ArcMap& flow, + const SmartDigraph::ArcMap& cap, + SmartDigraph::Node s, SmartDigraph::Node t) { + + for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) { + if (flow[e] < 0 || flow[e] > cap[e]) return false; + } + + for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) { + if (n == s || n == t) continue; + int sum = 0; + for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) { + sum += flow[e]; + } + for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) { + sum -= flow[e]; + } + if (sum != 0) return false; + } + return true; +} + +void initFlowTest() +{ + DIGRAPH_TYPEDEFS(SmartDigraph); + + SmartDigraph g; + SmartDigraph::ArcMap cap(g),iflow(g); + Node s=g.addNode(); Node t=g.addNode(); + Node n1=g.addNode(); Node n2=g.addNode(); + Arc a; + a=g.addArc(s,n1); cap[a]=20; iflow[a]=20; + a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0; + a=g.addArc(n2,t); cap[a]=20; iflow[a]=0; + + Preflow pre(g,cap,s,t); + pre.init(iflow); + pre.startFirstPhase(); + check(pre.flowValue() == 10, "The incorrect max flow value."); + check(pre.minCut(s), "Wrong min cut (Node s)."); + check(pre.minCut(n1), "Wrong min cut (Node n1)."); + check(!pre.minCut(n2), "Wrong min cut (Node n2)."); + check(!pre.minCut(t), "Wrong min cut (Node t)."); +} + + +int main() { + + typedef SmartDigraph Digraph; + + typedef Digraph::Node Node; + typedef Digraph::NodeIt NodeIt; + typedef Digraph::ArcIt ArcIt; + typedef Digraph::ArcMap CapMap; + typedef Digraph::ArcMap FlowMap; + typedef Digraph::NodeMap CutMap; + + typedef Preflow PType; + + Digraph g; + Node s, t; + CapMap cap(g); + std::istringstream input(test_lgf); + DigraphReader(g,input). + arcMap("capacity", cap). + node("source",s). + node("target",t). + run(); + + PType preflow_test(g, cap, s, t); + preflow_test.run(); + + check(checkFlow(g, preflow_test.flowMap(), cap, s, t), + "The flow is not feasible."); + + CutMap min_cut(g); + preflow_test.minCutMap(min_cut); + int min_cut_value=cutValue(g,min_cut,cap); + + check(preflow_test.flowValue() == min_cut_value, + "The max flow value is not equal to the three min cut values."); + + FlowMap flow(g); + for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e]; + + int flow_value=preflow_test.flowValue(); + + for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e]; + preflow_test.init(flow); + preflow_test.startFirstPhase(); + + CutMap min_cut1(g); + preflow_test.minCutMap(min_cut1); + min_cut_value=cutValue(g,min_cut1,cap); + + check(preflow_test.flowValue() == min_cut_value && + min_cut_value == 2*flow_value, + "The max flow value or the min cut value is wrong."); + + preflow_test.startSecondPhase(); + + check(checkFlow(g, preflow_test.flowMap(), cap, s, t), + "The flow is not feasible."); + + CutMap min_cut2(g); + preflow_test.minCutMap(min_cut2); + min_cut_value=cutValue(g,min_cut2,cap); + + check(preflow_test.flowValue() == min_cut_value && + min_cut_value == 2*flow_value, + "The max flow value or the three min cut values were not doubled"); + + + preflow_test.flowMap(flow); + + NodeIt tmp1(g,s); + ++tmp1; + if ( tmp1 != INVALID ) s=tmp1; + + NodeIt tmp2(g,t); + ++tmp2; + if ( tmp2 != INVALID ) t=tmp2; + + preflow_test.source(s); + preflow_test.target(t); + + preflow_test.run(); + + CutMap min_cut3(g); + preflow_test.minCutMap(min_cut3); + min_cut_value=cutValue(g,min_cut3,cap); + + + check(preflow_test.flowValue() == min_cut_value, + "The max flow value or the three min cut values are incorrect."); + + initFlowTest(); + + return 0; +} diff --git a/lemon/test/radix_sort_test.cc b/lemon/test/radix_sort_test.cc new file mode 100644 index 0000000..2a27a7e --- /dev/null +++ b/lemon/test/radix_sort_test.cc @@ -0,0 +1,147 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include +#include + +#include "test_tools.h" + +#include +#include + +using namespace lemon; + +static const int n = 10000; + +struct Negate { + typedef int argument_type; + typedef int result_type; + int operator()(int a) { return - a; } +}; + +int negate(int a) { return - a; } + + +void generateIntSequence(int n, std::vector& data) { + int prime = 9973; + int root = 136, value = 1; + for (int i = 0; i < n; ++i) { + data.push_back(value - prime / 2); + value = (value * root) % prime; + } +} + +void generateCharSequence(int n, std::vector& data) { + int prime = 251; + int root = 3, value = root; + for (int i = 0; i < n; ++i) { + data.push_back(static_cast(value)); + value = (value * root) % prime; + } +} + +void checkRadixSort() { + { + std::vector data1; + generateIntSequence(n, data1); + + std::vector data2(data1); + std::sort(data1.begin(), data1.end()); + + radixSort(data2.begin(), data2.end()); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[i], "Test failed"); + } + + radixSort(data2.begin(), data2.end(), Negate()); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[n - 1 - i], "Test failed"); + } + + radixSort(data2.begin(), data2.end(), negate); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[n - 1 - i], "Test failed"); + } + + } + + { + std::vector data1(n); + generateCharSequence(n, data1); + + std::vector data2(data1); + std::sort(data1.begin(), data1.end()); + + radixSort(data2.begin(), data2.end()); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[i], "Test failed"); + } + + } +} + + +void checkStableRadixSort() { + { + std::vector data1; + generateIntSequence(n, data1); + + std::vector data2(data1); + std::sort(data1.begin(), data1.end()); + + stableRadixSort(data2.begin(), data2.end()); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[i], "Test failed"); + } + + stableRadixSort(data2.begin(), data2.end(), Negate()); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[n - 1 - i], "Test failed"); + } + + stableRadixSort(data2.begin(), data2.end(), negate); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[n - 1 - i], "Test failed"); + } + } + + { + std::vector data1(n); + generateCharSequence(n, data1); + + std::vector data2(data1); + std::sort(data1.begin(), data1.end()); + + radixSort(data2.begin(), data2.end()); + for (int i = 0; i < n; ++i) { + check(data1[i] == data2[i], "Test failed"); + } + + } +} + +int main() { + + checkRadixSort(); + checkStableRadixSort(); + + return 0; +} diff --git a/lemon/test/random_test.cc b/lemon/test/random_test.cc new file mode 100644 index 0000000..49dd8b6 --- /dev/null +++ b/lemon/test/random_test.cc @@ -0,0 +1,40 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include "test_tools.h" + +int seed_array[] = {1, 2}; + +int main() +{ + double a=lemon::rnd(); + check(a<1.0&&a>0.0,"This should be in [0,1)"); + a=lemon::rnd.gauss(); + a=lemon::rnd.gamma(3.45,0); + a=lemon::rnd.gamma(4); + //Does gamma work with integer k? + a=lemon::rnd.gamma(4.0,0); + a=lemon::rnd.poisson(.5); + + lemon::rnd.seed(100); + lemon::rnd.seed(seed_array, seed_array + + (sizeof(seed_array) / sizeof(seed_array[0]))); + + return 0; +} diff --git a/lemon/test/suurballe_test.cc b/lemon/test/suurballe_test.cc new file mode 100644 index 0000000..5e3edad --- /dev/null +++ b/lemon/test/suurballe_test.cc @@ -0,0 +1,265 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "test_tools.h" + +using namespace lemon; + +char test_lgf[] = + "@nodes\n" + "label\n" + "1\n" + "2\n" + "3\n" + "4\n" + "5\n" + "6\n" + "7\n" + "8\n" + "9\n" + "10\n" + "11\n" + "12\n" + "@arcs\n" + " length\n" + " 1 2 70\n" + " 1 3 150\n" + " 1 4 80\n" + " 2 8 80\n" + " 3 5 140\n" + " 4 6 60\n" + " 4 7 80\n" + " 4 8 110\n" + " 5 7 60\n" + " 5 11 120\n" + " 6 3 0\n" + " 6 9 140\n" + " 6 10 90\n" + " 7 1 30\n" + " 8 12 60\n" + " 9 12 50\n" + "10 12 70\n" + "10 2 100\n" + "10 7 60\n" + "11 10 20\n" + "12 11 30\n" + "@attributes\n" + "source 1\n" + "target 12\n" + "@end\n"; + +// Check the interface of Suurballe +void checkSuurballeCompile() +{ + typedef int VType; + typedef concepts::Digraph Digraph; + + typedef Digraph::Node Node; + typedef Digraph::Arc Arc; + typedef concepts::ReadMap LengthMap; + + typedef Suurballe ST; + typedef Suurballe + ::SetFlowMap + ::SetPotentialMap + ::SetPath > + ::SetHeap > > + ::Create SuurballeType; + + Digraph g; + Node n; + Arc e; + LengthMap len; + SuurballeType::FlowMap flow(g); + SuurballeType::PotentialMap pi(g); + + SuurballeType suurb_test(g, len); + const SuurballeType& const_suurb_test = suurb_test; + + suurb_test + .flowMap(flow) + .potentialMap(pi); + + int k; + k = suurb_test.run(n, n); + k = suurb_test.run(n, n, k); + suurb_test.init(n); + suurb_test.fullInit(n); + suurb_test.start(n); + suurb_test.start(n, k); + k = suurb_test.findFlow(n); + k = suurb_test.findFlow(n, k); + suurb_test.findPaths(); + + int f; + VType c; + c = const_suurb_test.totalLength(); + f = const_suurb_test.flow(e); + const SuurballeType::FlowMap& fm = + const_suurb_test.flowMap(); + c = const_suurb_test.potential(n); + const SuurballeType::PotentialMap& pm = + const_suurb_test.potentialMap(); + k = const_suurb_test.pathNum(); + Path p = const_suurb_test.path(k); + + ignore_unused_variable_warning(fm); + ignore_unused_variable_warning(pm); +} + +// Check the feasibility of the flow +template +bool checkFlow( const Digraph& gr, const FlowMap& flow, + typename Digraph::Node s, typename Digraph::Node t, + int value ) +{ + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + for (ArcIt e(gr); e != INVALID; ++e) + if (!(flow[e] == 0 || flow[e] == 1)) return false; + + for (NodeIt n(gr); n != INVALID; ++n) { + int sum = 0; + for (OutArcIt e(gr, n); e != INVALID; ++e) + sum += flow[e]; + for (InArcIt e(gr, n); e != INVALID; ++e) + sum -= flow[e]; + if (n == s && sum != value) return false; + if (n == t && sum != -value) return false; + if (n != s && n != t && sum != 0) return false; + } + + return true; +} + +// Check the optimalitiy of the flow +template < typename Digraph, typename CostMap, + typename FlowMap, typename PotentialMap > +bool checkOptimality( const Digraph& gr, const CostMap& cost, + const FlowMap& flow, const PotentialMap& pi ) +{ + // Check the "Complementary Slackness" optimality condition + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + bool opt = true; + for (ArcIt e(gr); e != INVALID; ++e) { + typename CostMap::Value red_cost = + cost[e] + pi[gr.source(e)] - pi[gr.target(e)]; + opt = (flow[e] == 0 && red_cost >= 0) || + (flow[e] == 1 && red_cost <= 0); + if (!opt) break; + } + return opt; +} + +// Check a path +template +bool checkPath( const Digraph& gr, const Path& path, + typename Digraph::Node s, typename Digraph::Node t) +{ + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); + Node n = s; + for (int i = 0; i < path.length(); ++i) { + if (gr.source(path.nth(i)) != n) return false; + n = gr.target(path.nth(i)); + } + return n == t; +} + + +int main() +{ + DIGRAPH_TYPEDEFS(ListDigraph); + + // Read the test digraph + ListDigraph digraph; + ListDigraph::ArcMap length(digraph); + Node s, t; + + std::istringstream input(test_lgf); + DigraphReader(digraph, input). + arcMap("length", length). + node("source", s). + node("target", t). + run(); + + // Check run() + { + Suurballe suurballe(digraph, length); + + // Find 2 paths + check(suurballe.run(s, t) == 2, "Wrong number of paths"); + check(checkFlow(digraph, suurballe.flowMap(), s, t, 2), + "The flow is not feasible"); + check(suurballe.totalLength() == 510, "The flow is not optimal"); + check(checkOptimality(digraph, length, suurballe.flowMap(), + suurballe.potentialMap()), + "Wrong potentials"); + for (int i = 0; i < suurballe.pathNum(); ++i) + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path"); + + // Find 3 paths + check(suurballe.run(s, t, 3) == 3, "Wrong number of paths"); + check(checkFlow(digraph, suurballe.flowMap(), s, t, 3), + "The flow is not feasible"); + check(suurballe.totalLength() == 1040, "The flow is not optimal"); + check(checkOptimality(digraph, length, suurballe.flowMap(), + suurballe.potentialMap()), + "Wrong potentials"); + for (int i = 0; i < suurballe.pathNum(); ++i) + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path"); + + // Find 5 paths (only 3 can be found) + check(suurballe.run(s, t, 5) == 3, "Wrong number of paths"); + check(checkFlow(digraph, suurballe.flowMap(), s, t, 3), + "The flow is not feasible"); + check(suurballe.totalLength() == 1040, "The flow is not optimal"); + check(checkOptimality(digraph, length, suurballe.flowMap(), + suurballe.potentialMap()), + "Wrong potentials"); + for (int i = 0; i < suurballe.pathNum(); ++i) + check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path"); + } + + // Check fullInit() + start() + { + Suurballe suurballe(digraph, length); + suurballe.fullInit(s); + + // Find 2 paths + check(suurballe.start(t) == 2, "Wrong number of paths"); + check(suurballe.totalLength() == 510, "The flow is not optimal"); + + // Find 3 paths + check(suurballe.start(t, 3) == 3, "Wrong number of paths"); + check(suurballe.totalLength() == 1040, "The flow is not optimal"); + + // Find 5 paths (only 3 can be found) + check(suurballe.start(t, 5) == 3, "Wrong number of paths"); + check(suurballe.totalLength() == 1040, "The flow is not optimal"); + } + + return 0; +} diff --git a/lemon/test/test_tools.h b/lemon/test/test_tools.h new file mode 100644 index 0000000..3300356 --- /dev/null +++ b/lemon/test/test_tools.h @@ -0,0 +1,50 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_TEST_TEST_TOOLS_H +#define LEMON_TEST_TEST_TOOLS_H + +///\ingroup misc +///\file +///\brief Some utilities to write test programs. + +#include +#include + +///If \c rc is fail, writes an error message and exits. + +///If \c rc is fail, writes an error message and exits. +///The error message contains the file name and the line number of the +///source code in a standard from, which makes it possible to go there +///using good source browsers like e.g. \c emacs. +/// +///For example +///\code check(0==1,"This is obviously false.");\endcode will +///print something like this (and then exits). +///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim +#define check(rc, msg) \ + { \ + if(!(rc)) { \ + std::cerr << __FILE__ ":" << __LINE__ << ": error: " \ + << msg << std::endl; \ + abort(); \ + } else { } \ + } \ + + +#endif diff --git a/lemon/test/test_tools_fail.cc b/lemon/test/test_tools_fail.cc new file mode 100644 index 0000000..6407cd1 --- /dev/null +++ b/lemon/test/test_tools_fail.cc @@ -0,0 +1,25 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include "test_tools.h" + +int main() +{ + check(false, "Don't panic. Failing is the right behaviour here."); + return 0; +} diff --git a/lemon/test/test_tools_pass.cc b/lemon/test/test_tools_pass.cc new file mode 100644 index 0000000..b590c15 --- /dev/null +++ b/lemon/test/test_tools_pass.cc @@ -0,0 +1,25 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include "test_tools.h" + +int main() +{ + check(true, "It should pass."); + return 0; +} diff --git a/lemon/test/time_measure_test.cc b/lemon/test/time_measure_test.cc new file mode 100644 index 0000000..5ae5aa1 --- /dev/null +++ b/lemon/test/time_measure_test.cc @@ -0,0 +1,56 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include + +using namespace lemon; + +void f() +{ + double d=0; + for(int i=0;i<1000;i++) + d+=0.1; +} + +void g() +{ + static Timer T; + + for(int i=0;i<1000;i++) + TimeStamp x(T); +} + +int main() +{ + Timer T; + unsigned int n; + for(n=0;T.realTime()<0.1;n++) ; + std::cout << T << " (" << n << " time queries)\n"; + + TimeStamp full; + TimeStamp t; + t=runningTimeTest(f,0.1,&n,&full); + std::cout << t << " (" << n << " tests)\n"; + std::cout << "Total: " << full << "\n"; + + t=runningTimeTest(g,0.1,&n,&full); + std::cout << t << " (" << n << " tests)\n"; + std::cout << "Total: " << full << "\n"; + + return 0; +} diff --git a/lemon/test/unionfind_test.cc b/lemon/test/unionfind_test.cc new file mode 100644 index 0000000..e82d8e6 --- /dev/null +++ b/lemon/test/unionfind_test.cc @@ -0,0 +1,102 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include +#include +#include "test_tools.h" + +using namespace lemon; +using namespace std; + +typedef UnionFindEnum > UFE; + +int main() { + ListGraph g; + ListGraph::NodeMap base(g); + UFE U(base); + vector n; + + for(int i=0;i<20;i++) n.push_back(g.addNode()); + + U.insert(n[1]); + U.insert(n[2]); + + check(U.join(n[1],n[2]) != -1, "Something is wrong with UnionFindEnum"); + + U.insert(n[3]); + U.insert(n[4]); + U.insert(n[5]); + U.insert(n[6]); + U.insert(n[7]); + + + check(U.join(n[1],n[4]) != -1, "Something is wrong with UnionFindEnum"); + check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum"); + check(U.join(n[3],n[5]) != -1, "Something is wrong with UnionFindEnum"); + + + U.insert(n[8],U.find(n[5])); + + + check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[5])) == 3, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[6])) == 1, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum"); + + + U.insert(n[9]); + U.insert(n[10],U.find(n[9])); + + + check(U.join(n[8],n[10]) != -1, "Something is wrong with UnionFindEnum"); + + + check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[9])) == 5, "Something is wrong with UnionFindEnum"); + + check(U.size(U.find(n[8])) == 5, "Something is wrong with UnionFindEnum"); + + U.erase(n[9]); + U.erase(n[1]); + + check(U.size(U.find(n[10])) == 4, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[2])) == 2, "Something is wrong with UnionFindEnum"); + + U.erase(n[6]); + U.split(U.find(n[8])); + + + check(U.size(U.find(n[4])) == 2, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[3])) == 1, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[2])) == 2, "Something is wrong with UnionFindEnum"); + + + check(U.join(n[3],n[4]) != -1, "Something is wrong with UnionFindEnum"); + check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum"); + + + check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[3])) == 3, "Something is wrong with UnionFindEnum"); + check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum"); + + U.eraseClass(U.find(n[4])); + U.eraseClass(U.find(n[7])); + + return 0; +} diff --git a/lemon/tools/.deps/.dirstamp b/lemon/tools/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/lemon/tools/.deps/dimacs-solver.Po b/lemon/tools/.deps/dimacs-solver.Po new file mode 100644 index 0000000..f8eb074 --- /dev/null +++ b/lemon/tools/.deps/dimacs-solver.Po @@ -0,0 +1,543 @@ +tools/dimacs-solver.o: tools/dimacs-solver.cc \ + /usr/include/c++/4.7/iostream \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/ostream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/iosfwd /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/xlocale.h /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/cctype \ + /usr/include/ctype.h /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/locale_classes.h /usr/include/c++/4.7/string \ + /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/bits/basic_string.tcc \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc \ + /usr/include/c++/4.7/bits/ostream.tcc /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/bits/istream.tcc /usr/include/c++/4.7/fstream \ + /usr/include/c++/4.7/bits/codecvt.h /usr/include/c++/4.7/cstdio \ + /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h \ + /usr/include/c++/4.7/bits/fstream.tcc /usr/include/c++/4.7/cstring \ + /usr/include/string.h lemon/smart_graph.h /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_construct.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/vector.tcc lemon/core.h \ + /usr/include/c++/4.7/algorithm /usr/include/c++/4.7/utility \ + /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_algo.h /usr/include/c++/4.7/cstdlib \ + /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h /usr/include/alloca.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h \ + /usr/include/c++/4.7/bits/stl_tempbuf.h lemon/config.h \ + lemon/bits/enable_if.h lemon/bits/traits.h lemon/assert.h lemon/error.h \ + /usr/include/c++/4.7/sstream /usr/include/c++/4.7/bits/sstream.tcc \ + /usr/include/c++/4.7/memory \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h lemon/bits/graph_extender.h \ + lemon/bits/map_extender.h /usr/include/c++/4.7/iterator \ + /usr/include/c++/4.7/bits/stream_iterator.h lemon/concept_check.h \ + lemon/concepts/maps.h lemon/bits/default_map.h lemon/bits/array_map.h \ + lemon/bits/alteration_notifier.h /usr/include/c++/4.7/list \ + /usr/include/c++/4.7/bits/stl_list.h /usr/include/c++/4.7/bits/list.tcc \ + lemon/bits/vector_map.h lemon/dimacs.h /usr/include/c++/4.7/limits \ + lemon/maps.h /usr/include/c++/4.7/functional /usr/include/c++/4.7/map \ + /usr/include/c++/4.7/bits/stl_tree.h /usr/include/c++/4.7/bits/stl_map.h \ + /usr/include/c++/4.7/bits/stl_multimap.h lemon/lgf_writer.h \ + lemon/time_measure.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + /usr/include/x86_64-linux-gnu/sys/times.h \ + /usr/include/x86_64-linux-gnu/sys/time.h lemon/arg_parser.h \ + lemon/dijkstra.h lemon/list_graph.h lemon/bin_heap.h \ + lemon/bits/path_dump.h lemon/path.h lemon/concepts/path.h \ + lemon/preflow.h lemon/tolerance.h lemon/elevator.h lemon/matching.h \ + /usr/include/c++/4.7/queue /usr/include/c++/4.7/deque \ + /usr/include/c++/4.7/bits/stl_deque.h \ + /usr/include/c++/4.7/bits/deque.tcc \ + /usr/include/c++/4.7/bits/stl_queue.h /usr/include/c++/4.7/set \ + /usr/include/c++/4.7/bits/stl_set.h \ + /usr/include/c++/4.7/bits/stl_multiset.h lemon/unionfind.h \ + lemon/fractional_matching.h lemon/network_simplex.h lemon/math.h \ + /usr/include/c++/4.7/cmath /usr/include/math.h \ + /usr/include/x86_64-linux-gnu/bits/huge_val.h \ + /usr/include/x86_64-linux-gnu/bits/huge_valf.h \ + /usr/include/x86_64-linux-gnu/bits/huge_vall.h \ + /usr/include/x86_64-linux-gnu/bits/inf.h \ + /usr/include/x86_64-linux-gnu/bits/nan.h \ + /usr/include/x86_64-linux-gnu/bits/mathdef.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mathinline.h + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/xlocale.h: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/fstream: + +/usr/include/c++/4.7/bits/codecvt.h: + +/usr/include/c++/4.7/cstdio: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h: + +/usr/include/c++/4.7/bits/fstream.tcc: + +/usr/include/c++/4.7/cstring: + +/usr/include/string.h: + +lemon/smart_graph.h: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +lemon/core.h: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +lemon/config.h: + +lemon/bits/enable_if.h: + +lemon/bits/traits.h: + +lemon/assert.h: + +lemon/error.h: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: + +lemon/bits/graph_extender.h: + +lemon/bits/map_extender.h: + +/usr/include/c++/4.7/iterator: + +/usr/include/c++/4.7/bits/stream_iterator.h: + +lemon/concept_check.h: + +lemon/concepts/maps.h: + +lemon/bits/default_map.h: + +lemon/bits/array_map.h: + +lemon/bits/alteration_notifier.h: + +/usr/include/c++/4.7/list: + +/usr/include/c++/4.7/bits/stl_list.h: + +/usr/include/c++/4.7/bits/list.tcc: + +lemon/bits/vector_map.h: + +lemon/dimacs.h: + +/usr/include/c++/4.7/limits: + +lemon/maps.h: + +/usr/include/c++/4.7/functional: + +/usr/include/c++/4.7/map: + +/usr/include/c++/4.7/bits/stl_tree.h: + +/usr/include/c++/4.7/bits/stl_map.h: + +/usr/include/c++/4.7/bits/stl_multimap.h: + +lemon/lgf_writer.h: + +lemon/time_measure.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +/usr/include/x86_64-linux-gnu/sys/times.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +lemon/arg_parser.h: + +lemon/dijkstra.h: + +lemon/list_graph.h: + +lemon/bin_heap.h: + +lemon/bits/path_dump.h: + +lemon/path.h: + +lemon/concepts/path.h: + +lemon/preflow.h: + +lemon/tolerance.h: + +lemon/elevator.h: + +lemon/matching.h: + +/usr/include/c++/4.7/queue: + +/usr/include/c++/4.7/deque: + +/usr/include/c++/4.7/bits/stl_deque.h: + +/usr/include/c++/4.7/bits/deque.tcc: + +/usr/include/c++/4.7/bits/stl_queue.h: + +/usr/include/c++/4.7/set: + +/usr/include/c++/4.7/bits/stl_set.h: + +/usr/include/c++/4.7/bits/stl_multiset.h: + +lemon/unionfind.h: + +lemon/fractional_matching.h: + +lemon/network_simplex.h: + +lemon/math.h: + +/usr/include/c++/4.7/cmath: + +/usr/include/math.h: + +/usr/include/x86_64-linux-gnu/bits/huge_val.h: + +/usr/include/x86_64-linux-gnu/bits/huge_valf.h: + +/usr/include/x86_64-linux-gnu/bits/huge_vall.h: + +/usr/include/x86_64-linux-gnu/bits/inf.h: + +/usr/include/x86_64-linux-gnu/bits/nan.h: + +/usr/include/x86_64-linux-gnu/bits/mathdef.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathinline.h: diff --git a/lemon/tools/.deps/dimacs-to-lgf.Po b/lemon/tools/.deps/dimacs-to-lgf.Po new file mode 100644 index 0000000..f4f3a75 --- /dev/null +++ b/lemon/tools/.deps/dimacs-to-lgf.Po @@ -0,0 +1,439 @@ +tools/dimacs-to-lgf.o: tools/dimacs-to-lgf.cc \ + /usr/include/c++/4.7/iostream \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/ostream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/iosfwd /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/xlocale.h /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/cctype \ + /usr/include/ctype.h /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/locale_classes.h /usr/include/c++/4.7/string \ + /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/range_access.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/bits/basic_string.tcc \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc \ + /usr/include/c++/4.7/bits/ostream.tcc /usr/include/c++/4.7/istream \ + /usr/include/c++/4.7/bits/istream.tcc /usr/include/c++/4.7/fstream \ + /usr/include/c++/4.7/bits/codecvt.h /usr/include/c++/4.7/cstdio \ + /usr/include/libio.h /usr/include/_G_config.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h \ + /usr/include/c++/4.7/bits/fstream.tcc /usr/include/c++/4.7/cstring \ + /usr/include/string.h lemon/smart_graph.h /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_construct.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/vector.tcc lemon/core.h \ + /usr/include/c++/4.7/algorithm /usr/include/c++/4.7/utility \ + /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_algo.h /usr/include/c++/4.7/cstdlib \ + /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h /usr/include/alloca.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h \ + /usr/include/c++/4.7/bits/stl_tempbuf.h lemon/config.h \ + lemon/bits/enable_if.h lemon/bits/traits.h lemon/assert.h lemon/error.h \ + /usr/include/c++/4.7/sstream /usr/include/c++/4.7/bits/sstream.tcc \ + /usr/include/c++/4.7/memory \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h lemon/bits/graph_extender.h \ + lemon/bits/map_extender.h /usr/include/c++/4.7/iterator \ + /usr/include/c++/4.7/bits/stream_iterator.h lemon/concept_check.h \ + lemon/concepts/maps.h lemon/bits/default_map.h lemon/bits/array_map.h \ + lemon/bits/alteration_notifier.h /usr/include/c++/4.7/list \ + /usr/include/c++/4.7/bits/stl_list.h /usr/include/c++/4.7/bits/list.tcc \ + lemon/bits/vector_map.h lemon/dimacs.h /usr/include/c++/4.7/limits \ + lemon/maps.h /usr/include/c++/4.7/functional /usr/include/c++/4.7/map \ + /usr/include/c++/4.7/bits/stl_tree.h /usr/include/c++/4.7/bits/stl_map.h \ + /usr/include/c++/4.7/bits/stl_multimap.h lemon/lgf_writer.h \ + lemon/arg_parser.h + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/xlocale.h: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/fstream: + +/usr/include/c++/4.7/bits/codecvt.h: + +/usr/include/c++/4.7/cstdio: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h: + +/usr/include/c++/4.7/bits/fstream.tcc: + +/usr/include/c++/4.7/cstring: + +/usr/include/string.h: + +lemon/smart_graph.h: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +lemon/core.h: + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +lemon/config.h: + +lemon/bits/enable_if.h: + +lemon/bits/traits.h: + +lemon/assert.h: + +lemon/error.h: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: + +lemon/bits/graph_extender.h: + +lemon/bits/map_extender.h: + +/usr/include/c++/4.7/iterator: + +/usr/include/c++/4.7/bits/stream_iterator.h: + +lemon/concept_check.h: + +lemon/concepts/maps.h: + +lemon/bits/default_map.h: + +lemon/bits/array_map.h: + +lemon/bits/alteration_notifier.h: + +/usr/include/c++/4.7/list: + +/usr/include/c++/4.7/bits/stl_list.h: + +/usr/include/c++/4.7/bits/list.tcc: + +lemon/bits/vector_map.h: + +lemon/dimacs.h: + +/usr/include/c++/4.7/limits: + +lemon/maps.h: + +/usr/include/c++/4.7/functional: + +/usr/include/c++/4.7/map: + +/usr/include/c++/4.7/bits/stl_tree.h: + +/usr/include/c++/4.7/bits/stl_map.h: + +/usr/include/c++/4.7/bits/stl_multimap.h: + +lemon/lgf_writer.h: + +lemon/arg_parser.h: diff --git a/lemon/tools/.deps/lgf-gen.Po b/lemon/tools/.deps/lgf-gen.Po new file mode 100644 index 0000000..81a1657 --- /dev/null +++ b/lemon/tools/.deps/lgf-gen.Po @@ -0,0 +1,567 @@ +tools/lgf-gen.o: tools/lgf-gen.cc /usr/include/c++/4.7/algorithm \ + /usr/include/c++/4.7/utility \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/bits/predefs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h \ + /usr/include/c++/4.7/bits/stl_relops.h \ + /usr/include/c++/4.7/bits/stl_pair.h /usr/include/c++/4.7/bits/move.h \ + /usr/include/c++/4.7/bits/concept_check.h \ + /usr/include/c++/4.7/bits/stl_algobase.h \ + /usr/include/c++/4.7/bits/functexcept.h \ + /usr/include/c++/4.7/bits/exception_defines.h \ + /usr/include/c++/4.7/bits/cpp_type_traits.h \ + /usr/include/c++/4.7/ext/type_traits.h \ + /usr/include/c++/4.7/ext/numeric_traits.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_types.h \ + /usr/include/c++/4.7/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/4.7/bits/stl_iterator.h \ + /usr/include/c++/4.7/debug/debug.h /usr/include/c++/4.7/bits/stl_algo.h \ + /usr/include/c++/4.7/cstdlib /usr/include/stdlib.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h /usr/include/xlocale.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/sigset.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ + /usr/include/c++/4.7/bits/algorithmfwd.h \ + /usr/include/c++/4.7/bits/stl_heap.h \ + /usr/include/c++/4.7/bits/stl_tempbuf.h \ + /usr/include/c++/4.7/bits/stl_construct.h /usr/include/c++/4.7/new \ + /usr/include/c++/4.7/exception \ + /usr/include/c++/4.7/bits/atomic_lockfree_defines.h \ + /usr/include/c++/4.7/ext/alloc_traits.h \ + /usr/include/c++/4.7/bits/allocator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h \ + /usr/include/c++/4.7/ext/new_allocator.h /usr/include/c++/4.7/set \ + /usr/include/c++/4.7/bits/stl_tree.h \ + /usr/include/c++/4.7/bits/stl_function.h \ + /usr/include/c++/4.7/backward/binders.h \ + /usr/include/c++/4.7/bits/stl_set.h \ + /usr/include/c++/4.7/bits/stl_multiset.h \ + /usr/include/c++/4.7/bits/range_access.h /usr/include/c++/4.7/ctime \ + lemon/list_graph.h lemon/core.h /usr/include/c++/4.7/vector \ + /usr/include/c++/4.7/bits/stl_uninitialized.h \ + /usr/include/c++/4.7/bits/stl_vector.h \ + /usr/include/c++/4.7/bits/stl_bvector.h \ + /usr/include/c++/4.7/bits/vector.tcc lemon/config.h \ + lemon/bits/enable_if.h lemon/bits/traits.h lemon/assert.h lemon/error.h \ + /usr/include/c++/4.7/string /usr/include/c++/4.7/bits/stringfwd.h \ + /usr/include/c++/4.7/bits/char_traits.h \ + /usr/include/c++/4.7/bits/postypes.h /usr/include/c++/4.7/cwchar \ + /usr/include/wchar.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/c++/4.7/bits/localefwd.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h \ + /usr/include/c++/4.7/clocale /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.7/iosfwd \ + /usr/include/c++/4.7/cctype /usr/include/ctype.h \ + /usr/include/c++/4.7/bits/ostream_insert.h \ + /usr/include/c++/4.7/bits/cxxabi_forced.h \ + /usr/include/c++/4.7/bits/basic_string.h \ + /usr/include/c++/4.7/ext/atomicity.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h \ + /usr/include/c++/4.7/bits/basic_string.tcc /usr/include/c++/4.7/sstream \ + /usr/include/c++/4.7/istream /usr/include/c++/4.7/ios \ + /usr/include/c++/4.7/bits/ios_base.h \ + /usr/include/c++/4.7/bits/locale_classes.h \ + /usr/include/c++/4.7/bits/locale_classes.tcc \ + /usr/include/c++/4.7/streambuf /usr/include/c++/4.7/bits/streambuf.tcc \ + /usr/include/c++/4.7/bits/basic_ios.h \ + /usr/include/c++/4.7/bits/locale_facets.h /usr/include/c++/4.7/cwctype \ + /usr/include/wctype.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h \ + /usr/include/c++/4.7/bits/streambuf_iterator.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h \ + /usr/include/c++/4.7/bits/locale_facets.tcc \ + /usr/include/c++/4.7/bits/basic_ios.tcc /usr/include/c++/4.7/ostream \ + /usr/include/c++/4.7/bits/ostream.tcc \ + /usr/include/c++/4.7/bits/istream.tcc \ + /usr/include/c++/4.7/bits/sstream.tcc /usr/include/c++/4.7/iostream \ + /usr/include/c++/4.7/memory \ + /usr/include/c++/4.7/bits/stl_raw_storage_iter.h \ + /usr/include/c++/4.7/backward/auto_ptr.h lemon/bits/graph_extender.h \ + lemon/bits/map_extender.h /usr/include/c++/4.7/iterator \ + /usr/include/c++/4.7/bits/stream_iterator.h lemon/concept_check.h \ + lemon/concepts/maps.h lemon/bits/default_map.h lemon/bits/array_map.h \ + lemon/bits/alteration_notifier.h /usr/include/c++/4.7/list \ + /usr/include/c++/4.7/bits/stl_list.h /usr/include/c++/4.7/bits/list.tcc \ + lemon/bits/vector_map.h lemon/random.h /usr/include/c++/4.7/limits \ + /usr/include/c++/4.7/fstream /usr/include/c++/4.7/bits/codecvt.h \ + /usr/include/c++/4.7/cstdio /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h \ + /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h \ + /usr/include/c++/4.7/bits/fstream.tcc lemon/math.h \ + /usr/include/c++/4.7/cmath /usr/include/math.h \ + /usr/include/x86_64-linux-gnu/bits/huge_val.h \ + /usr/include/x86_64-linux-gnu/bits/huge_valf.h \ + /usr/include/x86_64-linux-gnu/bits/huge_vall.h \ + /usr/include/x86_64-linux-gnu/bits/inf.h \ + /usr/include/x86_64-linux-gnu/bits/nan.h \ + /usr/include/x86_64-linux-gnu/bits/mathdef.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mathinline.h lemon/dim2.h \ + /usr/include/x86_64-linux-gnu/sys/time.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h /usr/include/getopt.h \ + lemon/bfs.h lemon/bits/path_dump.h lemon/maps.h \ + /usr/include/c++/4.7/functional /usr/include/c++/4.7/map \ + /usr/include/c++/4.7/bits/stl_map.h \ + /usr/include/c++/4.7/bits/stl_multimap.h lemon/path.h \ + lemon/concepts/path.h lemon/counter.h lemon/suurballe.h lemon/bin_heap.h \ + lemon/dijkstra.h lemon/graph_to_eps.h lemon/color.h lemon/bits/bezier.h \ + lemon/lgf_writer.h lemon/arg_parser.h lemon/euler.h lemon/adaptors.h \ + lemon/bits/variant.h lemon/bits/graph_adaptor_extender.h \ + lemon/tolerance.h lemon/connectivity.h lemon/dfs.h \ + lemon/concepts/digraph.h lemon/concepts/graph_components.h \ + lemon/concepts/graph.h /usr/include/c++/4.7/stack \ + /usr/include/c++/4.7/deque /usr/include/c++/4.7/bits/stl_deque.h \ + /usr/include/c++/4.7/bits/deque.tcc \ + /usr/include/c++/4.7/bits/stl_stack.h lemon/kruskal.h lemon/unionfind.h \ + lemon/time_measure.h /usr/include/x86_64-linux-gnu/sys/times.h + +/usr/include/c++/4.7/algorithm: + +/usr/include/c++/4.7/utility: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++config.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/os_defines.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/bits/predefs.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/cpu_defines.h: + +/usr/include/c++/4.7/bits/stl_relops.h: + +/usr/include/c++/4.7/bits/stl_pair.h: + +/usr/include/c++/4.7/bits/move.h: + +/usr/include/c++/4.7/bits/concept_check.h: + +/usr/include/c++/4.7/bits/stl_algobase.h: + +/usr/include/c++/4.7/bits/functexcept.h: + +/usr/include/c++/4.7/bits/exception_defines.h: + +/usr/include/c++/4.7/bits/cpp_type_traits.h: + +/usr/include/c++/4.7/ext/type_traits.h: + +/usr/include/c++/4.7/ext/numeric_traits.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_types.h: + +/usr/include/c++/4.7/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/4.7/bits/stl_iterator.h: + +/usr/include/c++/4.7/debug/debug.h: + +/usr/include/c++/4.7/bits/stl_algo.h: + +/usr/include/c++/4.7/cstdlib: + +/usr/include/stdlib.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/xlocale.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sigset.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/sys/sysmacros.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/c++/4.7/bits/algorithmfwd.h: + +/usr/include/c++/4.7/bits/stl_heap.h: + +/usr/include/c++/4.7/bits/stl_tempbuf.h: + +/usr/include/c++/4.7/bits/stl_construct.h: + +/usr/include/c++/4.7/new: + +/usr/include/c++/4.7/exception: + +/usr/include/c++/4.7/bits/atomic_lockfree_defines.h: + +/usr/include/c++/4.7/ext/alloc_traits.h: + +/usr/include/c++/4.7/bits/allocator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h: + +/usr/include/c++/4.7/ext/new_allocator.h: + +/usr/include/c++/4.7/set: + +/usr/include/c++/4.7/bits/stl_tree.h: + +/usr/include/c++/4.7/bits/stl_function.h: + +/usr/include/c++/4.7/backward/binders.h: + +/usr/include/c++/4.7/bits/stl_set.h: + +/usr/include/c++/4.7/bits/stl_multiset.h: + +/usr/include/c++/4.7/bits/range_access.h: + +/usr/include/c++/4.7/ctime: + +lemon/list_graph.h: + +lemon/core.h: + +/usr/include/c++/4.7/vector: + +/usr/include/c++/4.7/bits/stl_uninitialized.h: + +/usr/include/c++/4.7/bits/stl_vector.h: + +/usr/include/c++/4.7/bits/stl_bvector.h: + +/usr/include/c++/4.7/bits/vector.tcc: + +lemon/config.h: + +lemon/bits/enable_if.h: + +lemon/bits/traits.h: + +lemon/assert.h: + +lemon/error.h: + +/usr/include/c++/4.7/string: + +/usr/include/c++/4.7/bits/stringfwd.h: + +/usr/include/c++/4.7/bits/char_traits.h: + +/usr/include/c++/4.7/bits/postypes.h: + +/usr/include/c++/4.7/cwchar: + +/usr/include/wchar.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/c++/4.7/bits/localefwd.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++locale.h: + +/usr/include/c++/4.7/clocale: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/4.7/iosfwd: + +/usr/include/c++/4.7/cctype: + +/usr/include/ctype.h: + +/usr/include/c++/4.7/bits/ostream_insert.h: + +/usr/include/c++/4.7/bits/cxxabi_forced.h: + +/usr/include/c++/4.7/bits/basic_string.h: + +/usr/include/c++/4.7/ext/atomicity.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/gthr-default.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/atomic_word.h: + +/usr/include/c++/4.7/bits/basic_string.tcc: + +/usr/include/c++/4.7/sstream: + +/usr/include/c++/4.7/istream: + +/usr/include/c++/4.7/ios: + +/usr/include/c++/4.7/bits/ios_base.h: + +/usr/include/c++/4.7/bits/locale_classes.h: + +/usr/include/c++/4.7/bits/locale_classes.tcc: + +/usr/include/c++/4.7/streambuf: + +/usr/include/c++/4.7/bits/streambuf.tcc: + +/usr/include/c++/4.7/bits/basic_ios.h: + +/usr/include/c++/4.7/bits/locale_facets.h: + +/usr/include/c++/4.7/cwctype: + +/usr/include/wctype.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_base.h: + +/usr/include/c++/4.7/bits/streambuf_iterator.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/ctype_inline.h: + +/usr/include/c++/4.7/bits/locale_facets.tcc: + +/usr/include/c++/4.7/bits/basic_ios.tcc: + +/usr/include/c++/4.7/ostream: + +/usr/include/c++/4.7/bits/ostream.tcc: + +/usr/include/c++/4.7/bits/istream.tcc: + +/usr/include/c++/4.7/bits/sstream.tcc: + +/usr/include/c++/4.7/iostream: + +/usr/include/c++/4.7/memory: + +/usr/include/c++/4.7/bits/stl_raw_storage_iter.h: + +/usr/include/c++/4.7/backward/auto_ptr.h: + +lemon/bits/graph_extender.h: + +lemon/bits/map_extender.h: + +/usr/include/c++/4.7/iterator: + +/usr/include/c++/4.7/bits/stream_iterator.h: + +lemon/concept_check.h: + +lemon/concepts/maps.h: + +lemon/bits/default_map.h: + +lemon/bits/array_map.h: + +lemon/bits/alteration_notifier.h: + +/usr/include/c++/4.7/list: + +/usr/include/c++/4.7/bits/stl_list.h: + +/usr/include/c++/4.7/bits/list.tcc: + +lemon/bits/vector_map.h: + +lemon/random.h: + +/usr/include/c++/4.7/limits: + +/usr/include/c++/4.7/fstream: + +/usr/include/c++/4.7/bits/codecvt.h: + +/usr/include/c++/4.7/cstdio: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/basic_file.h: + +/usr/include/c++/4.7/x86_64-linux-gnu/bits/c++io.h: + +/usr/include/c++/4.7/bits/fstream.tcc: + +lemon/math.h: + +/usr/include/c++/4.7/cmath: + +/usr/include/math.h: + +/usr/include/x86_64-linux-gnu/bits/huge_val.h: + +/usr/include/x86_64-linux-gnu/bits/huge_valf.h: + +/usr/include/x86_64-linux-gnu/bits/huge_vall.h: + +/usr/include/x86_64-linux-gnu/bits/inf.h: + +/usr/include/x86_64-linux-gnu/bits/nan.h: + +/usr/include/x86_64-linux-gnu/bits/mathdef.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathinline.h: + +lemon/dim2.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/getopt.h: + +lemon/bfs.h: + +lemon/bits/path_dump.h: + +lemon/maps.h: + +/usr/include/c++/4.7/functional: + +/usr/include/c++/4.7/map: + +/usr/include/c++/4.7/bits/stl_map.h: + +/usr/include/c++/4.7/bits/stl_multimap.h: + +lemon/path.h: + +lemon/concepts/path.h: + +lemon/counter.h: + +lemon/suurballe.h: + +lemon/bin_heap.h: + +lemon/dijkstra.h: + +lemon/graph_to_eps.h: + +lemon/color.h: + +lemon/bits/bezier.h: + +lemon/lgf_writer.h: + +lemon/arg_parser.h: + +lemon/euler.h: + +lemon/adaptors.h: + +lemon/bits/variant.h: + +lemon/bits/graph_adaptor_extender.h: + +lemon/tolerance.h: + +lemon/connectivity.h: + +lemon/dfs.h: + +lemon/concepts/digraph.h: + +lemon/concepts/graph_components.h: + +lemon/concepts/graph.h: + +/usr/include/c++/4.7/stack: + +/usr/include/c++/4.7/deque: + +/usr/include/c++/4.7/bits/stl_deque.h: + +/usr/include/c++/4.7/bits/deque.tcc: + +/usr/include/c++/4.7/bits/stl_stack.h: + +lemon/kruskal.h: + +lemon/unionfind.h: + +lemon/time_measure.h: + +/usr/include/x86_64-linux-gnu/sys/times.h: diff --git a/lemon/tools/.dirstamp b/lemon/tools/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/lemon/tools/CMakeLists.txt b/lemon/tools/CMakeLists.txt new file mode 100644 index 0000000..64b7df7 --- /dev/null +++ b/lemon/tools/CMakeLists.txt @@ -0,0 +1,31 @@ +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} +) + +LINK_DIRECTORIES( + ${PROJECT_BINARY_DIR}/lemon +) + +ADD_EXECUTABLE(lgf-gen lgf-gen.cc) +TARGET_LINK_LIBRARIES(lgf-gen lemon) + +ADD_EXECUTABLE(dimacs-to-lgf dimacs-to-lgf.cc) +TARGET_LINK_LIBRARIES(dimacs-to-lgf lemon) + +ADD_EXECUTABLE(dimacs-solver dimacs-solver.cc) +TARGET_LINK_LIBRARIES(dimacs-solver lemon) + +INSTALL( + TARGETS lgf-gen dimacs-to-lgf dimacs-solver + RUNTIME DESTINATION bin + COMPONENT bin +) + +IF(NOT WIN32) + INSTALL( + PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh + DESTINATION bin + COMPONENT bin + ) +ENDIF() diff --git a/lemon/tools/Makefile.am b/lemon/tools/Makefile.am new file mode 100644 index 0000000..9bcca89 --- /dev/null +++ b/lemon/tools/Makefile.am @@ -0,0 +1,17 @@ +EXTRA_DIST += \ + tools/CMakeLists.txt + +if WANT_TOOLS + +bin_PROGRAMS += \ + tools/dimacs-solver \ + tools/dimacs-to-lgf \ + tools/lgf-gen + +dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh + +endif WANT_TOOLS + +tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc +tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc +tools_lgf_gen_SOURCES = tools/lgf-gen.cc diff --git a/lemon/tools/dimacs-solver.cc b/lemon/tools/dimacs-solver.cc new file mode 100644 index 0000000..dc99cae --- /dev/null +++ b/lemon/tools/dimacs-solver.cc @@ -0,0 +1,280 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2010 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup tools +///\file +///\brief DIMACS problem solver. +/// +/// This program solves various problems given in DIMACS format. +/// +/// See +/// \code +/// dimacs-solver --help +/// \endcode +/// for more info on usage. + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +using namespace lemon; +typedef SmartDigraph Digraph; +DIGRAPH_TYPEDEFS(Digraph); +typedef SmartGraph Graph; + +template +void solve_sp(ArgParser &ap, std::istream &is, std::ostream &, + DimacsDescriptor &desc) +{ + bool report = !ap.given("q"); + Digraph g; + Node s; + Digraph::ArcMap len(g); + Timer t; + t.restart(); + readDimacsSp(is, g, len, s, desc); + if(report) std::cerr << "Read the file: " << t << '\n'; + t.restart(); + Dijkstra > dij(g,len); + if(report) std::cerr << "Setup Dijkstra class: " << t << '\n'; + t.restart(); + dij.run(s); + if(report) std::cerr << "Run Dijkstra: " << t << '\n'; +} + +template +void solve_max(ArgParser &ap, std::istream &is, std::ostream &, + Value infty, DimacsDescriptor &desc) +{ + bool report = !ap.given("q"); + Digraph g; + Node s,t; + Digraph::ArcMap cap(g); + Timer ti; + ti.restart(); + readDimacsMax(is, g, cap, s, t, infty, desc); + if(report) std::cerr << "Read the file: " << ti << '\n'; + ti.restart(); + Preflow > pre(g,cap,s,t); + if(report) std::cerr << "Setup Preflow class: " << ti << '\n'; + ti.restart(); + pre.run(); + if(report) std::cerr << "Run Preflow: " << ti << '\n'; + if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n'; +} + +template +void solve_min(ArgParser &ap, std::istream &is, std::ostream &, + Value infty, DimacsDescriptor &desc) +{ + bool report = !ap.given("q"); + Digraph g; + Digraph::ArcMap lower(g), cap(g), cost(g); + Digraph::NodeMap sup(g); + Timer ti; + + ti.restart(); + readDimacsMin(is, g, lower, cap, cost, sup, infty, desc); + ti.stop(); + Value sum_sup = 0; + for (Digraph::NodeIt n(g); n != INVALID; ++n) { + sum_sup += sup[n]; + } + if (report) { + std::cerr << "Sum of supply values: " << sum_sup << "\n"; + if (sum_sup <= 0) + std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n"; + else + std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n"; + } + if (report) std::cerr << "Read the file: " << ti << '\n'; + + ti.restart(); + NetworkSimplex ns(g); + ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup); + if (sum_sup > 0) ns.supplyType(ns.LEQ); + if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n'; + ti.restart(); + bool res = ns.run(); + if (report) { + std::cerr << "Run NetworkSimplex: " << ti << "\n\n"; + std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n'; + if (res) std::cerr << "Min flow cost: " + << ns.template totalCost() << '\n'; + } +} + +void solve_mat(ArgParser &ap, std::istream &is, std::ostream &, + DimacsDescriptor &desc) +{ + bool report = !ap.given("q"); + Graph g; + Timer ti; + ti.restart(); + readDimacsMat(is, g, desc); + if(report) std::cerr << "Read the file: " << ti << '\n'; + ti.restart(); + MaxMatching mat(g); + if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n'; + ti.restart(); + mat.run(); + if(report) std::cerr << "Run MaxMatching: " << ti << '\n'; + if(report) std::cerr << "\nCardinality of max matching: " + << mat.matchingSize() << '\n'; +} + + +template +void solve(ArgParser &ap, std::istream &is, std::ostream &os, + DimacsDescriptor &desc) +{ + std::stringstream iss(static_cast(ap["infcap"])); + Value infty; + iss >> infty; + if(iss.fail()) + { + std::cerr << "Cannot interpret '" + << static_cast(ap["infcap"]) << "' as infinite" + << std::endl; + exit(1); + } + + switch(desc.type) + { + case DimacsDescriptor::MIN: + solve_min(ap,is,os,infty,desc); + break; + case DimacsDescriptor::MAX: + solve_max(ap,is,os,infty,desc); + break; + case DimacsDescriptor::SP: + solve_sp(ap,is,os,desc); + break; + case DimacsDescriptor::MAT: + solve_mat(ap,is,os,desc); + break; + default: + break; + } +} + +int main(int argc, const char *argv[]) { + typedef SmartDigraph Digraph; + + typedef Digraph::Arc Arc; + + std::string inputName; + std::string outputName; + + ArgParser ap(argc, argv); + ap.other("[INFILE [OUTFILE]]", + "If either the INFILE or OUTFILE file is missing the standard\n" + " input/output will be used instead.") + .boolOption("q", "Do not print any report") + .boolOption("int","Use 'int' for capacities, costs etc. (default)") + .optionGroup("datatype","int") +#ifdef LEMON_HAVE_LONG_LONG + .boolOption("long","Use 'long long' for capacities, costs etc.") + .optionGroup("datatype","long") +#endif + .boolOption("double","Use 'double' for capacities, costs etc.") + .optionGroup("datatype","double") + .boolOption("ldouble","Use 'long double' for capacities, costs etc.") + .optionGroup("datatype","ldouble") + .onlyOneGroup("datatype") + .stringOption("infcap","Value used for 'very high' capacities","0") + .run(); + + std::ifstream input; + std::ofstream output; + + switch(ap.files().size()) + { + case 2: + output.open(ap.files()[1].c_str()); + if (!output) { + throw IoError("Cannot open the file for writing", ap.files()[1]); + } + case 1: + input.open(ap.files()[0].c_str()); + if (!input) { + throw IoError("File cannot be found", ap.files()[0]); + } + case 0: + break; + default: + std::cerr << ap.commandName() << ": too many arguments\n"; + return 1; + } + std::istream& is = (ap.files().size()<1 ? std::cin : input); + std::ostream& os = (ap.files().size()<2 ? std::cout : output); + + DimacsDescriptor desc = dimacsType(is); + + if(!ap.given("q")) + { + std::cout << "Problem type: "; + switch(desc.type) + { + case DimacsDescriptor::MIN: + std::cout << "min"; + break; + case DimacsDescriptor::MAX: + std::cout << "max"; + break; + case DimacsDescriptor::SP: + std::cout << "sp"; + case DimacsDescriptor::MAT: + std::cout << "mat"; + break; + default: + exit(1); + break; + } + std::cout << "\nNum of nodes: " << desc.nodeNum; + std::cout << "\nNum of arcs: " << desc.edgeNum; + std::cout << "\n\n"; + } + + if(ap.given("double")) + solve(ap,is,os,desc); + else if(ap.given("ldouble")) + solve(ap,is,os,desc); +#ifdef LEMON_HAVE_LONG_LONG + else if(ap.given("long")) + solve(ap,is,os,desc); + else solve(ap,is,os,desc); +#else + else solve(ap,is,os,desc); +#endif + + return 0; +} diff --git a/lemon/tools/dimacs-to-lgf.cc b/lemon/tools/dimacs-to-lgf.cc new file mode 100644 index 0000000..3968645 --- /dev/null +++ b/lemon/tools/dimacs-to-lgf.cc @@ -0,0 +1,148 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +///\ingroup tools +///\file +///\brief DIMACS to LGF converter. +/// +/// This program converts various DIMACS formats to the LEMON Digraph Format +/// (LGF). +/// +/// See +/// \code +/// dimacs-to-lgf --help +/// \endcode +/// for more info on the usage. + +#include +#include +#include + +#include +#include +#include + +#include +#include + +using namespace std; +using namespace lemon; + + +int main(int argc, const char *argv[]) { + typedef SmartDigraph Digraph; + + typedef Digraph::Arc Arc; + typedef Digraph::Node Node; + typedef Digraph::ArcIt ArcIt; + typedef Digraph::NodeIt NodeIt; + typedef Digraph::ArcMap DoubleArcMap; + typedef Digraph::NodeMap DoubleNodeMap; + + std::string inputName; + std::string outputName; + + ArgParser ap(argc, argv); + ap.other("[INFILE [OUTFILE]]", + "If either the INFILE or OUTFILE file is missing the standard\n" + " input/output will be used instead.") + .run(); + + ifstream input; + ofstream output; + + switch(ap.files().size()) + { + case 2: + output.open(ap.files()[1].c_str()); + if (!output) { + throw IoError("Cannot open the file for writing", ap.files()[1]); + } + case 1: + input.open(ap.files()[0].c_str()); + if (!input) { + throw IoError("File cannot be found", ap.files()[0]); + } + case 0: + break; + default: + cerr << ap.commandName() << ": too many arguments\n"; + return 1; + } + istream& is = (ap.files().size()<1 ? cin : input); + ostream& os = (ap.files().size()<2 ? cout : output); + + DimacsDescriptor desc = dimacsType(is); + switch(desc.type) + { + case DimacsDescriptor::MIN: + { + Digraph digraph; + DoubleArcMap lower(digraph), capacity(digraph), cost(digraph); + DoubleNodeMap supply(digraph); + readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc); + DigraphWriter(digraph, os). + nodeMap("supply", supply). + arcMap("lower", lower). + arcMap("capacity", capacity). + arcMap("cost", cost). + attribute("problem","min"). + run(); + } + break; + case DimacsDescriptor::MAX: + { + Digraph digraph; + Node s, t; + DoubleArcMap capacity(digraph); + readDimacsMax(is, digraph, capacity, s, t, 0, desc); + DigraphWriter(digraph, os). + arcMap("capacity", capacity). + node("source", s). + node("target", t). + attribute("problem","max"). + run(); + } + break; + case DimacsDescriptor::SP: + { + Digraph digraph; + Node s; + DoubleArcMap capacity(digraph); + readDimacsSp(is, digraph, capacity, s, desc); + DigraphWriter(digraph, os). + arcMap("capacity", capacity). + node("source", s). + attribute("problem","sp"). + run(); + } + break; + case DimacsDescriptor::MAT: + { + Digraph digraph; + readDimacsMat(is, digraph,desc); + DigraphWriter(digraph, os). + attribute("problem","mat"). + run(); + } + break; + default: + break; + } + return 0; +} diff --git a/lemon/tools/lemon-0.x-to-1.x.sh b/lemon/tools/lemon-0.x-to-1.x.sh new file mode 100755 index 0000000..1dac1be --- /dev/null +++ b/lemon/tools/lemon-0.x-to-1.x.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +set -e + +if [ $# -eq 0 -o x$1 = "x-h" -o x$1 = "x-help" -o x$1 = "x--help" ]; then + echo "Usage:" + echo " $0 source-file(s)" + exit +fi + +for i in $@ +do + echo Update $i... + TMP=`mktemp` + sed -e "s/\/_gr_aph_label_/g"\ + -e "s/\/_gr_aph_label_s/g"\ + -e "s/\/_ed_ge_label_/g"\ + -e "s/\/_ed_ge_label_s/g"\ + -e "s/\/_digr_aph_label_/g"\ + -e "s/\/_digr_aph_label_s/g"\ + -e "s/\/_ar_c_label_/g"\ + -e "s/\/_ar_c_label_s/g"\ + -e "s/UGraph/_Gr_aph_label_/g"\ + -e "s/u[Gg]raph/_gr_aph_label_/g"\ + -e "s/Graph\>/_Digr_aph_label_/g"\ + -e "s/\/_digr_aph_label_/g"\ + -e "s/Graphs\>/_Digr_aph_label_s/g"\ + -e "s/\/_digr_aph_label_s/g"\ + -e "s/\([Gg]\)raph\([a-z]\)/_\1r_aph_label_\2/g"\ + -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\ + -e "s/Graph/_Digr_aph_label_/g"\ + -e "s/graph/_digr_aph_label_/g"\ + -e "s/UEdge/_Ed_ge_label_/g"\ + -e "s/u[Ee]dge/_ed_ge_label_/g"\ + -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\ + -e "s/Edge\>/_Ar_c_label_/g"\ + -e "s/\/_ar_c_label_/g"\ + -e "s/_edge\>/__ar_c_label_/g"\ + -e "s/Edges\>/_Ar_c_label_s/g"\ + -e "s/\/_ar_c_label_s/g"\ + -e "s/_edges\>/__ar_c_label_s/g"\ + -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\ + -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\ + -e "s/Edge/_Ar_c_label_/g"\ + -e "s/edge/_ar_c_label_/g"\ + -e "s/A[Nn]ode/_Re_d_label_/g"\ + -e "s/B[Nn]ode/_Blu_e_label_/g"\ + -e "s/A-[Nn]ode/_Re_d_label_/g"\ + -e "s/B-[Nn]ode/_Blu_e_label_/g"\ + -e "s/a[Nn]ode/_re_d_label_/g"\ + -e "s/b[Nn]ode/_blu_e_label_/g"\ + -e "s/\/_GR_APH_TY_PEDE_FS_label_/g"\ + -e "s/\/_DIGR_APH_TY_PEDE_FS_label_/g"\ + -e "s/_Digr_aph_label_/Digraph/g"\ + -e "s/_digr_aph_label_/digraph/g"\ + -e "s/_Gr_aph_label_/Graph/g"\ + -e "s/_gr_aph_label_/graph/g"\ + -e "s/_Ar_c_label_/Arc/g"\ + -e "s/_ar_c_label_/arc/g"\ + -e "s/_Ed_ge_label_/Edge/g"\ + -e "s/_ed_ge_label_/edge/g"\ + -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\ + -e "s/_Re_d_label_/Red/g"\ + -e "s/_Blu_e_label_/Blue/g"\ + -e "s/_re_d_label_/red/g"\ + -e "s/_blu_e_label_/blue/g"\ + -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\ + -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\ + -e "s/\/adaptors.h/g"\ + -e "s/\/core.h/g"\ + -e "s/\/lgf_reader.h/g"\ + -e "s/\/lgf_writer.h/g"\ + -e "s/\/connectivity.h/g"\ + -e "s/DigraphToEps/GraphToEps/g"\ + -e "s/digraphToEps/graphToEps/g"\ + -e "s/\/SetPredMap/g"\ + -e "s/\/SetDistMap/g"\ + -e "s/\/SetReachedMap/g"\ + -e "s/\/SetProcessedMap/g"\ + -e "s/\/SetHeap/g"\ + -e "s/\/SetStandradHeap/g"\ + -e "s/\/SetOperationTraits/g"\ + -e "s/\/SetStandardProcessedMap/g"\ + -e "s/\/graphCopy/g"\ + -e "s/\/digraphCopy/g"\ + -e "s/\/HypercubeGraph/g"\ + -e "s/\/RangeMap/g"\ + -e "s/\/rangeMap/g"\ + -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\ + -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\ + -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\ + -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\ + -e "s/\/LoggerBoolMap/g"\ + -e "s/\/loggerBoolMap/g"\ + -e "s/\/CrossRefMap/g"\ + -e "s/\/crossRefMap/g"\ + -e "s/\/RangeIdMap/g"\ + -e "s/\/rangeIdMap/g"\ + -e "s/\/Box/g"\ + -e "s/\/readNautyGraph/g"\ + -e "s/\/ReverseDigraph/g"\ + -e "s/\/reverseDigraph/g"\ + -e "s/\/SubDigraph/g"\ + -e "s/\/subDigraph/g"\ + -e "s/\/SubGraph/g"\ + -e "s/\/subGraph/g"\ + -e "s/\/FilterNodes/g"\ + -e "s/\/filterNodes/g"\ + -e "s/\/FilterArcs/g"\ + -e "s/\/filterArcs/g"\ + -e "s/\/Undirector/g"\ + -e "s/\/undirector/g"\ + -e "s/\/ResidualDigraph/g"\ + -e "s/\/residualDigraph/g"\ + -e "s/\/SplitNodes/g"\ + -e "s/\/splitNodes/g"\ + -e "s/\/SubGraph/g"\ + -e "s/\/subGraph/g"\ + -e "s/\/FilterNodes/g"\ + -e "s/\/filterNodes/g"\ + -e "s/\/FilterEdges/g"\ + -e "s/\/filterEdges/g"\ + -e "s/\/Orienter/g"\ + -e "s/\/orienter/g"\ + -e "s/\/CplexLp/g"\ + -e "s/\/CplexMip/g"\ + -e "s/\/GlpkLp/g"\ + -e "s/\/GlpkMip/g"\ + -e "s/\/SoplexLp/g"\ + <$i > $TMP + mv $TMP $i +done diff --git a/lemon/tools/lgf-gen.cc b/lemon/tools/lgf-gen.cc new file mode 100644 index 0000000..e8bf7cd --- /dev/null +++ b/lemon/tools/lgf-gen.cc @@ -0,0 +1,834 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2009 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +/// \ingroup tools +/// \file +/// \brief Special plane graph generator. +/// +/// Graph generator application for various types of plane graphs. +/// +/// See +/// \code +/// lgf-gen --help +/// \endcode +/// for more information on the usage. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace lemon; + +typedef dim2::Point Point; + +GRAPH_TYPEDEFS(ListGraph); + +bool progress=true; + +int N; +// int girth; + +ListGraph g; + +std::vector nodes; +ListGraph::NodeMap coords(g); + + +double totalLen(){ + double tlen=0; + for(EdgeIt e(g);e!=INVALID;++e) + tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare()); + return tlen; +} + +int tsp_impr_num=0; + +const double EPSILON=1e-8; +bool tsp_improve(Node u, Node v) +{ + double luv=std::sqrt((coords[v]-coords[u]).normSquare()); + Node u2=u; + Node v2=v; + do { + Node n; + for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e) { } + u2=v2; + v2=n; + if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON> + std::sqrt((coords[u]-coords[u2]).normSquare())+ + std::sqrt((coords[v]-coords[v2]).normSquare())) + { + g.erase(findEdge(g,u,v)); + g.erase(findEdge(g,u2,v2)); + g.addEdge(u2,u); + g.addEdge(v,v2); + tsp_impr_num++; + return true; + } + } while(v2!=u); + return false; +} + +bool tsp_improve(Node u) +{ + for(IncEdgeIt e(g,u);e!=INVALID;++e) + if(tsp_improve(u,g.runningNode(e))) return true; + return false; +} + +void tsp_improve() +{ + bool b; + do { + b=false; + for(NodeIt n(g);n!=INVALID;++n) + if(tsp_improve(n)) b=true; + } while(b); +} + +void tsp() +{ + for(int i=0;i" << l.b; + return os; +} + +bool cross(Line a, Line b) +{ + Point ao=rot90(a.b-a.a); + Point bo=rot90(b.b-b.a); + return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 && + (bo*(a.a-b.a))*(bo*(a.b-b.a))<0; +} + +struct Parc +{ + Node a; + Node b; + double len; +}; + +bool pedgeLess(Parc a,Parc b) +{ + return a.len arcs; + +namespace _delaunay_bits { + + struct Part { + int prev, curr, next; + + Part(int p, int c, int n) : prev(p), curr(c), next(n) {} + }; + + inline std::ostream& operator<<(std::ostream& os, const Part& part) { + os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')'; + return os; + } + + inline double circle_point(const Point& p, const Point& q, const Point& r) { + double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y); + if (a == 0) return std::numeric_limits::quiet_NaN(); + + double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) + + (q.x * q.x + q.y * q.y) * (r.y - p.y) + + (r.x * r.x + r.y * r.y) * (p.y - q.y); + + double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) + + (q.x * q.x + q.y * q.y) * (r.x - p.x) + + (r.x * r.x + r.y * r.y) * (p.x - q.x); + + double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) + + (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) + + (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y); + + return d / (2 * a) + std::sqrt((d * d + e * e) / (4 * a * a) + f / a); + } + + inline bool circle_form(const Point& p, const Point& q, const Point& r) { + return rot90(q - p) * (r - q) < 0.0; + } + + inline double intersection(const Point& p, const Point& q, double sx) { + const double epsilon = 1e-8; + + if (p.x == q.x) return (p.y + q.y) / 2.0; + + if (sx < p.x + epsilon) return p.y; + if (sx < q.x + epsilon) return q.y; + + double a = q.x - p.x; + double b = (q.x - sx) * p.y - (p.x - sx) * q.y; + double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare(); + return (b - std::sqrt(d)) / a; + } + + struct YLess { + + + YLess(const std::vector& points, double& sweep) + : _points(points), _sweep(sweep) {} + + bool operator()(const Part& l, const Part& r) const { + const double epsilon = 1e-8; + + // std::cerr << l << " vs " << r << std::endl; + double lbx = l.prev != -1 ? + intersection(_points[l.prev], _points[l.curr], _sweep) : + - std::numeric_limits::infinity(); + double rbx = r.prev != -1 ? + intersection(_points[r.prev], _points[r.curr], _sweep) : + - std::numeric_limits::infinity(); + double lex = l.next != -1 ? + intersection(_points[l.curr], _points[l.next], _sweep) : + std::numeric_limits::infinity(); + double rex = r.next != -1 ? + intersection(_points[r.curr], _points[r.next], _sweep) : + std::numeric_limits::infinity(); + + if (lbx > lex) std::swap(lbx, lex); + if (rbx > rex) std::swap(rbx, rex); + + if (lex < epsilon + rex && lbx + epsilon < rex) return true; + if (rex < epsilon + lex && rbx + epsilon < lex) return false; + return lex < rex; + } + + const std::vector& _points; + double& _sweep; + }; + + struct BeachIt; + + typedef std::multimap SpikeHeap; + + typedef std::multimap Beach; + + struct BeachIt { + Beach::iterator it; + + BeachIt(Beach::iterator iter) : it(iter) {} + }; + +} + +inline void delaunay() { + Counter cnt("Number of arcs added: "); + + using namespace _delaunay_bits; + + typedef _delaunay_bits::Part Part; + typedef std::vector > SiteHeap; + + + std::vector points; + std::vector nodes; + + for (NodeIt it(g); it != INVALID; ++it) { + nodes.push_back(it); + points.push_back(coords[it]); + } + + SiteHeap siteheap(points.size()); + + double sweep; + + + for (int i = 0; i < int(siteheap.size()); ++i) { + siteheap[i] = std::make_pair(points[i].x, i); + } + + std::sort(siteheap.begin(), siteheap.end()); + sweep = siteheap.front().first; + + YLess yless(points, sweep); + Beach beach(yless); + + SpikeHeap spikeheap; + + std::set > arcs; + + int siteindex = 0; + { + SiteHeap front; + + while (siteindex < int(siteheap.size()) && + siteheap[0].first == siteheap[siteindex].first) { + front.push_back(std::make_pair(points[siteheap[siteindex].second].y, + siteheap[siteindex].second)); + ++siteindex; + } + + std::sort(front.begin(), front.end()); + + for (int i = 0; i < int(front.size()); ++i) { + int prev = (i == 0 ? -1 : front[i - 1].second); + int curr = front[i].second; + int next = (i + 1 == int(front.size()) ? -1 : front[i + 1].second); + + beach.insert(std::make_pair(Part(prev, curr, next), + spikeheap.end())); + } + } + + while (siteindex < int(points.size()) || !spikeheap.empty()) { + + SpikeHeap::iterator spit = spikeheap.begin(); + + if (siteindex < int(points.size()) && + (spit == spikeheap.end() || siteheap[siteindex].first < spit->first)) { + int site = siteheap[siteindex].second; + sweep = siteheap[siteindex].first; + + Beach::iterator bit = beach.upper_bound(Part(site, site, site)); + + if (bit->second != spikeheap.end()) { + spikeheap.erase(bit->second); + } + + int prev = bit->first.prev; + int curr = bit->first.curr; + int next = bit->first.next; + + beach.erase(bit); + + SpikeHeap::iterator pit = spikeheap.end(); + if (prev != -1 && + circle_form(points[prev], points[curr], points[site])) { + double x = circle_point(points[prev], points[curr], points[site]); + pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end()))); + pit->second.it = + beach.insert(std::make_pair(Part(prev, curr, site), pit)); + } else { + beach.insert(std::make_pair(Part(prev, curr, site), pit)); + } + + beach.insert(std::make_pair(Part(curr, site, curr), spikeheap.end())); + + SpikeHeap::iterator nit = spikeheap.end(); + if (next != -1 && + circle_form(points[site], points[curr],points[next])) { + double x = circle_point(points[site], points[curr], points[next]); + nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end()))); + nit->second.it = + beach.insert(std::make_pair(Part(site, curr, next), nit)); + } else { + beach.insert(std::make_pair(Part(site, curr, next), nit)); + } + + ++siteindex; + } else { + sweep = spit->first; + + Beach::iterator bit = spit->second.it; + + int prev = bit->first.prev; + int curr = bit->first.curr; + int next = bit->first.next; + + { + std::pair arc; + + arc = prev < curr ? + std::make_pair(prev, curr) : std::make_pair(curr, prev); + + if (arcs.find(arc) == arcs.end()) { + arcs.insert(arc); + g.addEdge(nodes[prev], nodes[curr]); + ++cnt; + } + + arc = curr < next ? + std::make_pair(curr, next) : std::make_pair(next, curr); + + if (arcs.find(arc) == arcs.end()) { + arcs.insert(arc); + g.addEdge(nodes[curr], nodes[next]); + ++cnt; + } + } + + Beach::iterator pbit = bit; --pbit; + int ppv = pbit->first.prev; + Beach::iterator nbit = bit; ++nbit; + int nnt = nbit->first.next; + + if (bit->second != spikeheap.end()) spikeheap.erase(bit->second); + if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second); + if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second); + + beach.erase(nbit); + beach.erase(bit); + beach.erase(pbit); + + SpikeHeap::iterator pit = spikeheap.end(); + if (ppv != -1 && ppv != next && + circle_form(points[ppv], points[prev], points[next])) { + double x = circle_point(points[ppv], points[prev], points[next]); + if (x < sweep) x = sweep; + pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end()))); + pit->second.it = + beach.insert(std::make_pair(Part(ppv, prev, next), pit)); + } else { + beach.insert(std::make_pair(Part(ppv, prev, next), pit)); + } + + SpikeHeap::iterator nit = spikeheap.end(); + if (nnt != -1 && prev != nnt && + circle_form(points[prev], points[next], points[nnt])) { + double x = circle_point(points[prev], points[next], points[nnt]); + if (x < sweep) x = sweep; + nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end()))); + nit->second.it = + beach.insert(std::make_pair(Part(prev, next, nnt), nit)); + } else { + beach.insert(std::make_pair(Part(prev, next, nnt), nit)); + } + + } + } + + for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) { + int curr = it->first.curr; + int next = it->first.next; + + if (next == -1) continue; + + std::pair arc; + + arc = curr < next ? + std::make_pair(curr, next) : std::make_pair(next, curr); + + if (arcs.find(arc) == arcs.end()) { + arcs.insert(arc); + g.addEdge(nodes[curr], nodes[next]); + ++cnt; + } + } +} + +void sparse(int d) +{ + Counter cnt("Number of arcs removed: "); + Bfs bfs(g); + for(std::vector::reverse_iterator ei=arcs.rbegin(); + ei!=arcs.rend();++ei) + { + Node a=g.u(*ei); + Node b=g.v(*ei); + g.erase(*ei); + bfs.run(a,b); + if(bfs.predArc(b)==INVALID || bfs.dist(b)>d) + g.addEdge(a,b); + else cnt++; + } +} + +void sparse2(int d) +{ + Counter cnt("Number of arcs removed: "); + for(std::vector::reverse_iterator ei=arcs.rbegin(); + ei!=arcs.rend();++ei) + { + Node a=g.u(*ei); + Node b=g.v(*ei); + g.erase(*ei); + ConstMap cegy(1); + Suurballe > sur(g,cegy); + int k=sur.run(a,b,2); + if(k<2 || sur.totalLength()>d) + g.addEdge(a,b); + else cnt++; +// else std::cout << "Remove arc " << g.id(a) << "-" << g.id(b) << '\n'; + } +} + +void sparseTriangle(int d) +{ + Counter cnt("Number of arcs added: "); + std::vector pedges; + for(NodeIt n(g);n!=INVALID;++n) + for(NodeIt m=++(NodeIt(n));m!=INVALID;++m) + { + Parc p; + p.a=n; + p.b=m; + p.len=(coords[m]-coords[n]).normSquare(); + pedges.push_back(p); + } + std::sort(pedges.begin(),pedges.end(),pedgeLess); + for(std::vector::iterator pi=pedges.begin();pi!=pedges.end();++pi) + { + Line li(pi->a,pi->b); + EdgeIt e(g); + for(;e!=INVALID && !cross(e,li);++e) ; + Edge ne; + if(e==INVALID) { + ConstMap cegy(1); + Suurballe > sur(g,cegy); + int k=sur.run(pi->a,pi->b,2); + if(k<2 || sur.totalLength()>d) + { + ne=g.addEdge(pi->a,pi->b); + arcs.push_back(ne); + cnt++; + } + } + } +} + +template +class LengthSquareMap { +public: + typedef typename Graph::Edge Key; + typedef typename CoordMap::Value::Value Value; + + LengthSquareMap(const Graph& graph, const CoordMap& coords) + : _graph(graph), _coords(coords) {} + + Value operator[](const Key& key) const { + return (_coords[_graph.v(key)] - + _coords[_graph.u(key)]).normSquare(); + } + +private: + + const Graph& _graph; + const CoordMap& _coords; +}; + +void minTree() { + std::vector pedges; + Timer T; + std::cout << T.realTime() << "s: Creating delaunay triangulation...\n"; + delaunay(); + std::cout << T.realTime() << "s: Calculating spanning tree...\n"; + LengthSquareMap > ls(g, coords); + ListGraph::EdgeMap tree(g); + kruskal(g, ls, tree); + std::cout << T.realTime() << "s: Removing non tree arcs...\n"; + std::vector remove; + for (EdgeIt e(g); e != INVALID; ++e) { + if (!tree[e]) remove.push_back(e); + } + for(int i = 0; i < int(remove.size()); ++i) { + g.erase(remove[i]); + } + std::cout << T.realTime() << "s: Done\n"; +} + +void tsp2() +{ + std::cout << "Find a tree..." << std::endl; + + minTree(); + + std::cout << "Total arc length (tree) : " << totalLen() << std::endl; + + std::cout << "Make it Euler..." << std::endl; + + { + std::vector leafs; + for(NodeIt n(g);n!=INVALID;++n) + if(countIncEdges(g,n)%2==1) leafs.push_back(n); + +// for(unsigned int i=0;i pedges; + for(unsigned int i=0;i enext(g); + { + EulerIt e(g); + Arc eo=e; + Arc ef=e; +// std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl; + for(++e;e!=INVALID;++e) + { +// std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl; + enext[eo]=e; + eo=e; + } + enext[eo]=ef; + } + + std::cout << "Creating a tour from that..." << std::endl; + + int nnum = countNodes(g); + int ednum = countEdges(g); + + for(Arc p=enext[EdgeIt(g)];ednum>nnum;p=enext[p]) + { +// std::cout << "Checking arc " << g.id(p) << std::endl; + Arc e=enext[p]; + Arc f=enext[e]; + Node n2=g.source(f); + Node n1=g.oppositeNode(n2,e); + Node n3=g.oppositeNode(n2,f); + if(countIncEdges(g,n2)>2) + { +// std::cout << "Remove an Arc" << std::endl; + Arc ff=enext[f]; + g.erase(e); + g.erase(f); + if(n1!=n3) + { + Arc ne=g.direct(g.addEdge(n1,n3),n1); + enext[p]=ne; + enext[ne]=ff; + ednum--; + } + else { + enext[p]=ff; + ednum-=2; + } + } + } + + std::cout << "Total arc length (tour) : " << totalLen() << std::endl; + + std::cout << "2-opt the tour..." << std::endl; + + tsp_improve(); + + std::cout << "Total arc length (2-opt tour) : " << totalLen() << std::endl; +} + + +int main(int argc,const char **argv) +{ + ArgParser ap(argc,argv); + +// bool eps; + bool disc_d, square_d, gauss_d; +// bool tsp_a,two_a,tree_a; + int num_of_cities=1; + double area=1; + N=100; +// girth=10; + std::string ndist("disc"); + ap.refOption("n", "Number of nodes (default is 100)", N) + .intOption("g", "Girth parameter (default is 10)", 10) + .refOption("cities", "Number of cities (default is 1)", num_of_cities) + .refOption("area", "Full relative area of the cities (default is 1)", area) + .refOption("disc", "Nodes are evenly distributed on a unit disc (default)", + disc_d) + .optionGroup("dist", "disc") + .refOption("square", "Nodes are evenly distributed on a unit square", + square_d) + .optionGroup("dist", "square") + .refOption("gauss", "Nodes are located according to a two-dim Gauss " + "distribution", gauss_d) + .optionGroup("dist", "gauss") + .onlyOneGroup("dist") + .boolOption("eps", "Also generate .eps output (.eps)") + .boolOption("nonodes", "Draw only the edges in the generated .eps output") + .boolOption("dir", "Directed graph is generated (each edge is replaced by " + "two directed arcs)") + .boolOption("2con", "Create a two connected planar graph") + .optionGroup("alg","2con") + .boolOption("tree", "Create a min. cost spanning tree") + .optionGroup("alg","tree") + .boolOption("tsp", "Create a TSP tour") + .optionGroup("alg","tsp") + .boolOption("tsp2", "Create a TSP tour (tree based)") + .optionGroup("alg","tsp2") + .boolOption("dela", "Delaunay triangulation graph") + .optionGroup("alg","dela") + .onlyOneGroup("alg") + .boolOption("rand", "Use time seed for random number generator") + .optionGroup("rand", "rand") + .intOption("seed", "Random seed", -1) + .optionGroup("rand", "seed") + .onlyOneGroup("rand") + .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'") + .run(); + + if (ap["rand"]) { + int seed = int(time(0)); + std::cout << "Random number seed: " << seed << std::endl; + rnd = Random(seed); + } + if (ap.given("seed")) { + int seed = ap["seed"]; + std::cout << "Random number seed: " << seed << std::endl; + rnd = Random(seed); + } + + std::string prefix; + switch(ap.files().size()) + { + case 0: + prefix="lgf-gen-out"; + break; + case 1: + prefix=ap.files()[0]; + break; + default: + std::cerr << "\nAt most one prefix can be given\n\n"; + exit(1); + } + + double sum_sizes=0; + std::vector sizes; + std::vector cum_sizes; + for(int s=0;s(g,prefix+".lgf"). + nodeMap("coordinates_x",scaleMap(xMap(coords),600)). + nodeMap("coordinates_y",scaleMap(yMap(coords),600)). + run(); + else GraphWriter(g,prefix+".lgf"). + nodeMap("coordinates_x",scaleMap(xMap(coords),600)). + nodeMap("coordinates_y",scaleMap(yMap(coords),600)). + run(); +} + -- cgit v1.2.3