#include "catch.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include static_assert(osmium::index::empty_value() == osmium::Location{}, "Empty value for location is wrong"); template void test_func_all(TIndex& index) { const osmium::unsigned_object_id_type id1 = 12; const osmium::unsigned_object_id_type id2 = 3; const osmium::Location loc1{1.2, 4.5}; const osmium::Location loc2{3.5, -7.2}; REQUIRE_THROWS_AS(index.get(id1), const osmium::not_found&); index.set(id1, loc1); index.set(id2, loc2); index.sort(); REQUIRE_THROWS_AS(index.get(0), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(1), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(5), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(100), const osmium::not_found&); REQUIRE_THROWS_WITH(index.get(0), "id 0 not found"); REQUIRE_THROWS_WITH(index.get(1), "id 1 not found"); REQUIRE(index.get_noexcept(0) == osmium::Location{}); REQUIRE(index.get_noexcept(1) == osmium::Location{}); REQUIRE(index.get_noexcept(5) == osmium::Location{}); REQUIRE(index.get_noexcept(100) == osmium::Location{}); } template void test_func_real(TIndex& index) { const osmium::unsigned_object_id_type id1 = 12; const osmium::unsigned_object_id_type id2 = 3; const osmium::Location loc1{1.2, 4.5}; const osmium::Location loc2{3.5, -7.2}; index.set(id1, loc1); index.set(id2, loc2); index.sort(); REQUIRE(loc1 == index.get(id1)); REQUIRE(loc2 == index.get(id2)); REQUIRE(loc1 == index.get_noexcept(id1)); REQUIRE(loc2 == index.get_noexcept(id2)); REQUIRE_THROWS_AS(index.get(0), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(1), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(5), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(100), const osmium::not_found&); REQUIRE(index.get_noexcept(0) == osmium::Location{}); REQUIRE(index.get_noexcept(1) == osmium::Location{}); REQUIRE(index.get_noexcept(5) == osmium::Location{}); REQUIRE(index.get_noexcept(100) == osmium::Location{}); index.clear(); REQUIRE_THROWS_AS(index.get(id1), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(id2), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(0), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(1), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(5), const osmium::not_found&); REQUIRE_THROWS_AS(index.get(100), const osmium::not_found&); REQUIRE(index.get_noexcept(id1) == osmium::Location{}); REQUIRE(index.get_noexcept(id2) == osmium::Location{}); REQUIRE(index.get_noexcept(0) == osmium::Location{}); REQUIRE(index.get_noexcept(1) == osmium::Location{}); REQUIRE(index.get_noexcept(5) == osmium::Location{}); REQUIRE(index.get_noexcept(100) == osmium::Location{}); } TEST_CASE("Map Id to location: Dummy") { using index_type = osmium::index::map::Dummy; index_type index1; REQUIRE(0 == index1.size()); REQUIRE(0 == index1.used_memory()); test_func_all(index1); REQUIRE(0 == index1.size()); REQUIRE(0 == index1.used_memory()); } TEST_CASE("Map Id to location: DenseMemArray") { using index_type = osmium::index::map::DenseMemArray; index_type index1; index1.reserve(1000); test_func_all(index1); index_type index2; index2.reserve(1000); test_func_real(index2); } #ifdef __linux__ TEST_CASE("Map Id to location: DenseMmapArray") { using index_type = osmium::index::map::DenseMmapArray; index_type index1; test_func_all(index1); index_type index2; test_func_real(index2); } #else # pragma message("not running 'DenseMapMmap' test case on this machine") #endif TEST_CASE("Map Id to location: DenseFileArray") { using index_type = osmium::index::map::DenseFileArray; index_type index1; test_func_all(index1); index_type index2; test_func_real(index2); } #ifdef OSMIUM_WITH_SPARSEHASH TEST_CASE("Map Id to location: SparseMemTable") { using index_type = osmium::index::map::SparseMemTable; index_type index1; test_func_all(index1); index_type index2; test_func_real(index2); } #endif TEST_CASE("Map Id to location: SparseMemMap") { using index_type = osmium::index::map::SparseMemMap; index_type index1; test_func_all(index1); index_type index2; test_func_real(index2); } TEST_CASE("Map Id to location: SparseMemArray") { using index_type = osmium::index::map::SparseMemArray; index_type index1; REQUIRE(0 == index1.size()); REQUIRE(0 == index1.used_memory()); test_func_all(index1); REQUIRE(2 == index1.size()); index_type index2; test_func_real(index2); } TEST_CASE("Map Id to location: FlexMem sparse") { using index_type = osmium::index::map::FlexMem; index_type index1; test_func_all(index1); index_type index2; test_func_real(index2); } TEST_CASE("Map Id to location: FlexMem dense") { using index_type = osmium::index::map::FlexMem; index_type index1{true}; test_func_all(index1); index_type index2{true}; test_func_real(index2); } TEST_CASE("Map Id to location: FlexMem switch") { using index_type = osmium::index::map::FlexMem; const osmium::Location loc1{1.1, 1.2}; const osmium::Location loc2{2.2, -9.4}; index_type index; REQUIRE(index.size() == 0); index.set(17, loc1); index.set(99, loc2); REQUIRE_FALSE(index.is_dense()); REQUIRE(index.size() == 2); REQUIRE(index.get_noexcept(0) == osmium::Location{}); REQUIRE(index.get_noexcept(1) == osmium::Location{}); REQUIRE(index.get_noexcept(17) == loc1); REQUIRE(index.get_noexcept(99) == loc2); REQUIRE(index.get_noexcept(2000000000) == osmium::Location{}); index.switch_to_dense(); REQUIRE(index.is_dense()); REQUIRE(index.size() >= 2); REQUIRE(index.get_noexcept(0) == osmium::Location{}); REQUIRE(index.get_noexcept(1) == osmium::Location{}); REQUIRE(index.get_noexcept(17) == loc1); REQUIRE(index.get_noexcept(99) == loc2); REQUIRE(index.get_noexcept(2000000000) == osmium::Location{}); } TEST_CASE("Map Id to location: Dynamic map choice") { using map_type = osmium::index::map::Map; const auto& map_factory = osmium::index::MapFactory::instance(); const std::vector map_type_names = map_factory.map_types(); REQUIRE(map_type_names.size() >= 6); REQUIRE_THROWS_AS(map_factory.create_map(""), const osmium::map_factory_error&); REQUIRE_THROWS_AS(map_factory.create_map("does not exist"), const osmium::map_factory_error&); REQUIRE_THROWS_WITH(map_factory.create_map(""), "Need non-empty map type name"); REQUIRE_THROWS_WITH(map_factory.create_map("does not exist"), "Support for map type 'does not exist' not compiled into this binary"); for (const auto& map_type_name : map_type_names) { std::unique_ptr index1 = map_factory.create_map(map_type_name); index1->reserve(1000); test_func_all(*index1); std::unique_ptr index2 = map_factory.create_map(map_type_name); index2->reserve(1000); test_func_real(*index2); } }